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() {
|
public void test_hql_str_function_example_sql_server() {
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
//tag::hql-str-function-example[]
|
//tag::hql-str-function-example[]
|
||||||
|
// Special SQL Server function "str" that converts floats
|
||||||
List<String> timestamps = entityManager.createQuery(
|
List<String> timestamps = entityManager.createQuery(
|
||||||
"select str( cast(duration as float) / 60, 4, 2 ) " +
|
"select str( cast(duration as float) / 60, 4, 2 ) " +
|
||||||
"from Call c ", String.class )
|
"from Call c ", String.class )
|
||||||
|
|
|
@ -8,6 +8,8 @@ package org.hibernate.dialect;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.LockOptions;
|
import org.hibernate.LockOptions;
|
||||||
|
import org.hibernate.dialect.function.CastStrEmulation;
|
||||||
|
import org.hibernate.dialect.function.TransactSQLStrFunction;
|
||||||
import org.hibernate.query.NullOrdering;
|
import org.hibernate.query.NullOrdering;
|
||||||
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
||||||
import org.hibernate.cfg.Environment;
|
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( "least", new CaseLeastGreatestEmulation( true ) );
|
||||||
queryEngine.getSqmFunctionRegistry().register( "greatest", new CaseLeastGreatestEmulation( false ) );
|
queryEngine.getSqmFunctionRegistry().register( "greatest", new CaseLeastGreatestEmulation( false ) );
|
||||||
|
queryEngine.getSqmFunctionRegistry().register( "str", new TransactSQLStrFunction() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -10,6 +10,8 @@ import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
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.StandardArgumentsValidators;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
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
|
@Override
|
||||||
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
|
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
AllowableFunctionReturnType<T> impliedResultType,
|
AllowableFunctionReturnType<T> impliedResultType,
|
||||||
QueryEngine queryEngine,
|
QueryEngine queryEngine,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
SqmTypedNode<?> argument = arguments.get(0);
|
final SqmTypedNode<?> argument = arguments.get( 0 );
|
||||||
return queryEngine.getSqmFunctionRegistry().findFunctionDescriptor( "cast" )
|
return queryEngine.getSqmFunctionRegistry().findFunctionDescriptor( "cast" )
|
||||||
.generateSqmExpression(
|
.generateSqmExpression(
|
||||||
asList(
|
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