redesign 'collate' and add tests
* and add tests and documentation for 'collate' * much better and less-ambiguous syntax for collate(), consistent with cast() and treat() * reimplement collate() using the function infrastructure * implement collate() for HSQLDB This feature was previously untested and at least partially broken, and was making a mess of the HQL grammar.
This commit is contained in:
parent
4509cad315
commit
5ae55d7bfb
|
@ -850,6 +850,15 @@ include::{sourcedir}/HQLTest.java[tags=hql-year-function-example]
|
||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
||||||
|
===== `collate()`
|
||||||
|
|
||||||
|
Selects a collation to be used for its string-valued argument.
|
||||||
|
Collations are useful for <<hql-relational-comparisons,binary comparisons>> with `<` or `>`, and in the <<hql-order-by,order by clause>>.
|
||||||
|
|
||||||
|
For example, `collate(p.name as ucs_basic)` specifies the SQL standard collation `ucs_basic`.
|
||||||
|
|
||||||
|
IMPORTANT: Collations aren't very portable between databases.
|
||||||
|
|
||||||
[[hql-function-format]]
|
[[hql-function-format]]
|
||||||
===== `format()`
|
===== `format()`
|
||||||
|
|
||||||
|
|
|
@ -293,12 +293,12 @@ mapKeyNavigablePath
|
||||||
// GROUP BY clause
|
// GROUP BY clause
|
||||||
|
|
||||||
groupByClause
|
groupByClause
|
||||||
: GROUP BY groupByExpression ( COMMA groupByExpression )*
|
: GROUP BY groupByExpression ( COMMA groupByExpression )*
|
||||||
;
|
;
|
||||||
|
|
||||||
groupByExpression
|
groupByExpression
|
||||||
: identifier collationSpecification?
|
: identifier
|
||||||
| INTEGER_LITERAL collationSpecification?
|
| INTEGER_LITERAL
|
||||||
| expression
|
| expression
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -306,7 +306,7 @@ groupByExpression
|
||||||
//HAVING clause
|
//HAVING clause
|
||||||
|
|
||||||
havingClause
|
havingClause
|
||||||
: HAVING predicate
|
: HAVING predicate
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -333,22 +333,22 @@ nullsPrecedence
|
||||||
;
|
;
|
||||||
|
|
||||||
sortExpression
|
sortExpression
|
||||||
: identifier collationSpecification?
|
: identifier
|
||||||
| INTEGER_LITERAL collationSpecification?
|
| INTEGER_LITERAL
|
||||||
| expression
|
| expression
|
||||||
;
|
;
|
||||||
|
|
||||||
collationSpecification
|
collationExpression
|
||||||
: COLLATE collateName
|
: COLLATE LEFT_PAREN expression AS collation RIGHT_PAREN
|
||||||
;
|
;
|
||||||
|
|
||||||
collateName
|
collation
|
||||||
: dotIdentifierSequence
|
: dotIdentifierSequence
|
||||||
;
|
;
|
||||||
|
|
||||||
orderingSpecification
|
orderingSpecification
|
||||||
: ASC
|
: ASC
|
||||||
| DESC
|
| DESC
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -384,7 +384,7 @@ parameterOrNumberLiteral
|
||||||
// WHERE clause & Predicates
|
// WHERE clause & Predicates
|
||||||
|
|
||||||
whereClause
|
whereClause
|
||||||
: WHERE predicate
|
: WHERE predicate
|
||||||
;
|
;
|
||||||
|
|
||||||
predicate
|
predicate
|
||||||
|
@ -436,7 +436,7 @@ expression
|
||||||
: LEFT_PAREN expression RIGHT_PAREN # GroupedExpression
|
: LEFT_PAREN expression RIGHT_PAREN # GroupedExpression
|
||||||
| LEFT_PAREN expressionOrPredicate (COMMA expressionOrPredicate)+ RIGHT_PAREN # TupleExpression
|
| LEFT_PAREN expressionOrPredicate (COMMA expressionOrPredicate)+ RIGHT_PAREN # TupleExpression
|
||||||
| LEFT_PAREN subquery RIGHT_PAREN # SubqueryExpression
|
| LEFT_PAREN subquery RIGHT_PAREN # SubqueryExpression
|
||||||
| primaryExpression collationSpecification? # CollateExpression
|
| primaryExpression # BarePrimaryExpression
|
||||||
| signOperator numericLiteral # UnaryNumericLiteralExpression
|
| signOperator numericLiteral # UnaryNumericLiteralExpression
|
||||||
| signOperator expression # UnaryExpression
|
| signOperator expression # UnaryExpression
|
||||||
| expression datetimeField # ToDurationExpression
|
| expression datetimeField # ToDurationExpression
|
||||||
|
@ -707,6 +707,7 @@ standardFunction
|
||||||
| offsetDateTimeFunction
|
| offsetDateTimeFunction
|
||||||
| cube
|
| cube
|
||||||
| rollup
|
| rollup
|
||||||
|
| collationExpression
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -792,6 +792,7 @@ public abstract class Dialect implements ConversionContext {
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li> format(datetime as pattern)
|
* <li> format(datetime as pattern)
|
||||||
|
* <li> collate(string as collation)
|
||||||
* <li> str(arg) - synonym of cast(a as String)
|
* <li> str(arg) - synonym of cast(a as String)
|
||||||
* <li> ifnull(arg0, arg1) - synonym of coalesce(a, b)
|
* <li> ifnull(arg0, arg1) - synonym of coalesce(a, b)
|
||||||
* </ul>
|
* </ul>
|
||||||
|
@ -897,6 +898,10 @@ public abstract class Dialect implements ConversionContext {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//There is a 'collate' operator in a number of major databases
|
||||||
|
|
||||||
|
CommonFunctionFactory.collate( queryEngine );
|
||||||
|
|
||||||
//ANSI SQL extract() function is supported on the databases we care most
|
//ANSI SQL extract() function is supported on the databases we care most
|
||||||
//about (though it is called datepart() in some of them) but HQL defines
|
//about (though it is called datepart() in some of them) but HQL defines
|
||||||
//additional non-standard temporal field types, which must be emulated in
|
//additional non-standard temporal field types, which must be emulated in
|
||||||
|
|
|
@ -210,6 +210,7 @@ public class HSQLDialect extends Dialect {
|
||||||
CommonFunctionFactory.varPopSamp( queryEngine );
|
CommonFunctionFactory.varPopSamp( queryEngine );
|
||||||
CommonFunctionFactory.addMonths( queryEngine );
|
CommonFunctionFactory.addMonths( queryEngine );
|
||||||
CommonFunctionFactory.monthsBetween( queryEngine );
|
CommonFunctionFactory.monthsBetween( queryEngine );
|
||||||
|
CommonFunctionFactory.collate_quoted( queryEngine );
|
||||||
|
|
||||||
if ( getVersion().isSameOrAfter( 2 ) ) {
|
if ( getVersion().isSameOrAfter( 2 ) ) {
|
||||||
//SYSDATE is similar to LOCALTIMESTAMP but it returns the timestamp when it is called
|
//SYSDATE is similar to LOCALTIMESTAMP but it returns the timestamp when it is called
|
||||||
|
|
|
@ -2185,6 +2185,32 @@ public class CommonFunctionFactory {
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the 'collate' operator which exists on at least Postgres, MySQL, Oracle, and SQL Server
|
||||||
|
*/
|
||||||
|
public static void collate(QueryEngine queryEngine) {
|
||||||
|
queryEngine.getSqmFunctionRegistry().patternDescriptorBuilder("collate", "(?1 collate ?2)")
|
||||||
|
.setInvariantType(
|
||||||
|
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||||
|
)
|
||||||
|
.setExactArgumentCount( 2 )
|
||||||
|
.setArgumentListSignature("(string as collation)")
|
||||||
|
.register();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HSQL requires quotes around certain collations
|
||||||
|
*/
|
||||||
|
public static void collate_quoted(QueryEngine queryEngine) {
|
||||||
|
queryEngine.getSqmFunctionRegistry().patternDescriptorBuilder("collate", "(?1 collate '?2')")
|
||||||
|
.setInvariantType(
|
||||||
|
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||||
|
)
|
||||||
|
.setExactArgumentCount( 2 )
|
||||||
|
.setArgumentListSignature("(string as collation)")
|
||||||
|
.register();
|
||||||
|
}
|
||||||
|
|
||||||
public static void dateTrunc(QueryEngine queryEngine) {
|
public static void dateTrunc(QueryEngine queryEngine) {
|
||||||
queryEngine.getSqmFunctionRegistry().patternDescriptorBuilder( "date_trunc", "date_trunc('?1',?2)" )
|
queryEngine.getSqmFunctionRegistry().patternDescriptorBuilder( "date_trunc", "date_trunc('?1',?2)" )
|
||||||
.setInvariantType(
|
.setInvariantType(
|
||||||
|
|
|
@ -114,7 +114,7 @@ import org.hibernate.query.sqm.tree.expression.SqmByUnit;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
|
import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCaseSimple;
|
import org.hibernate.query.sqm.tree.expression.SqmCaseSimple;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCastTarget;
|
import org.hibernate.query.sqm.tree.expression.SqmCastTarget;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCollate;
|
import org.hibernate.query.sqm.tree.expression.SqmCollation;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCollectionSize;
|
import org.hibernate.query.sqm.tree.expression.SqmCollectionSize;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmDistinct;
|
import org.hibernate.query.sqm.tree.expression.SqmDistinct;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmDurationUnit;
|
import org.hibernate.query.sqm.tree.expression.SqmDurationUnit;
|
||||||
|
@ -1912,7 +1912,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
private Map<Class<?>, Enum<?>> getPossibleEnumValues(HqlParser.ExpressionContext expressionContext) {
|
private Map<Class<?>, Enum<?>> getPossibleEnumValues(HqlParser.ExpressionContext expressionContext) {
|
||||||
ParseTree ctx;
|
ParseTree ctx;
|
||||||
// Traverse the expression structure according to the grammar
|
// Traverse the expression structure according to the grammar
|
||||||
if ( expressionContext instanceof HqlParser.CollateExpressionContext && expressionContext.getChildCount() == 1 ) {
|
if ( expressionContext instanceof HqlParser.BarePrimaryExpressionContext && expressionContext.getChildCount() == 1 ) {
|
||||||
ctx = expressionContext.getChild( 0 );
|
ctx = expressionContext.getChild( 0 );
|
||||||
|
|
||||||
while ( ctx instanceof HqlParser.PrimaryExpressionContext && ctx.getChildCount() == 1 ) {
|
while ( ctx instanceof HqlParser.PrimaryExpressionContext && ctx.getChildCount() == 1 ) {
|
||||||
|
@ -2326,17 +2326,30 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitCollateExpression(HqlParser.CollateExpressionContext ctx) {
|
public Object visitCollationExpression(HqlParser.CollationExpressionContext ctx) {
|
||||||
SqmExpression<?> expression = (SqmExpression<?>) ctx.getChild( 0 ).accept( this );
|
|
||||||
if ( ctx.getChildCount() == 1 ) {
|
|
||||||
return expression;
|
|
||||||
}
|
|
||||||
if ( creationOptions.useStrictJpaCompliance() ) {
|
if ( creationOptions.useStrictJpaCompliance() ) {
|
||||||
throw new StrictJpaComplianceViolation(
|
throw new StrictJpaComplianceViolation(
|
||||||
StrictJpaComplianceViolation.Type.COLLATIONS
|
StrictJpaComplianceViolation.Type.COLLATIONS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return new SqmCollate<>( expression, ctx.getChild( 1 ).getChild( 1 ).getText() );
|
|
||||||
|
final SqmExpression<?> expressionToCollate = (SqmExpression<?>) ctx.getChild( 2 ).accept( this );
|
||||||
|
final SqmCollation castTargetExpression = (SqmCollation) ctx.getChild( 4 ).accept( this );
|
||||||
|
|
||||||
|
return getFunctionDescriptor("collate").generateSqmExpression(
|
||||||
|
asList( expressionToCollate, castTargetExpression ),
|
||||||
|
null, //why not string?
|
||||||
|
creationContext.getQueryEngine(),
|
||||||
|
creationContext.getJpaMetamodel().getTypeConfiguration()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object visitCollation(HqlParser.CollationContext ctx) {
|
||||||
|
return new SqmCollation(
|
||||||
|
ctx.getChild( 0 ).getText(),
|
||||||
|
null,
|
||||||
|
creationContext.getNodeBuilder() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -3466,7 +3479,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
|
|
||||||
return getFunctionDescriptor("format").generateSqmExpression(
|
return getFunctionDescriptor("format").generateSqmExpression(
|
||||||
asList( expressionToCast, format ),
|
asList( expressionToCast, format ),
|
||||||
null,
|
null, //why not string?
|
||||||
creationContext.getQueryEngine(),
|
creationContext.getQueryEngine(),
|
||||||
creationContext.getJpaMetamodel().getTypeConfiguration()
|
creationContext.getJpaMetamodel().getTypeConfiguration()
|
||||||
);
|
);
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.hibernate.query.sqm.tree.domain.SqmMinIndexPath;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmPluralPartJoin;
|
import org.hibernate.query.sqm.tree.domain.SqmPluralPartJoin;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
|
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
|
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmAny;
|
import org.hibernate.query.sqm.tree.expression.SqmAny;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic;
|
import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmByUnit;
|
import org.hibernate.query.sqm.tree.expression.SqmByUnit;
|
||||||
|
@ -34,30 +35,29 @@ import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCaseSimple;
|
import org.hibernate.query.sqm.tree.expression.SqmCaseSimple;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCastTarget;
|
import org.hibernate.query.sqm.tree.expression.SqmCastTarget;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCoalesce;
|
import org.hibernate.query.sqm.tree.expression.SqmCoalesce;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCollate;
|
import org.hibernate.query.sqm.tree.expression.SqmCollation;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCollectionSize;
|
import org.hibernate.query.sqm.tree.expression.SqmCollectionSize;
|
||||||
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
|
import org.hibernate.query.sqm.tree.expression.SqmDistinct;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmDurationUnit;
|
import org.hibernate.query.sqm.tree.expression.SqmDurationUnit;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmEnumLiteral;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmEvery;
|
import org.hibernate.query.sqm.tree.expression.SqmEvery;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmExtractUnit;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmFieldLiteral;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmFormat;
|
import org.hibernate.query.sqm.tree.expression.SqmFormat;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmModifiedSubQueryExpression;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmParameterizedEntityType;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmEnumLiteral;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmFieldLiteral;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
|
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
|
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmModifiedSubQueryExpression;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmNamedParameter;
|
import org.hibernate.query.sqm.tree.expression.SqmNamedParameter;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmParameterizedEntityType;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
|
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmStar;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmSummarization;
|
import org.hibernate.query.sqm.tree.expression.SqmSummarization;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmToDuration;
|
import org.hibernate.query.sqm.tree.expression.SqmToDuration;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmTrimSpecification;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmTuple;
|
import org.hibernate.query.sqm.tree.expression.SqmTuple;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmUnaryOperation;
|
import org.hibernate.query.sqm.tree.expression.SqmUnaryOperation;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmDistinct;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmExtractUnit;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmStar;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmTrimSpecification;
|
|
||||||
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
|
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
|
||||||
import org.hibernate.query.sqm.tree.from.SqmCrossJoin;
|
import org.hibernate.query.sqm.tree.from.SqmCrossJoin;
|
||||||
import org.hibernate.query.sqm.tree.from.SqmEntityJoin;
|
import org.hibernate.query.sqm.tree.from.SqmEntityJoin;
|
||||||
|
@ -197,7 +197,7 @@ public interface SemanticQueryWalker<T> {
|
||||||
|
|
||||||
T visitTuple(SqmTuple<?> sqmTuple);
|
T visitTuple(SqmTuple<?> sqmTuple);
|
||||||
|
|
||||||
T visitCollate(SqmCollate<?> sqmCollate);
|
T visitCollation(SqmCollation sqmCollate);
|
||||||
|
|
||||||
T visitBinaryArithmeticExpression(SqmBinaryArithmetic<?> expression);
|
T visitBinaryArithmeticExpression(SqmBinaryArithmetic<?> expression);
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ public class SqmFunctionRegistry {
|
||||||
* Get a builder for creating and registering a pattern-based function descriptor.
|
* Get a builder for creating and registering a pattern-based function descriptor.
|
||||||
*
|
*
|
||||||
* @param registrationKey The name under which the descriptor will get registered
|
* @param registrationKey The name under which the descriptor will get registered
|
||||||
* @param pattern The pattern defining the the underlying function call
|
* @param pattern The pattern defining the underlying function call
|
||||||
*
|
*
|
||||||
* @return The builder
|
* @return The builder
|
||||||
*/
|
*/
|
||||||
|
@ -119,7 +119,7 @@ public class SqmFunctionRegistry {
|
||||||
* Get a builder for creating and registering a pattern-based aggregate function descriptor.
|
* Get a builder for creating and registering a pattern-based aggregate function descriptor.
|
||||||
*
|
*
|
||||||
* @param registrationKey The name under which the descriptor will get registered
|
* @param registrationKey The name under which the descriptor will get registered
|
||||||
* @param pattern The pattern defining the the underlying function call
|
* @param pattern The pattern defining the underlying function call
|
||||||
*
|
*
|
||||||
* @return The builder
|
* @return The builder
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -40,7 +40,7 @@ import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCaseSimple;
|
import org.hibernate.query.sqm.tree.expression.SqmCaseSimple;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCastTarget;
|
import org.hibernate.query.sqm.tree.expression.SqmCastTarget;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCoalesce;
|
import org.hibernate.query.sqm.tree.expression.SqmCoalesce;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCollate;
|
import org.hibernate.query.sqm.tree.expression.SqmCollation;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCollectionSize;
|
import org.hibernate.query.sqm.tree.expression.SqmCollectionSize;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmDistinct;
|
import org.hibernate.query.sqm.tree.expression.SqmDistinct;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmDurationUnit;
|
import org.hibernate.query.sqm.tree.expression.SqmDurationUnit;
|
||||||
|
@ -53,10 +53,10 @@ import org.hibernate.query.sqm.tree.expression.SqmFormat;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
|
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
|
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmModifiedSubQueryExpression;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmNamedParameter;
|
import org.hibernate.query.sqm.tree.expression.SqmNamedParameter;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmParameterizedEntityType;
|
import org.hibernate.query.sqm.tree.expression.SqmParameterizedEntityType;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
|
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmModifiedSubQueryExpression;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmStar;
|
import org.hibernate.query.sqm.tree.expression.SqmStar;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmSummarization;
|
import org.hibernate.query.sqm.tree.expression.SqmSummarization;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmToDuration;
|
import org.hibernate.query.sqm.tree.expression.SqmToDuration;
|
||||||
|
@ -977,7 +977,7 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitCollate(SqmCollate<?> sqmCollate) {
|
public Object visitCollation(SqmCollation sqmCollate) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -829,7 +829,6 @@ public class CteInsertHandler implements InsertHandler {
|
||||||
insertSelectSpec.addSortSpecification(
|
insertSelectSpec.addSortSpecification(
|
||||||
new SortSpecification(
|
new SortSpecification(
|
||||||
rowNumberColumnReference,
|
rowNumberColumnReference,
|
||||||
null,
|
|
||||||
SortOrder.ASCENDING
|
SortOrder.ASCENDING
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -996,7 +995,6 @@ public class CteInsertHandler implements InsertHandler {
|
||||||
finalResultQuery.addSortSpecification(
|
finalResultQuery.addSortSpecification(
|
||||||
new SortSpecification(
|
new SortSpecification(
|
||||||
idColumnReference,
|
idColumnReference,
|
||||||
null,
|
|
||||||
SortOrder.ASCENDING
|
SortOrder.ASCENDING
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -317,7 +317,6 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio
|
||||||
idSelectQuerySpec.addSortSpecification(
|
idSelectQuerySpec.addSortSpecification(
|
||||||
new SortSpecification(
|
new SortSpecification(
|
||||||
columnReference,
|
columnReference,
|
||||||
null,
|
|
||||||
SortOrder.ASCENDING
|
SortOrder.ASCENDING
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -40,29 +40,29 @@ import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCaseSimple;
|
import org.hibernate.query.sqm.tree.expression.SqmCaseSimple;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCastTarget;
|
import org.hibernate.query.sqm.tree.expression.SqmCastTarget;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCoalesce;
|
import org.hibernate.query.sqm.tree.expression.SqmCoalesce;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCollate;
|
import org.hibernate.query.sqm.tree.expression.SqmCollation;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCollectionSize;
|
import org.hibernate.query.sqm.tree.expression.SqmCollectionSize;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmDistinct;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmDurationUnit;
|
import org.hibernate.query.sqm.tree.expression.SqmDurationUnit;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmEnumLiteral;
|
import org.hibernate.query.sqm.tree.expression.SqmEnumLiteral;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmEvery;
|
import org.hibernate.query.sqm.tree.expression.SqmEvery;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmExtractUnit;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmFieldLiteral;
|
import org.hibernate.query.sqm.tree.expression.SqmFieldLiteral;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmFormat;
|
import org.hibernate.query.sqm.tree.expression.SqmFormat;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
|
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
|
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmModifiedSubQueryExpression;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmNamedParameter;
|
import org.hibernate.query.sqm.tree.expression.SqmNamedParameter;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmParameterizedEntityType;
|
import org.hibernate.query.sqm.tree.expression.SqmParameterizedEntityType;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
|
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmModifiedSubQueryExpression;
|
import org.hibernate.query.sqm.tree.expression.SqmStar;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmSummarization;
|
import org.hibernate.query.sqm.tree.expression.SqmSummarization;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmToDuration;
|
import org.hibernate.query.sqm.tree.expression.SqmToDuration;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmTrimSpecification;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmTuple;
|
import org.hibernate.query.sqm.tree.expression.SqmTuple;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmUnaryOperation;
|
import org.hibernate.query.sqm.tree.expression.SqmUnaryOperation;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmDistinct;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmExtractUnit;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmStar;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmTrimSpecification;
|
|
||||||
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
|
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
|
||||||
import org.hibernate.query.sqm.tree.from.SqmCrossJoin;
|
import org.hibernate.query.sqm.tree.from.SqmCrossJoin;
|
||||||
import org.hibernate.query.sqm.tree.from.SqmEntityJoin;
|
import org.hibernate.query.sqm.tree.from.SqmEntityJoin;
|
||||||
|
@ -676,8 +676,7 @@ public abstract class BaseSemanticQueryWalker implements SemanticQueryWalker<Obj
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitCollate(SqmCollate<?> sqmCollate) {
|
public Object visitCollation(SqmCollation sqmCollate) {
|
||||||
sqmCollate.getExpression().accept( this );
|
|
||||||
return sqmCollate;
|
return sqmCollate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ import org.hibernate.query.sqm.tree.SqmJoinType;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmCorrelatedRootJoin;
|
import org.hibernate.query.sqm.tree.domain.SqmCorrelatedRootJoin;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmCorrelation;
|
import org.hibernate.query.sqm.tree.domain.SqmCorrelation;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmPluralPartJoin;
|
import org.hibernate.query.sqm.tree.domain.SqmPluralPartJoin;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmModifiedSubQueryExpression;
|
import org.hibernate.query.sqm.tree.expression.*;
|
||||||
import org.hibernate.query.sqm.tree.insert.SqmInsertStatement;
|
import org.hibernate.query.sqm.tree.insert.SqmInsertStatement;
|
||||||
import org.hibernate.sql.ast.tree.expression.ModifiedSubQueryExpression;
|
import org.hibernate.sql.ast.tree.expression.ModifiedSubQueryExpression;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmTreatedRoot;
|
import org.hibernate.query.sqm.tree.domain.SqmTreatedRoot;
|
||||||
|
@ -175,40 +175,6 @@ import org.hibernate.query.sqm.tree.domain.SqmMinIndexPath;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
|
import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath;
|
||||||
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
|
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
|
||||||
import org.hibernate.query.sqm.tree.expression.Conversion;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmAliasedNodeRef;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmAny;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmByUnit;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCaseSimple;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCastTarget;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCollate;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmCollectionSize;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmDistinct;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmDurationUnit;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmEnumLiteral;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmEvery;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmExtractUnit;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmFieldLiteral;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmFormat;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmJpaCriteriaParameterWrapper;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmLiteralNull;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmNamedParameter;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmParameterizedEntityType;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmStar;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmSummarization;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmToDuration;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmTrimSpecification;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmTuple;
|
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmUnaryOperation;
|
|
||||||
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
|
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
|
||||||
import org.hibernate.query.sqm.tree.from.SqmCrossJoin;
|
import org.hibernate.query.sqm.tree.from.SqmCrossJoin;
|
||||||
import org.hibernate.query.sqm.tree.from.SqmEntityJoin;
|
import org.hibernate.query.sqm.tree.from.SqmEntityJoin;
|
||||||
|
@ -281,7 +247,7 @@ import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
|
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
|
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.CastTarget;
|
import org.hibernate.sql.ast.tree.expression.CastTarget;
|
||||||
import org.hibernate.sql.ast.tree.expression.Collate;
|
import org.hibernate.sql.ast.tree.expression.Collation;
|
||||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
import org.hibernate.sql.ast.tree.expression.Distinct;
|
import org.hibernate.sql.ast.tree.expression.Distinct;
|
||||||
import org.hibernate.sql.ast.tree.expression.Duration;
|
import org.hibernate.sql.ast.tree.expression.Duration;
|
||||||
|
@ -3707,7 +3673,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
subQuerySpec.addSortSpecification(
|
subQuerySpec.addSortSpecification(
|
||||||
new SortSpecification(
|
new SortSpecification(
|
||||||
columnReference,
|
columnReference,
|
||||||
null,
|
|
||||||
max ? SortOrder.DESCENDING : SortOrder.ASCENDING
|
max ? SortOrder.DESCENDING : SortOrder.ASCENDING
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -4559,11 +4524,8 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitCollate(SqmCollate<?> sqmCollate) {
|
public Object visitCollation(SqmCollation sqmCollation) {
|
||||||
return new Collate(
|
return new Collation( sqmCollation.getLiteralValue() );
|
||||||
(Expression) sqmCollate.getExpression().accept( this ),
|
|
||||||
sqmCollate.getCollation()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -4628,10 +4590,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitFormat(SqmFormat sqmFormat) {
|
public Object visitFormat(SqmFormat sqmFormat) {
|
||||||
return new Format(
|
return new Format( sqmFormat.getLiteralValue() );
|
||||||
sqmFormat.getLiteralValue(),
|
|
||||||
(BasicValuedMapping) sqmFormat.getNodeType()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.query.sqm.tree.expression;
|
|
||||||
|
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Christian Beikov
|
|
||||||
*/
|
|
||||||
public class SqmCollate<T> extends AbstractSqmExpression<T> {
|
|
||||||
|
|
||||||
private final SqmExpression<T> expression;
|
|
||||||
private final String collation;
|
|
||||||
|
|
||||||
public SqmCollate(SqmExpression<T> expression, String collation) {
|
|
||||||
super( expression.getNodeType(), expression.nodeBuilder() );
|
|
||||||
assert !(expression instanceof SqmTuple);
|
|
||||||
this.expression = expression;
|
|
||||||
this.collation = collation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SqmExpression<T> getExpression() {
|
|
||||||
return expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCollation() {
|
|
||||||
return collation;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <X> X accept(SemanticQueryWalker<X> walker) {
|
|
||||||
return walker.visitCollate( this );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void appendHqlString(StringBuilder sb) {
|
|
||||||
expression.appendHqlString( sb );
|
|
||||||
sb.append( " collate " );
|
|
||||||
sb.append( collation );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* 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.query.sqm.tree.expression;
|
||||||
|
|
||||||
|
import org.hibernate.query.sqm.NodeBuilder;
|
||||||
|
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||||
|
import org.hibernate.query.sqm.SqmExpressable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class SqmCollation extends SqmLiteral<String> {
|
||||||
|
public SqmCollation(String value, SqmExpressable<String> inherentType, NodeBuilder nodeBuilder) {
|
||||||
|
super(value, inherentType, nodeBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R> R accept(SemanticQueryWalker<R> walker) {
|
||||||
|
return walker.visitCollation( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendHqlString(StringBuilder sb) {
|
||||||
|
sb.append( getLiteralValue() );
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
|
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
|
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.CastTarget;
|
import org.hibernate.sql.ast.tree.expression.CastTarget;
|
||||||
import org.hibernate.sql.ast.tree.expression.Collate;
|
import org.hibernate.sql.ast.tree.expression.Collation;
|
||||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
import org.hibernate.sql.ast.tree.expression.Distinct;
|
import org.hibernate.sql.ast.tree.expression.Distinct;
|
||||||
import org.hibernate.sql.ast.tree.expression.Duration;
|
import org.hibernate.sql.ast.tree.expression.Duration;
|
||||||
|
@ -149,7 +149,7 @@ public interface SqlAstWalker {
|
||||||
|
|
||||||
void visitTuple(SqlTuple tuple);
|
void visitTuple(SqlTuple tuple);
|
||||||
|
|
||||||
void visitCollate(Collate collate);
|
void visitCollation(Collation collation);
|
||||||
|
|
||||||
void visitParameter(JdbcParameter jdbcParameter);
|
void visitParameter(JdbcParameter jdbcParameter);
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
|
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
|
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.CastTarget;
|
import org.hibernate.sql.ast.tree.expression.CastTarget;
|
||||||
import org.hibernate.sql.ast.tree.expression.Collate;
|
import org.hibernate.sql.ast.tree.expression.Collation;
|
||||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
import org.hibernate.sql.ast.tree.expression.Distinct;
|
import org.hibernate.sql.ast.tree.expression.Distinct;
|
||||||
import org.hibernate.sql.ast.tree.expression.Duration;
|
import org.hibernate.sql.ast.tree.expression.Duration;
|
||||||
|
@ -4335,10 +4335,8 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitCollate(Collate collate) {
|
public void visitCollation(Collation collation) {
|
||||||
collate.getExpression().accept( this );
|
appendSql( collation.getCollation() );
|
||||||
appendSql( " collate " );
|
|
||||||
appendSql( collate.getCollation() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,7 +19,7 @@ import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
|
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
|
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.CastTarget;
|
import org.hibernate.sql.ast.tree.expression.CastTarget;
|
||||||
import org.hibernate.sql.ast.tree.expression.Collate;
|
import org.hibernate.sql.ast.tree.expression.Collation;
|
||||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||||
import org.hibernate.sql.ast.tree.expression.Distinct;
|
import org.hibernate.sql.ast.tree.expression.Distinct;
|
||||||
import org.hibernate.sql.ast.tree.expression.Duration;
|
import org.hibernate.sql.ast.tree.expression.Duration;
|
||||||
|
@ -162,8 +162,7 @@ public class AbstractSqlAstWalker implements SqlAstWalker {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitCollate(Collate collate) {
|
public void visitCollation(Collation collation) {
|
||||||
collate.getExpression().accept( this );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,106 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.sql.ast.tree.expression;
|
|
||||||
|
|
||||||
import org.hibernate.mapping.IndexedConsumer;
|
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
|
||||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
|
||||||
import org.hibernate.metamodel.mapping.SqlExpressable;
|
|
||||||
import org.hibernate.query.sqm.sql.internal.DomainResultProducer;
|
|
||||||
import org.hibernate.sql.ast.SqlAstWalker;
|
|
||||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
|
||||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
|
||||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Christian Beikov
|
|
||||||
*/
|
|
||||||
public class Collate implements Expression, SqlExpressable, SqlAstNode, DomainResultProducer {
|
|
||||||
|
|
||||||
private final Expression expression;
|
|
||||||
private final String collation;
|
|
||||||
|
|
||||||
public Collate(Expression expression, String collation) {
|
|
||||||
this.expression = expression;
|
|
||||||
this.collation = collation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Expression getExpression() {
|
|
||||||
return expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCollation() {
|
|
||||||
return collation;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JdbcMapping getJdbcMapping() {
|
|
||||||
if ( expression instanceof SqlExpressable ) {
|
|
||||||
return ( (SqlExpressable) expression ).getJdbcMapping();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( getExpressionType() instanceof SqlExpressable ) {
|
|
||||||
return ( (SqlExpressable) getExpressionType() ).getJdbcMapping();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( getExpressionType() != null ) {
|
|
||||||
final JdbcMappingContainer mappingContainer = getExpressionType();
|
|
||||||
assert mappingContainer.getJdbcTypeCount() == 1;
|
|
||||||
return mappingContainer.getJdbcMappings().get( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JdbcMappingContainer getExpressionType() {
|
|
||||||
return expression.getExpressionType();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void accept(SqlAstWalker sqlTreeWalker) {
|
|
||||||
sqlTreeWalker.visitCollate( this );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DomainResult createDomainResult(
|
|
||||||
String resultVariable,
|
|
||||||
DomainResultCreationState creationState) {
|
|
||||||
final JavaType javaTypeDescriptor = expression.getExpressionType().getJdbcMappings().get( 0 ).getJavaTypeDescriptor();
|
|
||||||
return new BasicResult(
|
|
||||||
creationState.getSqlAstCreationState().getSqlExpressionResolver().resolveSqlSelection(
|
|
||||||
this,
|
|
||||||
javaTypeDescriptor,
|
|
||||||
creationState.getSqlAstCreationState().getCreationContext().getDomainModel().getTypeConfiguration()
|
|
||||||
).getValuesArrayPosition(),
|
|
||||||
resultVariable,
|
|
||||||
javaTypeDescriptor
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void applySqlSelections(DomainResultCreationState creationState) {
|
|
||||||
final SqlAstCreationState sqlAstCreationState = creationState.getSqlAstCreationState();
|
|
||||||
final SqlExpressionResolver sqlExpressionResolver = sqlAstCreationState.getSqlExpressionResolver();
|
|
||||||
|
|
||||||
sqlExpressionResolver.resolveSqlSelection(
|
|
||||||
this,
|
|
||||||
expression.getExpressionType().getJdbcMappings().get( 0 ).getJavaTypeDescriptor(),
|
|
||||||
sqlAstCreationState.getCreationContext().getDomainModel().getTypeConfiguration()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
|
|
||||||
action.accept( offset, getJdbcMapping() );
|
|
||||||
return getJdbcTypeCount();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* 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.sql.ast.tree.expression;
|
||||||
|
|
||||||
|
import org.hibernate.mapping.IndexedConsumer;
|
||||||
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
|
import org.hibernate.metamodel.mapping.SqlExpressable;
|
||||||
|
import org.hibernate.sql.ast.SqlAstWalker;
|
||||||
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public class Collation implements SqlExpressable, SqlAstNode {
|
||||||
|
|
||||||
|
private final String collation;
|
||||||
|
|
||||||
|
public Collation(String collation) {
|
||||||
|
this.collation = collation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCollation() {
|
||||||
|
return collation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(SqlAstWalker walker) {
|
||||||
|
walker.visitCollation( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
|
||||||
|
return getJdbcTypeCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JdbcMapping getJdbcMapping() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,6 @@
|
||||||
package org.hibernate.sql.ast.tree.expression;
|
package org.hibernate.sql.ast.tree.expression;
|
||||||
|
|
||||||
import org.hibernate.mapping.IndexedConsumer;
|
import org.hibernate.mapping.IndexedConsumer;
|
||||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
|
||||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.metamodel.mapping.SqlExpressable;
|
import org.hibernate.metamodel.mapping.SqlExpressable;
|
||||||
import org.hibernate.sql.ast.SqlAstWalker;
|
import org.hibernate.sql.ast.SqlAstWalker;
|
||||||
|
@ -20,11 +19,9 @@ import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
*/
|
*/
|
||||||
public class Format implements SqlExpressable, SqlAstNode {
|
public class Format implements SqlExpressable, SqlAstNode {
|
||||||
private String format;
|
private String format;
|
||||||
private BasicValuedMapping type;
|
|
||||||
|
|
||||||
public Format(String format, BasicValuedMapping type) {
|
public Format(String format) {
|
||||||
this.format = format;
|
this.format = format;
|
||||||
this.type = type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormat() {
|
public String getFormat() {
|
||||||
|
@ -33,7 +30,7 @@ public class Format implements SqlExpressable, SqlAstNode {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JdbcMapping getJdbcMapping() {
|
public JdbcMapping getJdbcMapping() {
|
||||||
return type.getJdbcMapping();
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -43,7 +40,6 @@ public class Format implements SqlExpressable, SqlAstNode {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
|
public int forEachJdbcType(int offset, IndexedConsumer<JdbcMapping> action) {
|
||||||
action.accept( offset, type.getJdbcMapping() );
|
|
||||||
return getJdbcTypeCount();
|
return getJdbcTypeCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.hibernate.query.NullPrecedence;
|
||||||
import org.hibernate.query.SortOrder;
|
import org.hibernate.query.SortOrder;
|
||||||
import org.hibernate.sql.ast.SqlAstWalker;
|
import org.hibernate.sql.ast.SqlAstWalker;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
import org.hibernate.sql.ast.tree.expression.Collate;
|
import org.hibernate.sql.ast.tree.expression.Collation;
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,18 +20,15 @@ public class SortSpecification implements SqlAstNode {
|
||||||
private final Expression sortExpression;
|
private final Expression sortExpression;
|
||||||
private final SortOrder sortOrder;
|
private final SortOrder sortOrder;
|
||||||
private final NullPrecedence nullPrecedence;
|
private final NullPrecedence nullPrecedence;
|
||||||
|
private final Collation collation;
|
||||||
|
|
||||||
public SortSpecification(Expression sortExpression, String collation, SortOrder sortOrder) {
|
public SortSpecification(Expression sortExpression, SortOrder sortOrder) {
|
||||||
this( sortExpression, collation, sortOrder, NullPrecedence.NONE );
|
this( sortExpression, null, sortOrder, NullPrecedence.NONE );
|
||||||
}
|
}
|
||||||
|
|
||||||
public SortSpecification(Expression sortExpression, String collation, SortOrder sortOrder, NullPrecedence nullPrecedence) {
|
public SortSpecification(Expression sortExpression, String collation, SortOrder sortOrder, NullPrecedence nullPrecedence) {
|
||||||
if ( collation == null ) {
|
this.sortExpression = sortExpression;
|
||||||
this.sortExpression = sortExpression;
|
this.collation = collation == null ? null : new Collation(collation);
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.sortExpression = new Collate( sortExpression, collation );
|
|
||||||
}
|
|
||||||
this.sortOrder = sortOrder;
|
this.sortOrder = sortOrder;
|
||||||
this.nullPrecedence = nullPrecedence;
|
this.nullPrecedence = nullPrecedence;
|
||||||
}
|
}
|
||||||
|
@ -40,6 +37,10 @@ public class SortSpecification implements SqlAstNode {
|
||||||
return sortExpression;
|
return sortExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collation getCollation() {
|
||||||
|
return collation;
|
||||||
|
}
|
||||||
|
|
||||||
public SortOrder getSortOrder() {
|
public SortOrder getSortOrder() {
|
||||||
return sortOrder;
|
return sortOrder;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* 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.orm.test.query.hql;
|
||||||
|
|
||||||
|
import org.hibernate.dialect.HSQLDialect;
|
||||||
|
import org.hibernate.dialect.MySQLDialect;
|
||||||
|
import org.hibernate.dialect.PostgreSQLDialect;
|
||||||
|
import org.hibernate.testing.orm.domain.StandardDomainModel;
|
||||||
|
import org.hibernate.testing.orm.domain.gambit.EntityOfBasics;
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.RequiresDialect;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.sql.Date;
|
||||||
|
import java.sql.Time;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gavin King
|
||||||
|
*/
|
||||||
|
@ServiceRegistry
|
||||||
|
@DomainModel( standardModels = StandardDomainModel.GAMBIT )
|
||||||
|
@SessionFactory
|
||||||
|
public class CollateTests {
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public void prepareData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
em -> {
|
||||||
|
EntityOfBasics entity = new EntityOfBasics();
|
||||||
|
entity.setTheString("1234589");
|
||||||
|
entity.setId(123);
|
||||||
|
entity.setTheDate( new Date( 74, 2, 25 ) );
|
||||||
|
entity.setTheTime( new Time( 20, 10, 8 ) );
|
||||||
|
entity.setTheTimestamp( new Timestamp( 121, 4, 27, 13, 22, 50, 123456789 ) );
|
||||||
|
em.persist(entity);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test @RequiresDialect(PostgreSQLDialect.class)
|
||||||
|
public void testCollatePostgreSQL(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
session.createQuery("from EntityOfBasics e where e.theString is not null order by collate(e.theString as ucs_basic)").getResultList();
|
||||||
|
assertThat( session.createQuery("select collate('bar' as ucs_basic) < 'foo'").getSingleResult(), is(true) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test @RequiresDialect(MySQLDialect.class)
|
||||||
|
public void testCollateMySQL(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
session.createQuery("from EntityOfBasics e order by collate(e.theString as utf8mb4_bin)").getResultList();
|
||||||
|
assertThat( session.createQuery("select collate('bar' as utf8mb4_bin) < 'foo'").getSingleResult(), is(true) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test @RequiresDialect(HSQLDialect.class)
|
||||||
|
public void testCollateHSQL(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
session -> {
|
||||||
|
session.createQuery("from EntityOfBasics e order by collate(e.theString as SQL_TEXT_UCC)").getResultList();
|
||||||
|
session.createQuery("from EntityOfBasics e order by collate(e.theString as English)").getResultList();
|
||||||
|
assertThat( session.createQuery("select collate('bar' as English) < 'foo'").getSingleResult(), is(true) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue