Introduce special str function implementation for T-SQL
This commit is contained in:
parent
b4a82f0854
commit
118b160b02
|
@ -1459,6 +1459,7 @@ public class HQLTest extends BaseEntityManagerFunctionalTestCase {
|
|||
public void test_hql_str_function_example_sql_server() {
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
//tag::hql-str-function-example[]
|
||||
// Special SQL Server function "str" that converts floats
|
||||
List<String> timestamps = entityManager.createQuery(
|
||||
"select str( cast(duration as float) / 60, 4, 2 ) " +
|
||||
"from Call c ", String.class )
|
||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate.dialect;
|
|||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.dialect.function.CastStrEmulation;
|
||||
import org.hibernate.dialect.function.TransactSQLStrFunction;
|
||||
import org.hibernate.query.NullOrdering;
|
||||
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
||||
import org.hibernate.cfg.Environment;
|
||||
|
@ -116,6 +118,7 @@ public abstract class AbstractTransactSQLDialect extends Dialect {
|
|||
|
||||
queryEngine.getSqmFunctionRegistry().register( "least", new CaseLeastGreatestEmulation( true ) );
|
||||
queryEngine.getSqmFunctionRegistry().register( "greatest", new CaseLeastGreatestEmulation( false ) );
|
||||
queryEngine.getSqmFunctionRegistry().register( "str", new TransactSQLStrFunction() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,6 +10,8 @@ import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
|
|||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
|
@ -35,13 +37,20 @@ public class CastStrEmulation
|
|||
);
|
||||
}
|
||||
|
||||
protected CastStrEmulation(
|
||||
String name,
|
||||
ArgumentsValidator argumentsValidator,
|
||||
FunctionReturnTypeResolver returnTypeResolver) {
|
||||
super( name, argumentsValidator, returnTypeResolver );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
AllowableFunctionReturnType<T> impliedResultType,
|
||||
QueryEngine queryEngine,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
SqmTypedNode<?> argument = arguments.get(0);
|
||||
final SqmTypedNode<?> argument = arguments.get( 0 );
|
||||
return queryEngine.getSqmFunctionRegistry().findFunctionDescriptor( "cast" )
|
||||
.generateSqmExpression(
|
||||
asList(
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* A special function that renders to the T-SQL "str" function if more than a single argument is given,
|
||||
* otherwise renders a cast expression like {@link CastStrEmulation}.
|
||||
*
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
public class TransactSQLStrFunction extends CastStrEmulation implements FunctionRenderingSupport {
|
||||
|
||||
public TransactSQLStrFunction() {
|
||||
super(
|
||||
"str",
|
||||
StandardArgumentsValidators.between( 1, 3 ),
|
||||
StandardFunctionReturnTypeResolvers.invariant( StandardBasicTypes.STRING )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
AllowableFunctionReturnType<T> impliedResultType,
|
||||
QueryEngine queryEngine,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
if ( arguments.size() == 1 ) {
|
||||
return super.generateSqmFunctionExpression( arguments, impliedResultType, queryEngine, typeConfiguration );
|
||||
}
|
||||
|
||||
return new SelfRenderingSqmFunction<>(
|
||||
this,
|
||||
this,
|
||||
arguments,
|
||||
impliedResultType,
|
||||
getReturnTypeResolver(),
|
||||
queryEngine.getCriteriaBuilder(),
|
||||
getName()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(SqlAppender sqlAppender, List<SqlAstNode> arguments, SqlAstTranslator<?> walker) {
|
||||
sqlAppender.appendSql( "str(" );
|
||||
arguments.get( 0 ).accept( walker );
|
||||
for ( int i = 1; i < arguments.size(); i++ ) {
|
||||
sqlAppender.appendSql( ", " );
|
||||
arguments.get( i ).accept( walker );
|
||||
}
|
||||
sqlAppender.appendSql( ')' );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue