diff --git a/hibernate-core/src/main/antlr/org/hibernate/grammars/hql/HqlParser.g4 b/hibernate-core/src/main/antlr/org/hibernate/grammars/hql/HqlParser.g4 index 96ddbe4424..d2a050edd9 100644 --- a/hibernate-core/src/main/antlr/org/hibernate/grammars/hql/HqlParser.g4 +++ b/hibernate-core/src/main/antlr/org/hibernate/grammars/hql/HqlParser.g4 @@ -23,50 +23,86 @@ package org.hibernate.grammars.hql; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Statements +/** + * Toplevel rule, entrypoint to the whole grammar + */ statement - : ( selectStatement | updateStatement | deleteStatement | insertStatement ) EOF + : (selectStatement | updateStatement | deleteStatement | insertStatement) EOF ; +/** + * A 'select' query + */ selectStatement : queryExpression ; +/** + * A 'select' query that occurs within another statement + */ subquery : queryExpression ; +/** + * A declaration of a root entity, with an optional identification variable + */ targetEntity - : entityName identificationVariableDef? + : entityName variable? ; +/** + * A 'delete' statement + */ deleteStatement : DELETE FROM? targetEntity whereClause? ; +/** + * An 'update' statement + */ updateStatement : UPDATE VERSIONED? targetEntity setClause whereClause? ; +/** + * An 'set' list of assignments in an 'update' statement + */ setClause : SET assignment (COMMA assignment)* ; +/** + * An assignment to an entity attribute in an 'update' statement + */ assignment - : dotIdentifierSequence EQUAL expressionOrPredicate + : simplePath EQUAL expressionOrPredicate ; +/** + * An 'insert' statement + */ insertStatement : INSERT INTO? targetEntity targetFields (queryExpression | valuesList) ; +/** + * The list of target entity attributes in an 'insert' statement + */ targetFields - : LEFT_PAREN dotIdentifierSequence (COMMA dotIdentifierSequence)* RIGHT_PAREN + : LEFT_PAREN simplePath (COMMA simplePath)* RIGHT_PAREN ; +/** + * A 'values' clause in an 'insert' statement, with one of more tuples of values to insert + */ valuesList : VALUES values (COMMA values)* ; +/** + * A tuple of values to insert in an 'insert' statement + */ values : LEFT_PAREN expressionOrPredicate (COMMA expressionOrPredicate)* RIGHT_PAREN ; @@ -74,80 +110,131 @@ values // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // QUERY SPEC - general structure of root sqm or sub sqm +/** + * A toplevel query of subquery, which may be a union or intersection of subqueries + */ queryExpression : orderedQuery # SimpleQueryGroup | orderedQuery (setOperator orderedQuery)+ # SetQueryGroup ; +/** + * A query with an optional 'order by' clause + */ orderedQuery : query queryOrder? # QuerySpecExpression | LEFT_PAREN queryExpression RIGHT_PAREN queryOrder? # NestedQueryExpression ; +/** + * An operator whose operands are whole queries + */ setOperator : UNION ALL? | INTERSECT ALL? | EXCEPT ALL? ; +/** + * The 'order by' clause and optional subclauses for limiting and pagination + */ queryOrder : orderByClause limitClause? offsetClause? fetchClause? ; +/** + * An unordered query, with just projection, restriction, and aggregation + * + * - The 'select' clause may come first, in which case 'from' is optional + * - The 'from' clause may come first, in which case 'select' is optional, and comes last + */ query // TODO: add with clause - : selectClause fromClause? whereClause? ( groupByClause havingClause? )? - | fromClause whereClause? ( groupByClause havingClause? )? selectClause? + : selectClause fromClause? whereClause? (groupByClause havingClause?)? + | fromClause whereClause? (groupByClause havingClause?)? selectClause? ; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // FROM clause +/** + * The 'from' clause of a query + */ fromClause - : FROM fromClauseSpace (COMMA fromClauseSpace)* + : FROM entityWithJoins (COMMA entityWithJoins)* ; -fromClauseSpace - : pathRoot ( crossJoin | jpaCollectionJoin | qualifiedJoin )* +/** + * The declaration of a root entity in 'from' clause, along with its joins + */ +entityWithJoins + : rootEntity (join | crossJoin | jpaCollectionJoin)* ; -pathRoot - : entityName identificationVariableDef? +/** + * A root entity declaration in the 'from' clause, with optional identification variable + */ +rootEntity + : entityName variable? ; +/** + * An entity name, for identifying the root entity + */ entityName : identifier (DOT identifier)* ; -identificationVariableDef +/** + * An identification variable (an entity alias) + */ +variable : AS identifier | IDENTIFIER | QUOTED_IDENTIFIER ; +/** + * A 'cross join' to a second root entity (a cartesian product) + */ crossJoin - : CROSS JOIN pathRoot identificationVariableDef? + : CROSS JOIN rootEntity variable? ; +/** + * Deprecated syntax dating back to EJB-QL prior to EJB 3, required by JPA, never documented in Hibernate + */ jpaCollectionJoin - : COMMA IN LEFT_PAREN path RIGHT_PAREN identificationVariableDef? + : COMMA IN LEFT_PAREN path RIGHT_PAREN variable? ; -qualifiedJoin - : joinTypeQualifier JOIN FETCH? qualifiedJoinRhs qualifiedJoinPredicate? +/** + * A 'join', with an optional 'on' or 'with' clause + */ +join + : joinType JOIN FETCH? joinPath joinRestriction? ; -joinTypeQualifier +/** + * The inner or outer join type + */ +joinType : INNER? | (LEFT|RIGHT|FULL)? OUTER? ; -qualifiedJoinRhs - : path identificationVariableDef? +/** + * The joined path, with an optional identification variable + */ +joinPath + : path variable? ; -qualifiedJoinPredicate +/** + * An extra restriction added to the join condition + */ +joinRestriction : (ON | WITH) predicate ; @@ -156,73 +243,115 @@ qualifiedJoinPredicate // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // SELECT clause +/** + * The 'select' clause of a query + */ selectClause - : SELECT DISTINCT? selectionList + : SELECT DISTINCT? selectionList ; +/** + * A projection list: a list of selected items + */ selectionList : selection (COMMA selection)* ; +/** + * An element of a projection list: a selected item, with an optional alias + */ selection - : selectExpression identificationVariableDef? + : selectExpression variable? ; +/** + * A selected item ocurring in the 'select' clause + */ selectExpression - : dynamicInstantiation - | jpaSelectObjectSyntax - | mapEntrySelection - | expressionOrPredicate + : instantiation + | mapEntrySelection + | jpaSelectObjectSyntax + | expressionOrPredicate ; +/** + * The special function entry() which may only occur in the 'select' clause + */ mapEntrySelection : ENTRY LEFT_PAREN path RIGHT_PAREN ; -dynamicInstantiation - : NEW dynamicInstantiationTarget LEFT_PAREN dynamicInstantiationArgs RIGHT_PAREN +/** + * Instantiation using 'select new' + */ +instantiation + : NEW instantiationTarget LEFT_PAREN instantiationArguments RIGHT_PAREN ; -dynamicInstantiationTarget +/** + * The type to be instantiated with 'select new', 'list', 'map', or a fuly-qualified Java class name + */ +instantiationTarget : LIST | MAP - | dotIdentifierSequence + | simplePath ; -dynamicInstantiationArgs - : dynamicInstantiationArg ( COMMA dynamicInstantiationArg )* +/** + * The arguments to a 'select new' instantiation + */ +instantiationArguments + : instantiationArgument (COMMA instantiationArgument)* ; -dynamicInstantiationArg - : dynamicInstantiationArgExpression identificationVariableDef? +/** + * A single argument in a 'select new' instantiation, with an optional alias + */ +instantiationArgument + : instantiationArgumentExpression variable? ; -dynamicInstantiationArgExpression - : expressionOrPredicate - | dynamicInstantiation +/** + * A single argument in a 'select new' instantiation: an expression, or a nested instantiation + */ +instantiationArgumentExpression + : expressionOrPredicate + | instantiation ; +/** + * Deprecated syntax dating back to EJB-QL prior to EJB 3, required by JPA, never documented in Hibernate + */ jpaSelectObjectSyntax - : OBJECT LEFT_PAREN identifier RIGHT_PAREN + : OBJECT LEFT_PAREN identifier RIGHT_PAREN ; - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Path structures -dotIdentifierSequence - : identifier dotIdentifierSequenceContinuation* +/** + * A simple path expression + * + * - a reference to an identification variable (not case-sensitive), + * - followed by a list of period-separated identifiers (case-sensitive) + */ +simplePath + : identifier simplePathElement* ; -dotIdentifierSequenceContinuation +/** + * An element of a simple path expression: a period, and an identifier (case-sensitive) + */ +simplePathElement : DOT identifier ; - /** + * A much more complicated path expression involving operators and functions + * * A path which needs to be resolved semantically. This recognizes * any path-like structure. Generally, the path is semantically * interpreted by the consumer of the parse-tree. However, there @@ -234,11 +363,16 @@ path | generalPathFragment ; +/** + * A continuation of a path expression "broken" by an operator or function + */ pathContinuation - : DOT dotIdentifierSequence + : DOT simplePath ; /** + * An operator or function that may occur within a path expression + * * Rule for cases where we syntactically know that the path is a * "domain path" because it is one of these special cases: * @@ -254,36 +388,53 @@ syntacticDomainPath | collectionElementNavigablePath | collectionIndexNavigablePath | mapKeyNavigablePath - | dotIdentifierSequence indexedPathAccessFragment + | simplePath indexedPathAccessFragment ; /** - * The main path rule. Recognition for all normal path structures including + * The main path rule + * + * Recognition for all normal path structures including * class, field and enum references as well as navigable paths. * * NOTE : this rule does *not* cover the special syntactic navigable path * cases: TREAT, KEY, ELEMENTS, VALUES */ generalPathFragment - : dotIdentifierSequence indexedPathAccessFragment? + : simplePath indexedPathAccessFragment? ; +/** + * In index operator that "breaks" a path expression + */ indexedPathAccessFragment : LEFT_BRACKET expression RIGHT_BRACKET (DOT generalPathFragment)? ; +/** + * A 'treat()' function that "breaks" a path expression + */ treatedNavigablePath - : TREAT LEFT_PAREN path AS dotIdentifierSequence RIGHT_PAREN pathContinuation? + : TREAT LEFT_PAREN path AS simplePath RIGHT_PAREN pathContinuation? ; +/** + * A 'values()' or 'elements()' function that "breaks" a path expression + */ collectionElementNavigablePath : (VALUE | ELEMENTS) LEFT_PAREN path RIGHT_PAREN pathContinuation? ; +/** + * An 'indices()' function that "breaks" a path expression + */ collectionIndexNavigablePath : INDICES LEFT_PAREN path RIGHT_PAREN ; +/** + * A 'key()' function that "breaks" a path expression + */ mapKeyNavigablePath : KEY LEFT_PAREN path RIGHT_PAREN pathContinuation? ; @@ -292,10 +443,18 @@ mapKeyNavigablePath // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // GROUP BY clause +/** + * The 'group by' clause of a query, controls aggregation + */ groupByClause - : GROUP BY groupByExpression ( COMMA groupByExpression )* + : GROUP BY groupByExpression (COMMA groupByExpression)* ; +/** + * A grouped item that occurs in the 'group by' clause + * + * a select item alias, an ordinal position of a select item, or an expression + */ groupByExpression : identifier | INTEGER_LITERAL @@ -305,6 +464,9 @@ groupByExpression // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //HAVING clause +/** + * The 'having' clause of a query, a restriction on the grouped data + */ havingClause : HAVING predicate ; @@ -313,6 +475,9 @@ havingClause // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ORDER BY clause +/** + * The 'order by' clause of a query, controls sorting + */ orderByClause : ORDER BY sortSpecification (COMMA sortSpecification)* ; @@ -324,54 +489,92 @@ orderByFragment : sortSpecification (COMMA sortSpecification)* ; +/** + * A rule for sorting an item in the 'order by' clause + */ sortSpecification - : sortExpression orderingSpecification? nullsPrecedence? + : sortExpression sortDirection? nullsPrecedence? ; +/** + * A rule for sorting null values + */ nullsPrecedence : NULLS (FIRST | LAST) ; +/** + * A sorted item that occurs in the 'order by' clause + * + * a select item alias, an ordinal position of a select item, or an expression + */ sortExpression : identifier | INTEGER_LITERAL | expression ; -collationExpression - : COLLATE LEFT_PAREN expression AS collation RIGHT_PAREN - ; - -collation - : dotIdentifierSequence - ; - -orderingSpecification +/** + * The direction in which to sort + */ +sortDirection : ASC | DESC ; +/** + * The special 'collate()' functions + */ +collateFunction + : COLLATE LEFT_PAREN expression AS collation RIGHT_PAREN + ; + +/** + * The name of a database-defined collation + * + * Certain databases allow a period in a collation name + */ +collation + : simplePath + ; + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LIMIT/OFFSET clause +/** + * A 'limit' on the number of query results + */ limitClause : LIMIT parameterOrIntegerLiteral ; +/** + * An 'offset' of the first query result to return + */ offsetClause : OFFSET parameterOrIntegerLiteral (ROW | ROWS)? ; +/** + * A much more complex syntax for limits + */ fetchClause : FETCH (FIRST | NEXT) (parameterOrIntegerLiteral | parameterOrNumberLiteral PERCENT) (ROW | ROWS) (ONLY | WITH TIES) ; +/** + * An parameterizable integer literal + */ parameterOrIntegerLiteral : parameter | INTEGER_LITERAL ; +/** + * An parameterizable numeric literal + */ parameterOrNumberLiteral : parameter | INTEGER_LITERAL @@ -383,10 +586,16 @@ parameterOrNumberLiteral // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // WHERE clause & Predicates +/** + * The 'were' clause of a query, update statement, or delete statement + */ whereClause : WHERE predicate ; +/** + * A boolean-valued expression, usually used to express a restriction + */ predicate //highest to lowest precedence : LEFT_PAREN predicate RIGHT_PAREN # GroupedPredicate @@ -396,7 +605,7 @@ predicate | expression NOT? BETWEEN expression AND expression # BetweenPredicate | expression NOT? (LIKE | ILIKE) expression likeEscape? # LikePredicate | expression comparisonOperator expression # ComparisonPredicate - | EXISTS (ELEMENTS|INDICES) LEFT_PAREN dotIdentifierSequence RIGHT_PAREN # ExistsCollectionPartPredicate + | EXISTS (ELEMENTS|INDICES) LEFT_PAREN simplePath RIGHT_PAREN # ExistsCollectionPartPredicate | EXISTS expression # ExistsPredicate | expression NOT? MEMBER OF? path # MemberOfPredicate | NOT predicate # NegatedPredicate @@ -405,6 +614,9 @@ predicate | expression # BooleanExpressionPredicate ; +/** + * An operator which compares values for equality or order + */ comparisonOperator : EQUAL | NOT_EQUAL @@ -416,13 +628,21 @@ comparisonOperator | IS NOT DISTINCT FROM ; +/** + * Any right operand of the 'in' operator + * + * A list of values, a parameter (for a parameterized list of values), a subquery, or an `elements()` or `indices()` function + */ inList - : (ELEMENTS|INDICES) LEFT_PAREN dotIdentifierSequence RIGHT_PAREN # PersistentCollectionReferenceInList + : (ELEMENTS|INDICES) LEFT_PAREN simplePath RIGHT_PAREN # PersistentCollectionReferenceInList | LEFT_PAREN (expressionOrPredicate (COMMA expressionOrPredicate)*)? RIGHT_PAREN# ExplicitTupleInList | LEFT_PAREN subquery RIGHT_PAREN # SubqueryInList | parameter # ParamInList ; +/** + * A single character used to escape the '_' and '%' wildcards in a 'like' pattern + */ likeEscape : ESCAPE (STRING_LITERAL | parameter) ; @@ -431,6 +651,9 @@ likeEscape // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Expression +/** + * An expression, excluding boolean expressions + */ expression //highest to lowest precedence : LEFT_PAREN expression RIGHT_PAREN # GroupedExpression @@ -446,6 +669,9 @@ expression | expression DOUBLE_PIPE expression # ConcatenationExpression ; +/** + * An expression not involving operators + */ primaryExpression : caseList # CaseExpression | literal # LiteralExpression @@ -454,84 +680,139 @@ primaryExpression | entityIdReference # EntityIdExpression | entityVersionReference # EntityVersionExpression | entityNaturalIdReference # EntityNaturalIdExpression - | syntacticDomainPath pathContinuation? # SyntacticPathExpression + | syntacticDomainPath pathContinuation? # SyntacticPathExpression | function # FunctionExpression | generalPathFragment # GeneralPathExpression ; +/** + * Any expression, including boolean expressions + */ expressionOrPredicate : expression | predicate ; +/** + * A binary operator with the same precedence as * + */ multiplicativeOperator : SLASH | PERCENT_OP | ASTERISK ; +/** + * A binary operator with the same precedence as + + */ additiveOperator : PLUS | MINUS ; +/** + * A unary prefix operator + */ signOperator : PLUS | MINUS ; +/** + * The special function 'type()' + */ entityTypeReference : TYPE LEFT_PAREN (path | parameter) RIGHT_PAREN ; +/** + * The special function 'id()' + */ entityIdReference : ID LEFT_PAREN path RIGHT_PAREN pathContinuation? ; +/** + * The special function 'version()' + */ entityVersionReference : VERSION LEFT_PAREN path RIGHT_PAREN ; +/** + * The special function 'naturalid()' + */ entityNaturalIdReference : NATURALID LEFT_PAREN path RIGHT_PAREN pathContinuation? ; +/** + * A 'case' expression, which comes in two forms: "simple", and "searched" + */ caseList : simpleCaseList | searchedCaseList ; +/** + * A simple 'case' expression + */ simpleCaseList : CASE expressionOrPredicate simpleCaseWhen+ caseOtherwise? END ; +/** + * The 'when' clause of a simple case + */ simpleCaseWhen : WHEN expression THEN expressionOrPredicate ; +/** + * The 'else' clause of a 'case' expression + */ caseOtherwise : ELSE expressionOrPredicate ; +/** + * A searched 'case' expression + */ searchedCaseList : CASE searchedCaseWhen+ caseOtherwise? END ; +/** + * The 'when' clause of a searched case + */ searchedCaseWhen : WHEN predicate THEN expressionOrPredicate ; +/** + * A literal value + */ literal : STRING_LITERAL | NULL - | TRUE - | FALSE + | booleanLiteral | numericLiteral | binaryLiteral | temporalLiteral | generalizedLiteral ; +/** + * A boolean literal value + */ +booleanLiteral + : TRUE + | FALSE + ; + +/** + * A numeric literal value, including hexadecimal literals + */ numericLiteral : INTEGER_LITERAL | LONG_LITERAL @@ -542,11 +823,17 @@ numericLiteral | HEX_LITERAL ; +/** + * A binary literal value, as a SQL-style literal, or a braced list of byte literals + */ binaryLiteral : BINARY_LITERAL | LEFT_BRACE HEX_LITERAL (COMMA HEX_LITERAL)* RIGHT_BRACE ; +/** + * A literal date, time, or datetime, in HQL syntax, or as a JDBC-style "escape" syntax + */ temporalLiteral : dateTimeLiteral | dateLiteral @@ -556,33 +843,54 @@ temporalLiteral | jdbcTimeLiteral ; +/** + * A literal datetime, in braces, or with the 'datetime' keyword + */ dateTimeLiteral : LEFT_BRACE dateTime RIGHT_BRACE | DATETIME dateTime ; +/** + * A literal date, in braces, or with the 'date' keyword + */ dateLiteral : LEFT_BRACE date RIGHT_BRACE | DATE date ; +/** + * A literal time, in braces, or with the 'time' keyword + */ timeLiteral : LEFT_BRACE time RIGHT_BRACE | TIME time ; +/** + * A literal datetime + */ dateTime : date time (zoneId | offset)? ; +/** + * A literal date + */ date : year MINUS month MINUS day ; +/** + * A literal time + */ time : hour COLON minute (COLON second)? ; +/** + * A literal offset + */ offset : (PLUS | MINUS) hour (COLON minute)? ; @@ -597,14 +905,23 @@ zoneId : IDENTIFIER (SLASH IDENTIFIER)? | STRING_LITERAL; +/** + * A JDBC-style timestamp escape, as required by JPQL + */ jdbcTimestampLiteral : TIMESTAMP_ESCAPE_START (dateTime | genericTemporalLiteralText) RIGHT_BRACE ; +/** + * A JDBC-style date escape, as required by JPQL + */ jdbcDateLiteral : DATE_ESCAPE_START (date | genericTemporalLiteralText) RIGHT_BRACE ; +/** + * A JDBC-style time escape, as required by JPQL + */ jdbcTimeLiteral : TIME_ESCAPE_START (time | genericTemporalLiteralText) RIGHT_BRACE ; @@ -613,6 +930,9 @@ genericTemporalLiteralText : STRING_LITERAL ; +/** + * A generic format for specifying literal values of arbitary types + */ generalizedLiteral : LEFT_BRACE generalizedLiteralType COLON generalizedLiteralText RIGHT_BRACE ; @@ -621,45 +941,74 @@ generalizedLiteralType : STRING_LITERAL; generalizedLiteralText : STRING_LITERAL; +/** + * A query parameter: a named parameter, or an ordinal parameter + */ parameter : COLON identifier # NamedParameter | QUESTION_MARK INTEGER_LITERAL? # PositionalParameter ; +/** + * A function invocation that may occur in an arbitrary expression + */ function : standardFunction | aggregateFunction | jpaCollectionFunction | hqlCollectionFunction - | jpaNonStandardFunction + | jpaNonstandardFunction | genericFunction ; -jpaNonStandardFunction - : FUNCTION LEFT_PAREN jpaNonStandardFunctionName (COMMA nonStandardFunctionArguments)? RIGHT_PAREN +/** + * A syntax for calling user-defined or native database functions, required by JPQL + */ +jpaNonstandardFunction + : FUNCTION LEFT_PAREN jpaNonstandardFunctionName (COMMA genericFunctionArguments)? RIGHT_PAREN ; -jpaNonStandardFunctionName +/** + * The name of a user-defined or native database function, given as a quoted string + */ +jpaNonstandardFunctionName : STRING_LITERAL ; +/** + * Any function invocation that follows the regular syntax + * + * The function name, followed by a parenthesized list of comma-separated expressions + */ genericFunction - : genericFunctionName LEFT_PAREN (nonStandardFunctionArguments | ASTERISK)? RIGHT_PAREN filterClause? + : genericFunctionName LEFT_PAREN (genericFunctionArguments | ASTERISK)? RIGHT_PAREN filterClause? ; +/** + * The name of a generic function + */ genericFunctionName - : dotIdentifierSequence + : simplePath ; -nonStandardFunctionArguments +/** + * The arguments of a generic function + */ +genericFunctionArguments : (DISTINCT | datetimeField COMMA)? expressionOrPredicate (COMMA expressionOrPredicate)* ; +/** + * The special 'size()' and 'index()' functions defined by JPQL + */ jpaCollectionFunction : SIZE LEFT_PAREN path RIGHT_PAREN # CollectionSizeFunction | INDEX LEFT_PAREN identifier RIGHT_PAREN # CollectionIndexFunction ; +/** + * The special collection functions defined by HQL + */ hqlCollectionFunction : MAXINDEX LEFT_PAREN path RIGHT_PAREN # MaxIndexFunction | MAXELEMENT LEFT_PAREN path RIGHT_PAREN # MaxElementFunction @@ -667,59 +1016,85 @@ hqlCollectionFunction | MINELEMENT LEFT_PAREN path RIGHT_PAREN # MinElementFunction ; +/** + * The special `every()`, `all()`, `any()` and `some()` functions defined by HQL + * + * May be applied to a subquery or collection reference, or may occur as an aggregate function in the 'select' clause + */ aggregateFunction : everyFunction | anyFunction ; +/** + * The functions `every()` and `all()` are synonyms + */ everyFunction : (EVERY|ALL) LEFT_PAREN predicate RIGHT_PAREN filterClause? | (EVERY|ALL) LEFT_PAREN subquery RIGHT_PAREN - | (EVERY|ALL) (ELEMENTS|INDICES) LEFT_PAREN dotIdentifierSequence RIGHT_PAREN + | (EVERY|ALL) (ELEMENTS|INDICES) LEFT_PAREN simplePath RIGHT_PAREN ; +/** + * The functions `any()` and `some()` are synonyms + */ anyFunction : (ANY|SOME) LEFT_PAREN predicate RIGHT_PAREN filterClause? | (ANY|SOME) LEFT_PAREN subquery RIGHT_PAREN - | (ANY|SOME) (ELEMENTS|INDICES) LEFT_PAREN dotIdentifierSequence RIGHT_PAREN + | (ANY|SOME) (ELEMENTS|INDICES) LEFT_PAREN simplePath RIGHT_PAREN ; +/** + * A 'filter' clause: a restriction applied to an aggregate function + */ filterClause : FILTER LEFT_PAREN whereClause RIGHT_PAREN ; +/** + * Any function with an irregular syntax for the argument list + * + * These are all inspired by the syntax of ANSI SQL + */ standardFunction - : castFunction - | extractFunction - | formatFunction - | substringFunction - | overlayFunction - | trimFunction - | padFunction - | positionFunction - | currentDateFunction - | currentTimeFunction - | currentTimestampFunction - | instantFunction - | localDateFunction - | localTimeFunction - | localDateTimeFunction - | offsetDateTimeFunction - | cube - | rollup - | collationExpression + : castFunction + | extractFunction + | formatFunction + | collateFunction + | substringFunction + | overlayFunction + | trimFunction + | padFunction + | positionFunction + | currentDateFunction + | currentTimeFunction + | currentTimestampFunction + | instantFunction + | localDateFunction + | localTimeFunction + | localDateTimeFunction + | offsetDateTimeFunction + | cube + | rollup ; - +/** + * The 'cast()' function for typecasting + */ castFunction : CAST LEFT_PAREN expression AS castTarget RIGHT_PAREN ; +/** + * The target type for a typecast: a typename, together with length or precision/scale + */ castTarget : castTargetType (LEFT_PAREN INTEGER_LITERAL (COMMA INTEGER_LITERAL)? RIGHT_PAREN)? ; /** + * The name of the target type in a typecast + * * Like the `entityName` rule, we have a specialized dotIdentifierSequence rule */ castTargetType @@ -727,6 +1102,9 @@ castTargetType : (i=identifier { $fullTargetName = _localctx.i.getText(); }) (DOT c=identifier { $fullTargetName += ("." + _localctx.c.getText() ); })* ; +/** + * The two formats for the 'substring() function: one defined by JPQL, the other by ANSI SQL + */ substringFunction : SUBSTRING LEFT_PAREN expression COMMA substringFunctionStartArgument (COMMA substringFunctionLengthArgument)? RIGHT_PAREN | SUBSTRING LEFT_PAREN expression FROM substringFunctionStartArgument (FOR substringFunctionLengthArgument)? RIGHT_PAREN @@ -740,6 +1118,9 @@ substringFunctionLengthArgument : expression ; +/** + * The ANSI SQL-style 'trim()' function + */ trimFunction : TRIM LEFT_PAREN trimSpecification? trimCharacter? FROM? expression RIGHT_PAREN ; @@ -754,6 +1135,9 @@ trimCharacter : STRING_LITERAL ; +/** + * A 'pad()' function inspired by 'trim()' + */ padFunction : PAD LEFT_PAREN expression WITH padLength padSpecification padCharacter? RIGHT_PAREN ; @@ -771,6 +1155,9 @@ padLength : expression ; +/** + * The ANSI SQL-style 'overlay()' function + */ overlayFunction : OVERLAY LEFT_PAREN overlayFunctionStringArgument PLACING overlayFunctionReplacementArgument FROM overlayFunctionStartArgument (FOR overlayFunctionLengthArgument)? RIGHT_PAREN ; @@ -791,59 +1178,97 @@ overlayFunctionLengthArgument : expression ; +/** + * The deprecated current_date function required by JPQL + */ currentDateFunction : CURRENT_DATE (LEFT_PAREN RIGHT_PAREN)? | CURRENT DATE ; +/** + * The deprecated current_time function required by JPQL + */ currentTimeFunction : CURRENT_TIME (LEFT_PAREN RIGHT_PAREN)? | CURRENT TIME ; +/** + * The deprecated current_timestamp function required by JPQL + */ currentTimestampFunction : CURRENT_TIMESTAMP (LEFT_PAREN RIGHT_PAREN)? | CURRENT TIMESTAMP ; +/** + * The instant function, and deprecated current_instant function + */ instantFunction : CURRENT_INSTANT (LEFT_PAREN RIGHT_PAREN)? //deprecated legacy syntax | INSTANT ; +/** + * The 'local datetime' function (or literal if you prefer) + */ localDateTimeFunction : LOCAL_DATETIME (LEFT_PAREN RIGHT_PAREN)? | LOCAL DATETIME ; +/** + * The 'offset datetime' function (or literal if you prefer) + */ offsetDateTimeFunction : OFFSET_DATETIME (LEFT_PAREN RIGHT_PAREN)? | OFFSET DATETIME ; +/** + * The 'local date' function (or literal if you prefer) + */ localDateFunction : LOCAL_DATE (LEFT_PAREN RIGHT_PAREN)? | LOCAL DATE ; +/** + * The 'local time' function (or literal if you prefer) + */ localTimeFunction : LOCAL_TIME (LEFT_PAREN RIGHT_PAREN)? | LOCAL TIME ; +/** + * The 'format()' function for formatting dates and times according to a pattern + */ formatFunction : FORMAT LEFT_PAREN expression AS format RIGHT_PAREN ; +/** + * A format pattern, with a syntax inspired by by java.time.format.DateTimeFormatter + * + * see 'Dialect.appendDatetimeFormat()' + */ format : STRING_LITERAL ; +/** + * The 'extract()' function for extracting fields of dates, times, and datetimes + */ extractFunction : EXTRACT LEFT_PAREN extractField FROM expression RIGHT_PAREN | datetimeField LEFT_PAREN expression RIGHT_PAREN ; +/** + * A field that may be extracted from a date, time, or datetime + */ extractField : datetimeField | dayField @@ -885,6 +1310,9 @@ dateOrTimeField | TIME ; +/** + * The ANSI SQL-style 'position()' function + */ positionFunction : POSITION LEFT_PAREN positionFunctionPatternArgument IN positionFunctionStringArgument RIGHT_PAREN ; @@ -897,16 +1325,24 @@ positionFunctionStringArgument : expression ; +/** + * The 'cube()' function specific to the 'group by' clause + */ cube : CUBE LEFT_PAREN expressionOrPredicate (COMMA expressionOrPredicate)* RIGHT_PAREN ; +/** + * The 'rollup()' function specific to the 'group by' clause + */ rollup : ROLLUP LEFT_PAREN expressionOrPredicate (COMMA expressionOrPredicate)* RIGHT_PAREN ; /** - * The `identifier` is used to provide "keyword as identifier" handling. + * Support for "soft" keywords which may be used as identifiers + * + * The `identifier` rule is used to provide "keyword as identifier" handling. * * The lexer hands us recognized keywords using their specific tokens. This is important * for the recognition of sqm structure, especially in terms of performance! diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java index 6c67c3199d..ac8929275f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java @@ -391,8 +391,8 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } else { identificationVariable = applyJpaCompliance( - visitIdentificationVariableDef( - (HqlParser.IdentificationVariableDefContext) dmlTargetContext.getChild( 1 ) + visitVariable( + (HqlParser.VariableContext) dmlTargetContext.getChild( 1 ) ) ); } @@ -447,8 +447,8 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem processingStateStack.push( stateFieldsProcessingState ); try { - for ( HqlParser.DotIdentifierSequenceContext stateFieldCtx : targetFieldsSpecContext.dotIdentifierSequence() ) { - final SqmPath stateField = (SqmPath) visitDotIdentifierSequence( stateFieldCtx ); + for ( HqlParser.SimplePathContext stateFieldCtx : targetFieldsSpecContext.simplePath() ) { + final SqmPath stateField = (SqmPath) visitSimplePath( stateFieldCtx ); // todo : validate each resolved stateField... insertStatement.addInsertTargetStateField( stateField ); } @@ -486,8 +486,8 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem insertStatement.getValuesList().add( sqmValues ); } - for ( HqlParser.DotIdentifierSequenceContext stateFieldCtx : targetFieldsSpecContext.dotIdentifierSequence() ) { - final SqmPath stateField = (SqmPath) visitDotIdentifierSequence( stateFieldCtx ); + for ( HqlParser.SimplePathContext stateFieldCtx : targetFieldsSpecContext.simplePath() ) { + final SqmPath stateField = (SqmPath) visitSimplePath( stateFieldCtx ); // todo : validate each resolved stateField... insertStatement.addInsertTargetStateField( stateField ); } @@ -529,7 +529,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem if ( subCtx instanceof HqlParser.AssignmentContext ) { final HqlParser.AssignmentContext assignmentContext = (HqlParser.AssignmentContext) subCtx; updateStatement.applyAssignment( - consumeDomainPath( (HqlParser.DotIdentifierSequenceContext) assignmentContext.getChild( 0 ) ), + consumeDomainPath( (HqlParser.SimplePathContext) assignmentContext.getChild( 0 ) ), (SqmExpression) assignmentContext.getChild( 2 ).accept( this ) ); } @@ -890,7 +890,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } else { resultIdentifier = applyJpaCompliance( - visitIdentificationVariableDef( (HqlParser.IdentificationVariableDefContext) ctx.getChild( 1 ) ) + visitVariable( (HqlParser.VariableContext) ctx.getChild( 1 ) ) ); } final SqmSelectableNode selectableNode = visitSelectableNode( ctx ); @@ -946,10 +946,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } @Override - public SqmDynamicInstantiation visitDynamicInstantiation(HqlParser.DynamicInstantiationContext ctx) { + public SqmDynamicInstantiation visitInstantiation(HqlParser.InstantiationContext ctx) { final SqmDynamicInstantiation dynamicInstantiation; - final ParseTree instantiationTarget = ctx.dynamicInstantiationTarget().getChild( 0 ); - if ( instantiationTarget instanceof HqlParser.DotIdentifierSequenceContext ) { + final ParseTree instantiationTarget = ctx.instantiationTarget().getChild( 0 ); + if ( instantiationTarget instanceof HqlParser.SimplePathContext ) { final String className = instantiationTarget.getText(); try { final JavaType jtd = resolveInstantiationTargetJtd( className ); @@ -982,8 +982,8 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } } - for ( HqlParser.DynamicInstantiationArgContext arg : ctx.dynamicInstantiationArgs().dynamicInstantiationArg() ) { - dynamicInstantiation.addArgument( visitDynamicInstantiationArg( arg ) ); + for ( HqlParser.InstantiationArgumentContext arg : ctx.instantiationArguments().instantiationArgument() ) { + dynamicInstantiation.addArgument( visitInstantiationArgument( arg ) ); } return dynamicInstantiation; @@ -1002,10 +1002,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } @Override - public SqmDynamicInstantiationArgument visitDynamicInstantiationArg(HqlParser.DynamicInstantiationArgContext ctx) { + public SqmDynamicInstantiationArgument visitInstantiationArgument(HqlParser.InstantiationArgumentContext ctx) { final String alias; if ( ctx.getChildCount() > 1 ) { - alias = visitIdentificationVariableDef( (HqlParser.IdentificationVariableDefContext) ctx.getChild( ctx.getChildCount() - 1 ) ); + alias = visitVariable( (HqlParser.VariableContext) ctx.getChild( ctx.getChildCount() - 1 ) ); } else { alias = null; @@ -1148,7 +1148,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem int nextIndex = 1; if ( nextIndex < ctx.getChildCount() ) { ParseTree parseTree = ctx.getChild( nextIndex ); - if ( parseTree instanceof HqlParser.OrderingSpecificationContext ) { + if ( parseTree instanceof HqlParser.SortDirectionContext ) { switch ( ( (TerminalNode) parseTree.getChild( 0 ) ).getSymbol().getType() ) { case HqlParser.ASC: sortOrder = SortOrder.ASCENDING; @@ -1386,8 +1386,8 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem fromClause = new SqmFromClause( estimatedSize ); for ( int i = 0; i < size; i++ ) { final ParseTree parseTree = parserFromClause.getChild( i ); - if ( parseTree instanceof HqlParser.FromClauseSpaceContext ) { - fromClause.addRoot( visitFromClauseSpace( (HqlParser.FromClauseSpaceContext) parseTree ) ); + if ( parseTree instanceof HqlParser.EntityWithJoinsContext ) { + fromClause.addRoot( visitEntityWithJoins( (HqlParser.EntityWithJoinsContext) parseTree ) ); } } } @@ -1395,16 +1395,16 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } @Override - public SqmRoot visitFromClauseSpace(HqlParser.FromClauseSpaceContext parserSpace) { - final SqmRoot sqmRoot = visitPathRoot( (HqlParser.PathRootContext) parserSpace.getChild( 0 ) ); + public SqmRoot visitEntityWithJoins(HqlParser.EntityWithJoinsContext parserSpace) { + final SqmRoot sqmRoot = visitRootEntity( (HqlParser.RootEntityContext) parserSpace.getChild( 0 ) ); final int size = parserSpace.getChildCount(); for ( int i = 1; i < size; i++ ) { final ParseTree parseTree = parserSpace.getChild( i ); if ( parseTree instanceof HqlParser.CrossJoinContext ) { consumeCrossJoin( (HqlParser.CrossJoinContext) parseTree, sqmRoot ); } - else if ( parseTree instanceof HqlParser.QualifiedJoinContext ) { - consumeQualifiedJoin( (HqlParser.QualifiedJoinContext) parseTree, sqmRoot ); + else if ( parseTree instanceof HqlParser.JoinContext ) { + consumeJoin( (HqlParser.JoinContext) parseTree, sqmRoot ); } else if ( parseTree instanceof HqlParser.JpaCollectionJoinContext ) { consumeJpaCollectionJoin( (HqlParser.JpaCollectionJoinContext) parseTree, sqmRoot ); @@ -1416,7 +1416,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem @Override @SuppressWarnings( { "rawtypes", "unchecked" } ) - public SqmRoot visitPathRoot(HqlParser.PathRootContext ctx) { + public SqmRoot visitRootEntity(HqlParser.RootEntityContext ctx) { final HqlParser.EntityNameContext entityNameContext = (HqlParser.EntityNameContext) ctx.getChild( 0 ); final List entityNameParseTreeChildren = entityNameContext.children; final String name = getEntityName( entityNameContext ); @@ -1426,15 +1426,15 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem .getJpaMetamodel() .getHqlEntityReference( name ); - final HqlParser.IdentificationVariableDefContext identificationVariableDefContext; + final HqlParser.VariableContext identificationVariableDefContext; if ( ctx.getChildCount() > 1 ) { - identificationVariableDefContext = (HqlParser.IdentificationVariableDefContext) ctx.getChild( 1 ); + identificationVariableDefContext = (HqlParser.VariableContext) ctx.getChild( 1 ); } else { identificationVariableDefContext = null; } final String alias = applyJpaCompliance( - visitIdentificationVariableDef( identificationVariableDefContext ) + visitVariable( identificationVariableDefContext ) ); final SqmCreationProcessingState processingState = processingStateStack.getCurrent(); @@ -1502,7 +1502,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } @Override - public String visitIdentificationVariableDef(HqlParser.IdentificationVariableDefContext ctx) { + public String visitVariable(HqlParser.VariableContext ctx) { if ( ctx == null ) { return null; } @@ -1554,7 +1554,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } private void consumeCrossJoin(HqlParser.CrossJoinContext parserJoin, SqmRoot sqmRoot) { - final HqlParser.PathRootContext pathRootContext = (HqlParser.PathRootContext) parserJoin.getChild( 2 ); + final HqlParser.RootEntityContext pathRootContext = (HqlParser.RootEntityContext) parserJoin.getChild( 2 ); final HqlParser.EntityNameContext entityNameContext = (HqlParser.EntityNameContext) pathRootContext.getChild( 0 ); final String name = getEntityName( entityNameContext ); @@ -1566,16 +1566,16 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem if ( entityDescriptor instanceof SqmPolymorphicRootDescriptor ) { throw new SemanticException( "Unmapped polymorphic reference cannot be used as a CROSS JOIN target" ); } - final HqlParser.IdentificationVariableDefContext identificationVariableDefContext; + final HqlParser.VariableContext identificationVariableDefContext; if ( pathRootContext.getChildCount() > 1 ) { - identificationVariableDefContext = (HqlParser.IdentificationVariableDefContext) pathRootContext.getChild( 1 ); + identificationVariableDefContext = (HqlParser.VariableContext) pathRootContext.getChild( 1 ); } else { identificationVariableDefContext = null; } final SqmCrossJoin join = new SqmCrossJoin<>( entityDescriptor, - visitIdentificationVariableDef( identificationVariableDefContext ), + visitVariable( identificationVariableDefContext ), sqmRoot ); @@ -1586,15 +1586,15 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } @Override - public final SqmQualifiedJoin visitQualifiedJoin(HqlParser.QualifiedJoinContext parserJoin) { - throw new UnsupportedOperationException( "Unexpected call to #visitQualifiedJoin, see #consumeQualifiedJoin" ); + public final SqmJoin visitJoin(HqlParser.JoinContext parserJoin) { + throw new UnsupportedOperationException( "Unexpected call to #visitJoin, see #consumeJoin" ); } @SuppressWarnings("WeakerAccess") - protected void consumeQualifiedJoin(HqlParser.QualifiedJoinContext parserJoin, SqmRoot sqmRoot) { + protected void consumeJoin(HqlParser.JoinContext parserJoin, SqmRoot sqmRoot) { final SqmJoinType joinType; final int firstJoinTypeSymbolType; - if ( parserJoin.getChild( 0 ) instanceof HqlParser.JoinTypeQualifierContext + if ( parserJoin.getChild( 0 ) instanceof HqlParser.JoinTypeContext && parserJoin.getChild( 0 ).getChildCount() != 0 ) { firstJoinTypeSymbolType = ( (TerminalNode) parserJoin.getChild( 0 ).getChild( 0 ) ).getSymbol().getType(); } @@ -1618,15 +1618,15 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem break; } - final HqlParser.QualifiedJoinRhsContext qualifiedJoinRhsContext = parserJoin.qualifiedJoinRhs(); - final HqlParser.IdentificationVariableDefContext identificationVariableDefContext; - if ( qualifiedJoinRhsContext.getChildCount() > 1 ) { - identificationVariableDefContext = (HqlParser.IdentificationVariableDefContext) qualifiedJoinRhsContext.getChild( 1 ); + final HqlParser.JoinPathContext qualifiedJoinPathContext = parserJoin.joinPath(); + final HqlParser.VariableContext identificationVariableDefContext; + if ( qualifiedJoinPathContext.getChildCount() > 1 ) { + identificationVariableDefContext = (HqlParser.VariableContext) qualifiedJoinPathContext.getChild( 1 ); } else { identificationVariableDefContext = null; } - final String alias = visitIdentificationVariableDef( identificationVariableDefContext ); + final String alias = visitVariable( identificationVariableDefContext ); final boolean fetch = parserJoin.getChild( 2 ) instanceof TerminalNode; if ( fetch && processingStateStack.depth() > 1 ) { @@ -1645,9 +1645,9 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem try { //noinspection unchecked - final SqmQualifiedJoin join = (SqmQualifiedJoin) qualifiedJoinRhsContext.getChild( 0 ).accept( this ); + final SqmQualifiedJoin join = (SqmQualifiedJoin) qualifiedJoinPathContext.getChild( 0 ).accept( this ); - final HqlParser.QualifiedJoinPredicateContext qualifiedJoinPredicateContext = parserJoin.qualifiedJoinPredicate(); + final HqlParser.JoinRestrictionContext qualifiedJoinRestrictionContext = parserJoin.joinRestriction(); if ( join instanceof SqmEntityJoin ) { sqmRoot.addSqmJoin( join ); } @@ -1663,15 +1663,15 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } } } - if ( qualifiedJoinPredicateContext != null && attributeJoin.isFetched() ) { + if ( qualifiedJoinRestrictionContext != null && attributeJoin.isFetched() ) { throw new SemanticException( "with-clause not allowed on fetched associations; use filters" ); } } - if ( qualifiedJoinPredicateContext != null ) { + if ( qualifiedJoinRestrictionContext != null ) { dotIdentifierConsumerStack.push( new QualifiedJoinPredicatePathConsumer( join, this ) ); try { - join.setJoinPredicate( (SqmPredicate) qualifiedJoinPredicateContext.getChild( 1 ).accept( this ) ); + join.setJoinPredicate( (SqmPredicate) qualifiedJoinRestrictionContext.getChild( 1 ).accept( this ) ); } finally { dotIdentifierConsumerStack.pop(); @@ -1692,14 +1692,14 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem protected void consumeJpaCollectionJoin( HqlParser.JpaCollectionJoinContext ctx, SqmRoot sqmRoot) { - final HqlParser.IdentificationVariableDefContext identificationVariableDefContext; + final HqlParser.VariableContext identificationVariableDefContext; if ( ctx.getChildCount() > 5 ) { - identificationVariableDefContext = (HqlParser.IdentificationVariableDefContext) ctx.getChild( 5 ); + identificationVariableDefContext = (HqlParser.VariableContext) ctx.getChild( 5 ); } else { identificationVariableDefContext = null; } - final String alias = visitIdentificationVariableDef( identificationVariableDefContext ); + final String alias = visitVariable( identificationVariableDefContext ); dotIdentifierConsumerStack.push( new QualifiedJoinPathConsumer( sqmRoot, @@ -1922,7 +1922,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem if ( ctx instanceof HqlParser.GeneralPathFragmentContext && ctx.getChildCount() == 1 ) { ctx = ctx.getChild( 0 ); - if ( ctx instanceof HqlParser.DotIdentifierSequenceContext ) { + if ( ctx instanceof HqlParser.SimplePathContext ) { return creationContext.getJpaMetamodel().getAllowedEnumLiteralTexts().get( ctx.getText() ); } } @@ -2059,7 +2059,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem return new SqmInSubQueryPredicate<>( testExpression, createCollectionReferenceSubQuery( - (HqlParser.DotIdentifierSequenceContext) collectionReferenceInListContext.getChild( 2 ), + (HqlParser.SimplePathContext) collectionReferenceInListContext.getChild( 2 ), (TerminalNode) collectionReferenceInListContext.getChild( 0 ) ), negated, @@ -2074,7 +2074,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem @Override public SqmPredicate visitExistsCollectionPartPredicate(HqlParser.ExistsCollectionPartPredicateContext ctx) { final SqmSubQuery subQuery = createCollectionReferenceSubQuery( - (HqlParser.DotIdentifierSequenceContext) ctx.getChild( 3 ), + (HqlParser.SimplePathContext) ctx.getChild( 3 ), null ); return new SqmExistsPredicate( subQuery, creationContext.getNodeBuilder() ); @@ -2326,7 +2326,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } @Override - public Object visitCollationExpression(HqlParser.CollationExpressionContext ctx) { + public Object visitCollateFunction(HqlParser.CollateFunctionContext ctx) { if ( creationOptions.useStrictJpaCompliance() ) { throw new StrictJpaComplianceViolation( StrictJpaComplianceViolation.Type.COLLATIONS @@ -3125,7 +3125,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem // Functions @Override - public SqmExpression visitJpaNonStandardFunction(HqlParser.JpaNonStandardFunctionContext ctx) { + public SqmExpression visitJpaNonstandardFunction(HqlParser.JpaNonstandardFunctionContext ctx) { final String functionName = QuotingHelper.unquoteStringLiteral( ctx.getChild( 2 ).getText() ).toLowerCase(); final List> functionArguments; if ( ctx.getChildCount() > 4 ) { @@ -3171,7 +3171,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem final ParseTree argumentChild = ctx.getChild( 2 ); final List> functionArguments; - if ( argumentChild instanceof HqlParser.NonStandardFunctionArgumentsContext ) { + if ( argumentChild instanceof HqlParser.GenericFunctionArgumentsContext ) { functionArguments = (List>) argumentChild.accept( this ); } else if ( "*".equals( argumentChild.getText() ) ) { @@ -3221,7 +3221,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } @Override - public List> visitNonStandardFunctionArguments(HqlParser.NonStandardFunctionArgumentsContext ctx) { + public List> visitGenericFunctionArguments(HqlParser.GenericFunctionArgumentsContext ctx) { final int size = ctx.getChildCount(); final int lastIndex = size - 1; // Shift 1 bit instead of division by 2 @@ -3591,7 +3591,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } return new SqmEvery<>( createCollectionReferenceSubQuery( - (HqlParser.DotIdentifierSequenceContext) ctx.getChild( 3 ), + (HqlParser.SimplePathContext) ctx.getChild( 3 ), (TerminalNode) ctx.getChild( 1 ) ), creationContext.getNodeBuilder() @@ -3627,7 +3627,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } return new SqmAny<>( createCollectionReferenceSubQuery( - (HqlParser.DotIdentifierSequenceContext) ctx.getChild( 3 ), + (HqlParser.SimplePathContext) ctx.getChild( 3 ), (TerminalNode) ctx.getChild( 1 ) ), creationContext.getNodeBuilder() @@ -3636,7 +3636,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } private SqmSubQuery createCollectionReferenceSubQuery( - HqlParser.DotIdentifierSequenceContext pathCtx, + HqlParser.SimplePathContext pathCtx, TerminalNode collectionReferenceCtx) { final SqmPath pluralAttributePath = consumeDomainPath( pathCtx ); final SqmPathSource referencedPathSource = pluralAttributePath.getReferencedPathSource(); @@ -4008,7 +4008,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem @Override public SemanticPathPart visitGeneralPathFragment(HqlParser.GeneralPathFragmentContext ctx) { return visitIndexedPathAccessFragment( - (HqlParser.DotIdentifierSequenceContext) ctx.getChild( 0 ), + (HqlParser.SimplePathContext) ctx.getChild( 0 ), ctx.getChildCount() == 1 ? null : (HqlParser.IndexedPathAccessFragmentContext) ctx.getChild( 1 ) ); } @@ -4028,9 +4028,9 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem else if ( firstChild instanceof HqlParser.MapKeyNavigablePathContext ) { return visitMapKeyNavigablePath( (HqlParser.MapKeyNavigablePathContext) firstChild ); } - else if ( firstChild instanceof HqlParser.DotIdentifierSequenceContext && ctx.getChildCount() == 2 ) { + else if ( firstChild instanceof HqlParser.SimplePathContext && ctx.getChildCount() == 2 ) { return visitIndexedPathAccessFragment( - (HqlParser.DotIdentifierSequenceContext) firstChild, + (HqlParser.SimplePathContext) firstChild, (HqlParser.IndexedPathAccessFragmentContext) ctx.getChild( 1 ) ); } @@ -4039,9 +4039,9 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } private SemanticPathPart visitIndexedPathAccessFragment( - HqlParser.DotIdentifierSequenceContext ctx, + HqlParser.SimplePathContext ctx, HqlParser.IndexedPathAccessFragmentContext idxCtx) { - final SemanticPathPart pathPart = visitDotIdentifierSequence( ctx ); + final SemanticPathPart pathPart = visitSimplePath( ctx ); if ( idxCtx == null ) { return pathPart; @@ -4075,7 +4075,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } @Override - public SemanticPathPart visitDotIdentifierSequence(HqlParser.DotIdentifierSequenceContext ctx) { + public SemanticPathPart visitSimplePath(HqlParser.SimplePathContext ctx) { final int numberOfContinuations = ctx.getChildCount() - 1; final boolean hasContinuations = numberOfContinuations != 0; @@ -4091,7 +4091,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem if ( hasContinuations ) { for ( int i = 1; i < ctx.getChildCount(); i++ ) { - final HqlParser.DotIdentifierSequenceContinuationContext continuation = (HqlParser.DotIdentifierSequenceContinuationContext) ctx.getChild( i ); + final HqlParser.SimplePathElementContext continuation = (HqlParser.SimplePathElementContext) ctx.getChild( i ); final HqlParser.IdentifierContext identifier = (HqlParser.IdentifierContext) continuation.getChild( 1 ); assert identifier.getChildCount() == 1; dotIdentifierConsumer.consumeIdentifier( @@ -4108,7 +4108,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem @Override public SqmPath visitTreatedNavigablePath(HqlParser.TreatedNavigablePathContext ctx) { final DotIdentifierConsumer consumer = dotIdentifierConsumerStack.getCurrent(); - if ( consumer instanceof QualifiedJoinPathConsumer ) { + if ( consumer instanceof QualifiedJoinPathConsumer) { ( (QualifiedJoinPathConsumer) consumer ).setNested( true ); } consumeManagedTypeReference( (HqlParser.PathContext) ctx.getChild( 2 ) ); @@ -4129,7 +4129,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } ); try { - result = consumeDomainPath( (HqlParser.DotIdentifierSequenceContext) ctx.getChild( 6 ).getChild( 1 ) ); + result = consumeDomainPath( (HqlParser.SimplePathContext) ctx.getChild( 6 ).getChild( 1 ) ); } finally { dotIdentifierConsumerStack.pop(); @@ -4165,7 +4165,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem SqmPath result = pluralAttributePath.resolvePathPart( CollectionPart.Nature.ELEMENT.getName(), true, this ); if ( ctx.getChildCount() == 5 ) { - result = consumeDomainPath( (HqlParser.DotIdentifierSequenceContext) ctx.getChild( 4 ).getChild( 1 ) ); + result = consumeDomainPath( (HqlParser.SimplePathContext) ctx.getChild( 4 ).getChild( 1 ) ); } return result; @@ -4194,7 +4194,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem public SqmPath visitMapKeyNavigablePath(HqlParser.MapKeyNavigablePathContext ctx) { final DotIdentifierConsumer consumer = dotIdentifierConsumerStack.getCurrent(); final boolean madeNested; - if ( consumer instanceof QualifiedJoinPathConsumer ) { + if ( consumer instanceof QualifiedJoinPathConsumer) { final QualifiedJoinPathConsumer qualifiedJoinPathConsumer = (QualifiedJoinPathConsumer) consumer; madeNested = !qualifiedJoinPathConsumer.isNested(); if ( madeNested ) { @@ -4210,7 +4210,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem SqmPath result; if ( sqmPath instanceof SqmMapJoin ) { final SqmMapJoin sqmMapJoin = (SqmMapJoin) sqmPath; - if ( consumer instanceof QualifiedJoinPathConsumer ) { + if ( consumer instanceof QualifiedJoinPathConsumer) { if ( madeNested && !hasContinuation ) { // Reset the nested state before consuming the terminal identifier ( (QualifiedJoinPathConsumer) consumer ).setNested( false ); @@ -4233,9 +4233,9 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem // Reset the nested state before consuming the terminal identifier ( (QualifiedJoinPathConsumer) consumer ).setNested( false ); } - final HqlParser.DotIdentifierSequenceContext identCtx = (HqlParser.DotIdentifierSequenceContext) ctx.getChild( 4 ) + final HqlParser.SimplePathContext identCtx = (HqlParser.SimplePathContext) ctx.getChild( 4 ) .getChild( 1 ); - if ( consumer instanceof QualifiedJoinPathConsumer ) { + if ( consumer instanceof QualifiedJoinPathConsumer) { result = consumeDomainPath( identCtx ); } else { @@ -4269,7 +4269,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem } - private SqmPath consumeDomainPath(HqlParser.DotIdentifierSequenceContext sequence) { + private SqmPath consumeDomainPath(HqlParser.SimplePathContext sequence) { final SemanticPathPart consumedPart = (SemanticPathPart) sequence.accept( this ); if ( consumedPart instanceof SqmPath ) { return (SqmPath) consumedPart;