Polishing.

Inline select_query into select_statement, simplify set_function resolution.
Align JPQL and EQL grammars.
Adopt Hibernate version guards in tests.

Original Pull Request: #3695
This commit is contained in:
Mark Paluch
2024-11-27 08:25:32 +01:00
parent 2b562420a6
commit 3effe55929
15 changed files with 723 additions and 436 deletions

View File

@@ -43,7 +43,7 @@ ql_statement
;
select_statement
: select_clause from_clause (where_clause)? (groupby_clause)? (having_clause)? (orderby_clause)? (setOperator select_statement)*
: select_clause from_clause (where_clause)? (groupby_clause)? (having_clause)? (orderby_clause)? (set_fuction)?
;
setOperator
@@ -52,6 +52,10 @@ setOperator
| EXCEPT ALL?
;
set_fuction
: setOperator select_statement
;
update_statement
: update_clause (where_clause)?
;
@@ -675,6 +679,7 @@ constructor_name
literal
: STRINGLITERAL
| JAVASTRINGLITERAL
| INTLITERAL
| FLOATLITERAL
| LONGLITERAL
@@ -848,9 +853,9 @@ reserved_word
|OR
|ORDER
|OUTER
|POWER
|REPLACE
|RIGHT
|POWER
|ROUND
|SELECT
|SET
@@ -1021,6 +1026,7 @@ NOT_EQUAL : '<>' | '!=' ;
CHARACTER : '\'' (~ ('\'' | '\\')) '\'' ;
IDENTIFICATION_VARIABLE : ('a' .. 'z' | 'A' .. 'Z' | '\u0080' .. '\ufffe' | '$' | '_') ('a' .. 'z' | 'A' .. 'Z' | '\u0080' .. '\ufffe' | '0' .. '9' | '$' | '_')* ;
JAVASTRINGLITERAL : '"' ( ('\\' [btnfr"']) | ~('"'))* '"';
STRINGLITERAL : '\'' (~ ('\'' | '\\')|'\\')* '\'' ;
FLOATLITERAL : ('0' .. '9')* '.' ('0' .. '9')+ (E ('0' .. '9')+)* (F|D)?;
INTLITERAL : ('0' .. '9')+ ;

View File

@@ -43,10 +43,6 @@ ql_statement
;
select_statement
: select_query
;
select_query
: select_clause from_clause (where_clause)? (groupby_clause)? (having_clause)? (orderby_clause)? (set_fuction)?
;
@@ -57,11 +53,7 @@ setOperator
;
set_fuction
: setOperator set_function_select
;
set_function_select
: select_query
: setOperator select_statement
;
update_statement
@@ -95,7 +87,7 @@ join
;
fetch_join
: join_spec FETCH join_association_path_expression
: join_spec FETCH join_association_path_expression AS? identification_variable? join_condition?
;
join_spec
@@ -315,7 +307,7 @@ scalar_expression
| datetime_expression
| boolean_expression
| case_expression
| cast_expression
| cast_function
| entity_type_expression
;
@@ -550,8 +542,8 @@ functions_returning_strings
| SUBSTRING '(' string_expression ',' arithmetic_expression (',' arithmetic_expression)? ')'
| TRIM '(' ((trim_specification)? (trim_character)? FROM)? string_expression ')'
| LOWER '(' string_expression ')'
| REPLACE '(' string_expression ',' string_expression ',' string_expression ')'
| UPPER '(' string_expression ')'
| REPLACE '(' string_expression ',' string_expression ',' string_expression ')'
| LEFT '(' string_expression ',' arithmetic_expression ')'
| RIGHT '(' string_expression ',' arithmetic_expression ')'
;
@@ -637,9 +629,6 @@ nullif_expression
: NULLIF '(' scalar_expression ',' scalar_expression ')'
;
cast_expression
: CAST '(' string_expression AS type_literal ')'
;
/*******************
Gaps in the spec.
@@ -653,6 +642,7 @@ trim_character
identification_variable
: IDENTIFICATION_VARIABLE
| f=(COUNT
| AS
| DATE
| FROM
| INNER
@@ -668,6 +658,7 @@ identification_variable
| TIME
| TYPE
| VALUE)
| type_literal
;
constructor_name
@@ -695,6 +686,9 @@ pattern_value
date_time_timestamp_literal
: STRINGLITERAL
| DATELITERAL
| TIMELITERAL
| TIMESTAMPLITERAL
;
entity_type_literal
@@ -995,10 +989,10 @@ ON : O N;
OR : O R;
ORDER : O R D E R;
OUTER : O U T E R;
REPLACE : R E P L A C E;
RIGHT : R I G H T;
POWER : P O W E R;
REGEXP : R E G E X P;
REPLACE : R E P L A C E;
RIGHT : R I G H T;
ROUND : R O U N D;
SELECT : S E L E C T;
SET : S E T;
@@ -1033,4 +1027,7 @@ STRINGLITERAL : '\'' (~ ('\'' | '\\')|'\\')* '\'' ;
JAVASTRINGLITERAL : '"' ( ('\\' [btnfr"']) | ~('"'))* '"';
FLOATLITERAL : ('0' .. '9')* '.' ('0' .. '9')+ (E ('0' .. '9')+)* (F|D)?;
INTLITERAL : ('0' .. '9')+ ;
LONGLITERAL : ('0' .. '9')+L ;
LONGLITERAL : ('0' .. '9')+ L;
DATELITERAL : '{' D STRINGLITERAL '}';
TIMELITERAL : '{' T STRINGLITERAL '}';
TIMESTAMPLITERAL : '{' T S STRINGLITERAL '}';

View File

@@ -42,7 +42,7 @@ class EqlCountQueryTransformer extends EqlQueryRenderer {
}
@Override
public QueryRendererBuilder visitSelect_statement(EqlParser.Select_statementContext ctx) {
public QueryTokenStream visitSelect_statement(EqlParser.Select_statementContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
@@ -92,7 +92,7 @@ class EqlCountQueryTransformer extends EqlQueryRenderer {
return builder;
}
private QueryRendererBuilder getDistinctCountSelection(QueryTokenStream selectionListbuilder) {
private QueryTokenStream getDistinctCountSelection(QueryTokenStream selectionListbuilder) {
QueryRendererBuilder nested = new QueryRendererBuilder();
CountSelectionTokenStream countSelection = CountSelectionTokenStream.create(selectionListbuilder);

View File

@@ -79,30 +79,8 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
builder.appendExpression(visit(ctx.orderby_clause()));
}
for (int i = 0; i < ctx.setOperator().size(); i++) {
builder.appendExpression(visit(ctx.setOperator(i)));
builder.appendExpression(visit(ctx.select_statement(i)));
}
return builder;
}
@Override
public QueryTokenStream visitSetOperator(EqlParser.SetOperatorContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.UNION() != null) {
builder.append(QueryTokens.expression(ctx.UNION()));
} else if (ctx.INTERSECT() != null) {
builder.append(QueryTokens.expression(ctx.INTERSECT()));
} else if (ctx.EXCEPT() != null) {
builder.append(QueryTokens.expression(ctx.EXCEPT()));
}
if (ctx.ALL() != null) {
builder.append(QueryTokens.expression(ctx.ALL()));
if (ctx.set_fuction() != null) {
builder.appendExpression(visit(ctx.set_fuction()));
}
return builder;
@@ -228,9 +206,11 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
if (ctx.AS() != null) {
builder.append(QueryTokens.expression(ctx.AS()));
}
if (ctx.identification_variable() != null) {
builder.appendExpression(visit(ctx.identification_variable()));
}
if (ctx.join_condition() != null) {
builder.appendExpression(visit(ctx.join_condition()));
}
@@ -293,8 +273,7 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
}
@Override
public QueryTokenStream visitJoin_association_path_expression(
EqlParser.Join_association_path_expressionContext ctx) {
public QueryTokenStream visitJoin_association_path_expression(EqlParser.Join_association_path_expressionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
@@ -306,31 +285,25 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
builder.appendExpression(visit(ctx.join_single_valued_path_expression()));
}
} else {
QueryRendererBuilder nested = QueryRenderer.builder();
if (ctx.join_collection_valued_path_expression() != null) {
QueryRendererBuilder nested = QueryRenderer.builder();
nested.append(QueryTokens.token(ctx.TREAT()));
nested.append(TOKEN_OPEN_PAREN);
nested.appendInline(visit(ctx.join_collection_valued_path_expression()));
nested.appendExpression(visit(ctx.join_collection_valued_path_expression()));
nested.append(QueryTokens.expression(ctx.AS()));
nested.appendInline(visit(ctx.subtype()));
nested.append(TOKEN_CLOSE_PAREN);
nested.appendExpression(visit(ctx.subtype()));
builder.appendExpression(nested);
} else if (ctx.join_single_valued_path_expression() != null) {
QueryRendererBuilder nested = QueryRenderer.builder();
nested.append(QueryTokens.token(ctx.TREAT()));
nested.append(TOKEN_OPEN_PAREN);
nested.appendInline(visit(ctx.join_single_valued_path_expression()));
nested.appendExpression(visit(ctx.join_single_valued_path_expression()));
nested.append(QueryTokens.expression(ctx.AS()));
nested.appendInline(visit(ctx.subtype()));
nested.append(TOKEN_CLOSE_PAREN);
builder.appendExpression(nested);
nested.appendExpression(visit(ctx.subtype()));
}
builder.append(QueryTokens.token(ctx.TREAT()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
}
return builder;
@@ -452,8 +425,7 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
}
@Override
public QueryTokenStream visitGeneral_identification_variable(
EqlParser.General_identification_variableContext ctx) {
public QueryTokenStream visitGeneral_identification_variable(EqlParser.General_identification_variableContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
@@ -496,12 +468,15 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
public QueryTokenStream visitTreated_subpath(EqlParser.Treated_subpathContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
QueryRendererBuilder nested = QueryRenderer.builder();
nested.appendExpression(visit(ctx.general_subpath()));
nested.append(QueryTokens.expression(ctx.AS()));
nested.appendExpression(visit(ctx.subtype()));
builder.append(QueryTokens.token(ctx.TREAT()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.general_subpath()));
builder.append(QueryTokens.expression(ctx.AS()));
builder.appendInline(visit(ctx.subtype()));
builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
return builder;
@@ -854,15 +829,15 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.state_field_path_expression() != null) {
builder.append(visit(ctx.state_field_path_expression()));
builder.appendExpression(visit(ctx.state_field_path_expression()));
} else if (ctx.general_identification_variable() != null) {
builder.append(visit(ctx.general_identification_variable()));
builder.appendExpression(visit(ctx.general_identification_variable()));
} else if (ctx.result_variable() != null) {
builder.append(visit(ctx.result_variable()));
builder.appendExpression(visit(ctx.result_variable()));
} else if (ctx.string_expression() != null) {
builder.append(visit(ctx.string_expression()));
builder.appendExpression(visit(ctx.string_expression()));
} else if (ctx.scalar_expression() != null) {
builder.append(visit(ctx.scalar_expression()));
builder.appendExpression(visit(ctx.scalar_expression()));
}
if (ctx.ASC() != null) {
@@ -884,12 +859,44 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(TOKEN_NULLS);
builder.append(QueryTokens.expression(ctx.NULLS()));
if (ctx.FIRST() != null) {
builder.append(TOKEN_FIRST);
builder.append(QueryTokens.expression(ctx.FIRST()));
} else if (ctx.LAST() != null) {
builder.append(TOKEN_LAST);
builder.append(QueryTokens.expression(ctx.LAST()));
}
return builder;
}
@Override
public QueryTokenStream visitSet_fuction(EqlParser.Set_fuctionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.setOperator() != null) {
builder.append(visit(ctx.setOperator()));
}
builder.appendExpression(visit(ctx.select_statement()));
return builder;
}
@Override
public QueryTokenStream visitSetOperator(EqlParser.SetOperatorContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.INTERSECT() != null) {
builder.append(QueryTokens.expression(ctx.INTERSECT()));
} else if (ctx.UNION() != null) {
builder.append(QueryTokens.expression(ctx.UNION()));
} else if (ctx.EXCEPT() != null) {
builder.append(QueryTokens.expression(ctx.EXCEPT()));
} else if (ctx.ALL() != null) {
builder.append(QueryTokens.expression(ctx.ALL()));
}
return builder;
@@ -994,83 +1001,82 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
@Override
public QueryTokenStream visitScalar_expression(EqlParser.Scalar_expressionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.arithmetic_expression() != null) {
builder.append(visit(ctx.arithmetic_expression()));
return visit(ctx.arithmetic_expression());
} else if (ctx.string_expression() != null) {
builder.append(visit(ctx.string_expression()));
return visit(ctx.string_expression());
} else if (ctx.enum_expression() != null) {
builder.append(visit(ctx.enum_expression()));
return visit(ctx.enum_expression());
} else if (ctx.datetime_expression() != null) {
builder.append(visit(ctx.datetime_expression()));
return visit(ctx.datetime_expression());
} else if (ctx.boolean_expression() != null) {
builder.append(visit(ctx.boolean_expression()));
return visit(ctx.boolean_expression());
} else if (ctx.case_expression() != null) {
builder.append(visit(ctx.case_expression()));
return visit(ctx.case_expression());
} else if (ctx.entity_type_expression() != null) {
builder.append(visit(ctx.entity_type_expression()));
return visit(ctx.entity_type_expression());
} else if (ctx.cast_function() != null) {
return (visit(ctx.cast_function()));
}
return builder;
return QueryTokenStream.empty();
}
@Override
public QueryTokenStream visitConditional_expression(EqlParser.Conditional_expressionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.conditional_expression() != null) {
builder.append(visit(ctx.conditional_expression()));
builder.append(QueryTokens.expression(ctx.OR()));
builder.append(visit(ctx.conditional_term()));
} else {
builder.append(visit(ctx.conditional_term()));
}
QueryRendererBuilder builder = QueryRenderer.builder();
return builder;
builder.appendExpression(visit(ctx.conditional_expression()));
builder.append(QueryTokens.expression(ctx.OR()));
builder.appendExpression(visit(ctx.conditional_term()));
return builder;
} else {
return visit(ctx.conditional_term());
}
}
@Override
public QueryTokenStream visitConditional_term(EqlParser.Conditional_termContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.conditional_term() != null) {
builder.append(visit(ctx.conditional_term()));
builder.append(QueryTokens.expression(ctx.AND()));
builder.append(visit(ctx.conditional_factor()));
} else {
builder.append(visit(ctx.conditional_factor()));
}
QueryRendererBuilder builder = QueryRenderer.builder();
return builder;
builder.appendExpression(visit(ctx.conditional_term()));
builder.append(QueryTokens.expression(ctx.AND()));
builder.appendExpression(visit(ctx.conditional_factor()));
return builder;
} else {
return visit(ctx.conditional_factor());
}
}
@Override
public QueryTokenStream visitConditional_factor(EqlParser.Conditional_factorContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.NOT() != null) {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(QueryTokens.expression(ctx.NOT()));
builder.appendExpression(visit(ctx.conditional_primary()));
return builder;
}
builder.append(visit(ctx.conditional_primary()));
return builder;
return visit(ctx.conditional_primary());
}
@Override
public QueryTokenStream visitConditional_primary(EqlParser.Conditional_primaryContext ctx) {
if (ctx.simple_cond_expression() != null) {
return visit(ctx.simple_cond_expression());
}
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.simple_cond_expression() != null) {
builder.append(visit(ctx.simple_cond_expression()));
} else if (ctx.conditional_expression() != null) {
if (ctx.conditional_expression() != null) {
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.conditional_expression()));
@@ -1083,27 +1089,25 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
@Override
public QueryTokenStream visitSimple_cond_expression(EqlParser.Simple_cond_expressionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.comparison_expression() != null) {
builder.append(visit(ctx.comparison_expression()));
return visit(ctx.comparison_expression());
} else if (ctx.between_expression() != null) {
builder.append(visit(ctx.between_expression()));
return visit(ctx.between_expression());
} else if (ctx.in_expression() != null) {
builder.append(visit(ctx.in_expression()));
return visit(ctx.in_expression());
} else if (ctx.like_expression() != null) {
builder.append(visit(ctx.like_expression()));
return visit(ctx.like_expression());
} else if (ctx.null_comparison_expression() != null) {
builder.append(visit(ctx.null_comparison_expression()));
return visit(ctx.null_comparison_expression());
} else if (ctx.empty_collection_comparison_expression() != null) {
builder.append(visit(ctx.empty_collection_comparison_expression()));
return visit(ctx.empty_collection_comparison_expression());
} else if (ctx.collection_member_expression() != null) {
builder.append(visit(ctx.collection_member_expression()));
return visit(ctx.collection_member_expression());
} else if (ctx.exists_expression() != null) {
builder.append(visit(ctx.exists_expression()));
return visit(ctx.exists_expression());
}
return builder;
return QueryTokenStream.empty();
}
@Override
@@ -1113,7 +1117,7 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
if (ctx.arithmetic_expression(0) != null) {
builder.append(visit(ctx.arithmetic_expression(0)));
builder.appendExpression(visit(ctx.arithmetic_expression(0)));
if (ctx.NOT() != null) {
builder.append(QueryTokens.expression(ctx.NOT()));
@@ -1139,7 +1143,7 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
} else if (ctx.datetime_expression(0) != null) {
builder.append(visit(ctx.datetime_expression(0)));
builder.appendExpression(visit(ctx.datetime_expression(0)));
if (ctx.NOT() != null) {
builder.append(QueryTokens.expression(ctx.NOT()));
@@ -1160,10 +1164,10 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.string_expression() != null) {
builder.append(visit(ctx.string_expression()));
builder.appendExpression(visit(ctx.string_expression()));
}
if (ctx.type_discriminator() != null) {
builder.append(visit(ctx.type_discriminator()));
builder.appendExpression(visit(ctx.type_discriminator()));
}
if (ctx.NOT() != null) {
builder.append(QueryTokens.expression(ctx.NOT()));
@@ -1176,7 +1180,6 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(QueryTokenStream.concat(ctx.in_item(), this::visit, TOKEN_COMMA));
builder.append(TOKEN_CLOSE_PAREN);
} else if (ctx.subquery() != null) {
@@ -1217,7 +1220,8 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(visit(ctx.string_expression()));
builder.appendExpression(visit(ctx.string_expression()));
if (ctx.NOT() != null) {
builder.append(QueryTokens.expression(ctx.NOT()));
}
@@ -1239,11 +1243,11 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.single_valued_path_expression() != null) {
builder.append(visit(ctx.single_valued_path_expression()));
builder.appendExpression(visit(ctx.single_valued_path_expression()));
} else if (ctx.input_parameter() != null) {
builder.append(visit(ctx.input_parameter()));
builder.appendExpression(visit(ctx.input_parameter()));
} else if (ctx.nullif_expression() != null) {
builder.append(visit(ctx.nullif_expression()));
builder.appendExpression(visit(ctx.nullif_expression()));
}
if (ctx.op != null) {
@@ -1265,7 +1269,7 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(visit(ctx.collection_valued_path_expression()));
builder.appendExpression(visit(ctx.collection_valued_path_expression()));
builder.append(QueryTokens.expression(ctx.IS()));
if (ctx.NOT() != null) {
builder.append(QueryTokens.expression(ctx.NOT()));
@@ -1280,7 +1284,7 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(visit(ctx.entity_or_value_expression()));
builder.appendExpression(visit(ctx.entity_or_value_expression()));
if (ctx.NOT() != null) {
builder.append(QueryTokens.expression(ctx.NOT()));
}
@@ -1296,25 +1300,21 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
@Override
public QueryTokenStream visitEntity_or_value_expression(EqlParser.Entity_or_value_expressionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.single_valued_object_path_expression() != null) {
builder.append(visit(ctx.single_valued_object_path_expression()));
return visit(ctx.single_valued_object_path_expression());
} else if (ctx.state_field_path_expression() != null) {
builder.append(visit(ctx.state_field_path_expression()));
return visit(ctx.state_field_path_expression());
} else if (ctx.simple_entity_or_value_expression() != null) {
builder.append(visit(ctx.simple_entity_or_value_expression()));
return visit(ctx.simple_entity_or_value_expression());
}
return builder;
return QueryTokenStream.empty();
}
@Override
public QueryTokenStream visitSimple_entity_or_value_expression(
EqlParser.Simple_entity_or_value_expressionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.identification_variable() != null) {
return visit(ctx.identification_variable());
} else if (ctx.input_parameter() != null) {
@@ -1368,13 +1368,13 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.appendInline(visit(ctx.string_expression(0)));
builder.append(visit(ctx.comparison_operator()));
builder.appendExpression(visit(ctx.string_expression(0)));
builder.appendExpression(visit(ctx.comparison_operator()));
if (ctx.string_expression(1) != null) {
builder.append(visit(ctx.string_expression(1)));
builder.appendExpression(visit(ctx.string_expression(1)));
} else {
builder.append(visit(ctx.all_or_any_expression()));
builder.appendExpression(visit(ctx.all_or_any_expression()));
}
return builder;
@@ -1389,9 +1389,9 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
builder.append(QueryTokens.ventilated(ctx.op));
if (ctx.boolean_expression(1) != null) {
builder.append(visit(ctx.boolean_expression(1)));
builder.appendExpression(visit(ctx.boolean_expression(1)));
} else {
builder.append(visit(ctx.all_or_any_expression()));
builder.appendExpression(visit(ctx.all_or_any_expression()));
}
return builder;
@@ -1411,9 +1411,9 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
builder.append(QueryTokens.ventilated(ctx.op));
if (ctx.enum_expression(1) != null) {
builder.append(visit(ctx.enum_expression(1)));
builder.appendExpression(visit(ctx.enum_expression(1)));
} else {
builder.append(visit(ctx.all_or_any_expression()));
builder.appendExpression(visit(ctx.all_or_any_expression()));
}
return builder;
@@ -1428,9 +1428,9 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
builder.append(QueryTokens.ventilated(ctx.comparison_operator().op));
if (ctx.datetime_expression(1) != null) {
builder.append(visit(ctx.datetime_expression(1)));
builder.appendExpression(visit(ctx.datetime_expression(1)));
} else {
builder.append(visit(ctx.all_or_any_expression()));
builder.appendExpression(visit(ctx.all_or_any_expression()));
}
return builder;
@@ -1445,9 +1445,9 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
builder.append(QueryTokens.expression(ctx.op));
if (ctx.entity_expression(1) != null) {
builder.append(visit(ctx.entity_expression(1)));
builder.appendExpression(visit(ctx.entity_expression(1)));
} else {
builder.append(visit(ctx.all_or_any_expression()));
builder.appendExpression(visit(ctx.all_or_any_expression()));
}
return builder;
@@ -1458,13 +1458,13 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(visit(ctx.arithmetic_expression(0)));
builder.append(visit(ctx.comparison_operator()));
builder.appendExpression(visit(ctx.arithmetic_expression(0)));
builder.appendExpression(visit(ctx.comparison_operator()));
if (ctx.arithmetic_expression(1) != null) {
builder.append(visit(ctx.arithmetic_expression(1)));
builder.appendExpression(visit(ctx.arithmetic_expression(1)));
} else {
builder.append(visit(ctx.all_or_any_expression()));
builder.appendExpression(visit(ctx.all_or_any_expression()));
}
return builder;
@@ -1477,7 +1477,7 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
builder.appendInline(visit(ctx.entity_type_expression(0)));
builder.append(QueryTokens.ventilated(ctx.op));
builder.append(visit(ctx.entity_type_expression(1)));
builder.appendExpression(visit(ctx.entity_type_expression(1)));
return builder;
}
@@ -1496,42 +1496,37 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
@Override
public QueryTokenStream visitComparison_operator(EqlParser.Comparison_operatorContext ctx) {
return QueryRendererBuilder.from(QueryTokens.ventilated(ctx.op));
return QueryRenderer.from(QueryTokens.token(ctx.op));
}
@Override
public QueryTokenStream visitArithmetic_expression(EqlParser.Arithmetic_expressionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.arithmetic_expression() != null) {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(visit(ctx.arithmetic_expression()));
builder.append(QueryTokens.expression(ctx.op));
builder.append(QueryTokens.ventilated(ctx.op));
builder.append(visit(ctx.arithmetic_term()));
return builder;
} else {
builder.append(visit(ctx.arithmetic_term()));
return visit(ctx.arithmetic_term());
}
return builder;
}
@Override
public QueryTokenStream visitArithmetic_term(EqlParser.Arithmetic_termContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.arithmetic_term() != null) {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.appendInline(visit(ctx.arithmetic_term()));
builder.append(QueryTokens.ventilated(ctx.op));
builder.append(visit(ctx.arithmetic_factor()));
return builder;
} else {
builder.append(visit(ctx.arithmetic_factor()));
return visit(ctx.arithmetic_factor());
}
return builder;
}
@Override
@@ -1542,7 +1537,8 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
if (ctx.op != null) {
builder.append(QueryTokens.token(ctx.op));
}
builder.appendInline(visit(ctx.arithmetic_primary()));
builder.append(visit(ctx.arithmetic_primary()));
return builder;
}
@@ -1705,45 +1701,39 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
@Override
public QueryTokenStream visitEntity_expression(EqlParser.Entity_expressionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.single_valued_object_path_expression() != null) {
builder.append(visit(ctx.single_valued_object_path_expression()));
return visit(ctx.single_valued_object_path_expression());
} else if (ctx.simple_entity_expression() != null) {
builder.append(visit(ctx.simple_entity_expression()));
return visit(ctx.simple_entity_expression());
}
return builder;
return QueryTokenStream.empty();
}
@Override
public QueryTokenStream visitSimple_entity_expression(EqlParser.Simple_entity_expressionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.identification_variable() != null) {
builder.append(visit(ctx.identification_variable()));
return visit(ctx.identification_variable());
} else if (ctx.input_parameter() != null) {
builder.append(visit(ctx.input_parameter()));
return visit(ctx.input_parameter());
}
return builder;
return QueryTokenStream.empty();
}
@Override
public QueryTokenStream visitEntity_type_expression(EqlParser.Entity_type_expressionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.type_discriminator() != null) {
builder.append(visit(ctx.type_discriminator()));
return visit(ctx.type_discriminator());
} else if (ctx.entity_type_literal() != null) {
builder.append(visit(ctx.entity_type_literal()));
return visit(ctx.entity_type_literal());
} else if (ctx.input_parameter() != null) {
builder.append(visit(ctx.input_parameter()));
return visit(ctx.input_parameter());
}
return builder;
return QueryTokenStream.empty();
}
@Override
@@ -1918,7 +1908,7 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
builder.append(QueryTokens.token(ctx.SUBSTRING()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.string_expression(0)));
builder.append(visit(ctx.string_expression(0)));
builder.append(TOKEN_COMMA);
builder.appendInline(QueryTokenStream.concat(ctx.arithmetic_expression(), this::visit, TOKEN_COMMA));
builder.append(TOKEN_CLOSE_PAREN);
@@ -1935,7 +1925,7 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
if (ctx.FROM() != null) {
builder.append(QueryTokens.expression(ctx.FROM()));
}
builder.appendInline(visit(ctx.string_expression(0)));
builder.append(visit(ctx.string_expression(0)));
builder.append(TOKEN_CLOSE_PAREN);
} else if (ctx.LOWER() != null) {
@@ -1947,10 +1937,9 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
builder.append(QueryTokens.token(ctx.UPPER()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.string_expression(0)));
builder.append(visit(ctx.string_expression(0)));
builder.append(TOKEN_CLOSE_PAREN);
} else if (ctx.LEFT() != null) {
builder.append(QueryTokens.token(ctx.LEFT()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.string_expression(0)));
@@ -1958,7 +1947,6 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
builder.appendInline(visit(ctx.arithmetic_expression(0)));
builder.append(TOKEN_CLOSE_PAREN);
} else if (ctx.RIGHT() != null) {
builder.append(QueryTokens.token(ctx.RIGHT()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.string_expression(0)));
@@ -1966,7 +1954,6 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
builder.appendInline(visit(ctx.arithmetic_expression(0)));
builder.append(TOKEN_CLOSE_PAREN);
} else if (ctx.REPLACE() != null) {
builder.append(QueryTokens.token(ctx.REPLACE()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.string_expression(0)));
@@ -1984,11 +1971,11 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
public QueryTokenStream visitTrim_specification(EqlParser.Trim_specificationContext ctx) {
if (ctx.LEADING() != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.LEADING()));
return QueryRenderer.from(QueryTokens.expression(ctx.LEADING()));
} else if (ctx.TRAILING() != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.TRAILING()));
return QueryRenderer.from(QueryTokens.expression(ctx.TRAILING()));
} else {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.BOTH()));
return QueryRenderer.from(QueryTokens.expression(ctx.BOTH()));
}
}
@@ -2076,12 +2063,15 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
public QueryTokenStream visitExtract_datetime_field(EqlParser.Extract_datetime_fieldContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
QueryRendererBuilder nested = QueryRenderer.builder();
nested.appendExpression(visit(ctx.datetime_field()));
nested.append(QueryTokens.expression(ctx.FROM()));
nested.appendExpression(visit(ctx.datetime_expression()));
builder.append(QueryTokens.token(ctx.EXTRACT()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendExpression(visit(ctx.datetime_field()));
builder.append(QueryTokens.expression(ctx.FROM()));
builder.appendInline(visit(ctx.datetime_expression()));
builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
return builder;
@@ -2096,12 +2086,15 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
public QueryTokenStream visitExtract_datetime_part(EqlParser.Extract_datetime_partContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
QueryRendererBuilder nested = QueryRenderer.builder();
nested.appendExpression(visit(ctx.datetime_part()));
nested.append(QueryTokens.expression(ctx.FROM()));
nested.appendExpression(visit(ctx.datetime_expression()));
builder.append(QueryTokens.token(ctx.EXTRACT()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendExpression(visit(ctx.datetime_part()));
builder.append(QueryTokens.expression(ctx.FROM()));
builder.appendInline(visit(ctx.datetime_expression()));
builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
return builder;
@@ -2154,10 +2147,7 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(QueryTokens.expression(ctx.CASE()));
ctx.when_clause().forEach(whenClauseContext -> {
builder.appendExpression(visit(whenClauseContext));
});
builder.appendExpression(QueryTokenStream.concat(ctx.when_clause(), this::visit, TOKEN_SPACE));
builder.append(QueryTokens.expression(ctx.ELSE()));
builder.appendExpression(visit(ctx.scalar_expression()));
@@ -2172,9 +2162,9 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(QueryTokens.expression(ctx.WHEN()));
builder.append(visit(ctx.conditional_expression()));
builder.appendExpression(visit(ctx.conditional_expression()));
builder.append(QueryTokens.expression(ctx.THEN()));
builder.append(visit(ctx.scalar_expression()));
builder.appendExpression(visit(ctx.scalar_expression()));
return builder;
}
@@ -2185,14 +2175,11 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(QueryTokens.expression(ctx.CASE()));
builder.append(visit(ctx.case_operand()));
ctx.simple_when_clause().forEach(simpleWhenClauseContext -> {
builder.append(visit(simpleWhenClauseContext));
});
builder.appendExpression(visit(ctx.case_operand()));
builder.appendExpression(QueryTokenStream.concat(ctx.simple_when_clause(), this::visit, TOKEN_SPACE));
builder.append(QueryTokens.expression(ctx.ELSE()));
builder.append(visit(ctx.scalar_expression()));
builder.appendExpression(visit(ctx.scalar_expression()));
builder.append(QueryTokens.expression(ctx.END()));
return builder;
@@ -2253,11 +2240,11 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
public QueryTokenStream visitTrim_character(EqlParser.Trim_characterContext ctx) {
if (ctx.CHARACTER() != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.CHARACTER()));
return QueryRenderer.from(QueryTokens.expression(ctx.CHARACTER()));
} else if (ctx.character_valued_input_parameter() != null) {
return visit(ctx.character_valued_input_parameter());
} else {
return QueryRenderer.builder();
return QueryTokenStream.empty();
}
}
@@ -2265,14 +2252,14 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
public QueryTokenStream visitIdentification_variable(EqlParser.Identification_variableContext ctx) {
if (ctx.IDENTIFICATION_VARIABLE() != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.IDENTIFICATION_VARIABLE()));
} else if (ctx.f != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.f));
return QueryRenderer.from(QueryTokens.token(ctx.IDENTIFICATION_VARIABLE()));
} else if (ctx.type_literal() != null) {
return visit(ctx.type_literal());
} else if (ctx.f != null) {
return QueryRenderer.from(QueryTokens.token(ctx.f));
} else {
return QueryTokenStream.empty();
}
return QueryRenderer.builder();
}
@Override
@@ -2283,23 +2270,23 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
@Override
public QueryTokenStream visitLiteral(EqlParser.LiteralContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.STRINGLITERAL() != null) {
builder.append(QueryTokens.expression(ctx.STRINGLITERAL()));
return QueryRenderer.from(QueryTokens.expression(ctx.STRINGLITERAL()));
} else if (ctx.JAVASTRINGLITERAL() != null) {
return QueryRenderer.from(QueryTokens.expression(ctx.JAVASTRINGLITERAL()));
} else if (ctx.INTLITERAL() != null) {
builder.append(QueryTokens.expression(ctx.INTLITERAL()));
return QueryRenderer.from(QueryTokens.expression(ctx.INTLITERAL()));
} else if (ctx.FLOATLITERAL() != null) {
builder.append(QueryTokens.expression(ctx.FLOATLITERAL()));
return QueryRenderer.from(QueryTokens.expression(ctx.FLOATLITERAL()));
} else if (ctx.LONGLITERAL() != null) {
builder.append(QueryTokens.expression(ctx.LONGLITERAL()));
return QueryRenderer.from(QueryTokens.expression(ctx.LONGLITERAL()));
} else if (ctx.boolean_literal() != null) {
builder.append(visit(ctx.boolean_literal()));
return visit(ctx.boolean_literal());
} else if (ctx.entity_type_literal() != null) {
builder.append(visit(ctx.entity_type_literal()));
return visit(ctx.entity_type_literal());
}
return builder;
return QueryTokenStream.empty();
}
@Override
@@ -2355,7 +2342,7 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
public QueryTokenStream visitEscape_character(EqlParser.Escape_characterContext ctx) {
if (ctx.CHARACTER() != null) {
return QueryRendererBuilder.from(QueryTokens.token(ctx.CHARACTER()));
return QueryRenderer.from(QueryTokens.expression(ctx.CHARACTER()));
} else if (ctx.character_valued_input_parameter() != null) {
return visit(ctx.character_valued_input_parameter());
} else if (ctx.string_literal() != null) {
@@ -2369,13 +2356,13 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
public QueryTokenStream visitNumeric_literal(EqlParser.Numeric_literalContext ctx) {
if (ctx.INTLITERAL() != null) {
return QueryRendererBuilder.from(QueryTokens.token(ctx.INTLITERAL()));
return QueryRenderer.from(QueryTokens.token(ctx.INTLITERAL()));
} else if (ctx.FLOATLITERAL() != null) {
return QueryRendererBuilder.from(QueryTokens.token(ctx.FLOATLITERAL()));
return QueryRenderer.from(QueryTokens.token(ctx.FLOATLITERAL()));
} else if (ctx.LONGLITERAL() != null) {
return QueryRendererBuilder.from(QueryTokens.token(ctx.LONGLITERAL()));
return QueryRenderer.from(QueryTokens.token(ctx.LONGLITERAL()));
} else {
return QueryRenderer.builder();
return QueryTokenStream.empty();
}
}
@@ -2383,11 +2370,11 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
public QueryTokenStream visitBoolean_literal(EqlParser.Boolean_literalContext ctx) {
if (ctx.TRUE() != null) {
return QueryRendererBuilder.from(QueryTokens.token(ctx.TRUE()));
return QueryRenderer.from(QueryTokens.expression(ctx.TRUE()));
} else if (ctx.FALSE() != null) {
return QueryRendererBuilder.from(QueryTokens.token(ctx.FALSE()));
return QueryRenderer.from(QueryTokens.expression(ctx.FALSE()));
} else {
return QueryRenderer.builder();
return QueryTokenStream.empty();
}
}
@@ -2400,11 +2387,11 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
public QueryTokenStream visitString_literal(EqlParser.String_literalContext ctx) {
if (ctx.CHARACTER() != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.CHARACTER()));
return QueryRenderer.from(QueryTokens.expression(ctx.CHARACTER()));
} else if (ctx.STRINGLITERAL() != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.STRINGLITERAL()));
return QueryRenderer.from(QueryTokens.expression(ctx.STRINGLITERAL()));
} else {
return QueryRenderer.builder();
return QueryTokenStream.empty();
}
}
@@ -2461,7 +2448,7 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
@Override
public QueryTokenStream visitEntity_name(EqlParser.Entity_nameContext ctx) {
return QueryTokenStream.concat(ctx.reserved_word(), this::visit, QueryRenderer::inline, TOKEN_DOT);
return QueryTokenStream.concat(ctx.reserved_word(), this::visit, TOKEN_DOT);
}
@Override
@@ -2492,26 +2479,25 @@ class EqlQueryRenderer extends EqlBaseVisitor<QueryTokenStream> {
}
@Override
public QueryTokenStream visitCharacter_valued_input_parameter(
EqlParser.Character_valued_input_parameterContext ctx) {
public QueryTokenStream visitCharacter_valued_input_parameter(EqlParser.Character_valued_input_parameterContext ctx) {
if (ctx.CHARACTER() != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.CHARACTER()));
return QueryRenderer.from(QueryTokens.expression(ctx.CHARACTER()));
} else if (ctx.input_parameter() != null) {
return visit(ctx.input_parameter());
} else {
return QueryRenderer.builder();
return QueryTokenStream.empty();
}
}
@Override
public QueryTokenStream visitReserved_word(EqlParser.Reserved_wordContext ctx) {
if (ctx.IDENTIFICATION_VARIABLE() != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.IDENTIFICATION_VARIABLE()));
return QueryRenderer.from(QueryTokens.token(ctx.IDENTIFICATION_VARIABLE()));
} else if (ctx.f != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.f));
return QueryRenderer.from(QueryTokens.token(ctx.f));
} else {
return QueryRenderer.builder();
return QueryTokenStream.empty();
}
}
}

View File

@@ -24,7 +24,6 @@ import org.springframework.data.jpa.repository.query.QueryRenderer.QueryRenderer
import org.springframework.data.repository.query.ReturnedType;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* An ANTLR {@link org.antlr.v4.runtime.tree.ParseTreeVisitor} that transforms a parsed EQL query by applying
@@ -54,7 +53,7 @@ class EqlSortedQueryTransformer extends EqlQueryRenderer {
}
@Override
public QueryRendererBuilder visitSelect_statement(EqlParser.Select_statementContext ctx) {
public QueryTokenStream visitSelect_statement(EqlParser.Select_statementContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
@@ -73,12 +72,10 @@ class EqlSortedQueryTransformer extends EqlQueryRenderer {
builder.appendExpression(visit(ctx.having_clause()));
}
doVisitOrderBy(builder, ctx, ObjectUtils.isEmpty(ctx.setOperator()) ? this.sort : Sort.unsorted());
for (int i = 0; i < ctx.setOperator().size(); i++) {
builder.appendExpression(visit(ctx.setOperator(i)));
builder.appendExpression(visit(ctx.select_statement(i)));
if (ctx.set_fuction() != null) {
builder.appendExpression(visit(ctx.set_fuction()));
} else {
doVisitOrderBy(builder, ctx);
}
return builder;
@@ -104,7 +101,7 @@ class EqlSortedQueryTransformer extends EqlQueryRenderer {
return builder.append(dtoDelegate.transformSelectionList(tokenStream));
}
private void doVisitOrderBy(QueryRendererBuilder builder, EqlParser.Select_statementContext ctx, Sort sort) {
private void doVisitOrderBy(QueryRendererBuilder builder, EqlParser.Select_statementContext ctx) {
if (ctx.orderby_clause() != null) {
QueryTokenStream existingOrder = visit(ctx.orderby_clause());

View File

@@ -44,16 +44,6 @@ class JpqlCountQueryTransformer extends JpqlQueryRenderer {
@Override
public QueryTokenStream visitSelect_statement(JpqlParser.Select_statementContext ctx) {
if(ctx.select_query() != null) {
return visitSelect_query(ctx.select_query());
}
return QueryTokenStream.empty();
}
@Override
public QueryTokenStream visitSelect_query(JpqlParser.Select_queryContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.appendExpression(visit(ctx.select_clause()));
@@ -68,7 +58,7 @@ class JpqlCountQueryTransformer extends JpqlQueryRenderer {
if (ctx.having_clause() != null) {
builder.appendExpression(visit(ctx.having_clause()));
}
if(ctx.set_fuction() != null) {
if (ctx.set_fuction() != null) {
builder.appendExpression(visit(ctx.set_fuction()));
}

View File

@@ -15,28 +15,14 @@
*/
package org.springframework.data.jpa.repository.query;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_CLOSE_PAREN;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_COLON;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_COMMA;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_DOT;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_EQUALS;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_OPEN_PAREN;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_QUESTION_MARK;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_DOUBLE_PIPE;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_SPACE;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_CLOSE_PAREN;
import static org.springframework.data.jpa.repository.query.QueryTokens.TOKEN_OPEN_PAREN;
import static org.springframework.data.jpa.repository.query.QueryTokens.*;
import java.util.ArrayList;
import java.util.List;
import org.antlr.v4.runtime.tree.ParseTree;
import org.springframework.data.jpa.repository.query.JpqlParser.Except_clauseContext;
import org.springframework.data.jpa.repository.query.JpqlParser.Intersect_clauseContext;
import org.springframework.data.jpa.repository.query.JpqlParser.Relation_fuctions_selectContext;
import org.springframework.data.jpa.repository.query.JpqlParser.NullsPrecedenceContext;
import org.springframework.data.jpa.repository.query.JpqlParser.Cast_expressionContext;
import org.springframework.data.jpa.repository.query.JpqlParser.Reserved_wordContext;
import org.springframework.data.jpa.repository.query.JpqlParser.Set_fuctionContext;
import org.springframework.data.jpa.repository.query.JpqlParser.Type_literalContext;
@@ -73,17 +59,8 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
}
}
@Override
public QueryTokenStream visitSelect_statement(JpqlParser.Select_statementContext ctx) {
if(ctx.select_query() != null) {
return visitSelect_query(ctx.select_query());
}
return QueryTokenStream.empty();
}
public QueryTokenStream visitSelect_query(JpqlParser.Select_queryContext ctx) {
@Override
public QueryTokenStream visitSelect_statement(JpqlParser.Select_statementContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
@@ -106,32 +83,13 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
builder.appendExpression(visit(ctx.orderby_clause()));
}
if(ctx.set_fuction() != null) {
builder.appendExpression(visit(ctx.set_fuction()));
if (ctx.set_fuction() != null) {
builder.appendExpression(visit(ctx.set_fuction()));
}
return builder;
}
@Override
public List<JpaQueryParsingToken> visitSetOperator_with_select_statement(
JpqlParser.SetOperator_with_select_statementContext ctx) {
List<JpaQueryParsingToken> tokens = new ArrayList<>();
if (ctx.INTERSECT() != null) {
tokens.add(new JpaQueryParsingToken(ctx.INTERSECT()));
} else if (ctx.UNION() != null) {
tokens.add(new JpaQueryParsingToken(ctx.UNION()));
} else if (ctx.EXCEPT() != null) {
tokens.add(new JpaQueryParsingToken(ctx.EXCEPT()));
}
tokens.addAll(visit(ctx.select_statement()));
return builder;
}
@Override
public QueryTokenStream visitUpdate_statement(JpqlParser.Update_statementContext ctx) {
@@ -230,14 +188,19 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(visit(ctx.join_spec()));
builder.append(visit(ctx.join_association_path_expression()));
builder.appendExpression(visit(ctx.join_spec()));
builder.appendExpression(visit(ctx.join_association_path_expression()));
if (ctx.AS() != null) {
builder.append(QueryTokens.expression(ctx.AS()));
}
builder.append(visit(ctx.identification_variable()));
if (ctx.identification_variable() != null) {
builder.appendExpression(visit(ctx.identification_variable()));
}
if (ctx.join_condition() != null) {
builder.append(visit(ctx.join_condition()));
builder.appendExpression(visit(ctx.join_condition()));
}
return builder;
@@ -248,9 +211,19 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(visit(ctx.join_spec()));
builder.appendExpression(visit(ctx.join_spec()));
builder.append(QueryTokens.expression(ctx.FETCH()));
builder.append(visit(ctx.join_association_path_expression()));
builder.appendExpression(visit(ctx.join_association_path_expression()));
if (ctx.AS() != null) {
builder.append(QueryTokens.expression(ctx.AS()));
}
if (ctx.identification_variable() != null) {
builder.appendExpression(visit(ctx.identification_variable()));
}
if (ctx.join_condition() != null) {
builder.appendExpression(visit(ctx.join_condition()));
}
return builder;
}
@@ -301,23 +274,25 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
builder.appendExpression(visit(ctx.join_single_valued_path_expression()));
}
} else {
QueryRendererBuilder nested = QueryRenderer.builder();
if (ctx.join_collection_valued_path_expression() != null) {
builder.append(QueryTokens.token(ctx.TREAT()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.join_collection_valued_path_expression()));
builder.append(QueryTokens.expression(ctx.AS()));
builder.appendInline(visit(ctx.subtype()));
builder.append(TOKEN_CLOSE_PAREN);
nested.appendExpression(visit(ctx.join_collection_valued_path_expression()));
nested.append(QueryTokens.expression(ctx.AS()));
nested.appendExpression(visit(ctx.subtype()));
} else if (ctx.join_single_valued_path_expression() != null) {
builder.append(QueryTokens.token(ctx.TREAT()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.join_single_valued_path_expression()));
builder.append(QueryTokens.expression(ctx.AS()));
builder.appendInline(visit(ctx.subtype()));
builder.append(TOKEN_CLOSE_PAREN);
nested.appendExpression(visit(ctx.join_single_valued_path_expression()));
nested.append(QueryTokens.expression(ctx.AS()));
nested.appendExpression(visit(ctx.subtype()));
}
builder.append(QueryTokens.token(ctx.TREAT()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
}
return builder;
@@ -477,12 +452,15 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
public QueryTokenStream visitTreated_subpath(JpqlParser.Treated_subpathContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
QueryRendererBuilder nested = QueryRenderer.builder();
nested.appendExpression(visit(ctx.general_subpath()));
nested.append(QueryTokens.expression(ctx.AS()));
nested.appendExpression(visit(ctx.subtype()));
builder.append(QueryTokens.token(ctx.TREAT()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.general_subpath()));
builder.append(QueryTokens.expression(ctx.AS()));
builder.appendInline(visit(ctx.subtype()));
builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
return builder;
@@ -826,19 +804,6 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
return builder;
}
@Override
public QueryTokenStream visitSet_fuction(Set_fuctionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(QueryTokens.expression(ctx.setOperator().getStart()));
if(ctx.setOperator().ALL() != null) {
builder.append(QueryTokens.expression(ctx.setOperator().ALL()));
}
builder.appendExpression(visit(ctx.set_function_select().select_query()));
return builder;
}
@Override
public QueryTokenStream visitOrderby_item(JpqlParser.Orderby_itemContext ctx) {
@@ -854,33 +819,13 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
if (ctx.ASC() != null) {
builder.append(QueryTokens.expression(ctx.ASC()));
}
if (ctx.DESC() != null) {
} else if (ctx.DESC() != null) {
builder.append(QueryTokens.expression(ctx.DESC()));
}
if (ctx.nullsPrecedence() != null) {
builder.append(visit(ctx.nullsPrecedence()));
}
if (ctx.nullsPrecedence() != null) {
tokens.addAll(visit(ctx.nullsPrecedence()));
}
return tokens;
}
@Override
public List<JpaQueryParsingToken> visitNullsPrecedence(JpqlParser.NullsPrecedenceContext ctx) {
List<JpaQueryParsingToken> tokens = new ArrayList<>();
tokens.add(new JpaQueryParsingToken(ctx.NULLS()));
if (ctx.FIRST() != null) {
tokens.add(new JpaQueryParsingToken(ctx.FIRST()));
} else if (ctx.LAST() != null) {
tokens.add(new JpaQueryParsingToken(ctx.LAST()));
}
return builder;
}
@@ -890,12 +835,44 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(TOKEN_NULLS);
builder.append(QueryTokens.expression(ctx.NULLS()));
if (ctx.FIRST() != null) {
builder.append(TOKEN_FIRST);
builder.append(QueryTokens.expression(ctx.FIRST()));
} else if (ctx.LAST() != null) {
builder.append(TOKEN_LAST);
builder.append(QueryTokens.expression(ctx.LAST()));
}
return builder;
}
@Override
public QueryTokenStream visitSet_fuction(Set_fuctionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.setOperator() != null) {
builder.append(visit(ctx.setOperator()));
}
builder.appendExpression(visit(ctx.select_statement()));
return builder;
}
@Override
public QueryTokenStream visitSetOperator(JpqlParser.SetOperatorContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
if (ctx.INTERSECT() != null) {
builder.append(QueryTokens.expression(ctx.INTERSECT()));
} else if (ctx.UNION() != null) {
builder.append(QueryTokens.expression(ctx.UNION()));
} else if (ctx.EXCEPT() != null) {
builder.append(QueryTokens.expression(ctx.EXCEPT()));
} else if (ctx.ALL() != null) {
builder.append(QueryTokens.expression(ctx.ALL()));
}
return builder;
@@ -1013,8 +990,8 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
return visit(ctx.case_expression());
} else if (ctx.entity_type_expression() != null) {
return visit(ctx.entity_type_expression());
} else if (ctx.cast_expression() != null) {
return (visit(ctx.cast_expression()));
} else if (ctx.cast_function() != null) {
return (visit(ctx.cast_function()));
}
return QueryTokenStream.empty();
@@ -1248,9 +1225,11 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
}
builder.append(QueryTokens.expression(ctx.IS()));
if (ctx.NOT() != null) {
builder.append(QueryTokens.expression(ctx.NOT()));
}
builder.append(QueryTokens.expression(ctx.NULL()));
return builder;
@@ -1601,11 +1580,6 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
builder.append(visit(ctx.type_cast_function()));
} else if (ctx.function_invocation() != null) {
builder.append(visit(ctx.function_invocation()));
} else if (ctx.op != null) {
tokens.addAll(visit(ctx.string_expression(0)));
tokens.add(new JpaQueryParsingToken(ctx.op));
tokens.addAll(visit(ctx.string_expression(1)));
} else if (ctx.subquery() != null) {
builder.append(TOKEN_OPEN_PAREN);
@@ -1859,6 +1833,8 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.identification_variable()));
builder.append(TOKEN_CLOSE_PAREN);
} else if (ctx.extract_datetime_field() != null) {
builder.append(visit(ctx.extract_datetime_field()));
}
return builder;
@@ -1886,6 +1862,8 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
} else if (ctx.DATETIME() != null) {
builder.append(QueryTokens.expression(ctx.DATETIME()));
}
} else if (ctx.extract_datetime_part() != null) {
builder.append(visit(ctx.extract_datetime_part()));
}
return builder;
@@ -1907,6 +1885,7 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
builder.append(QueryTokens.token(ctx.SUBSTRING()));
builder.append(TOKEN_OPEN_PAREN);
builder.append(visit(ctx.string_expression(0)));
builder.append(TOKEN_COMMA);
builder.appendInline(QueryTokenStream.concat(ctx.arithmetic_expression(), this::visit, TOKEN_COMMA));
builder.append(TOKEN_CLOSE_PAREN);
} else if (ctx.TRIM() != null) {
@@ -2053,12 +2032,15 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
public QueryTokenStream visitExtract_datetime_field(JpqlParser.Extract_datetime_fieldContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
QueryRendererBuilder nested = QueryRenderer.builder();
builder.append(QueryTokens.expression(ctx.EXTRACT()));
nested.appendExpression(visit(ctx.datetime_field()));
nested.append(QueryTokens.expression(ctx.FROM()));
nested.appendExpression(visit(ctx.datetime_expression()));
builder.append(QueryTokens.token(ctx.EXTRACT()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendExpression(visit(ctx.datetime_field()));
builder.append(QueryTokens.expression(ctx.FROM()));
builder.appendInline(visit(ctx.datetime_expression()));
builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
return builder;
@@ -2073,12 +2055,15 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
public QueryTokenStream visitExtract_datetime_part(JpqlParser.Extract_datetime_partContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
QueryRendererBuilder nested = QueryRenderer.builder();
builder.append(QueryTokens.expression(ctx.EXTRACT()));
nested.appendExpression(visit(ctx.datetime_part()));
nested.append(QueryTokens.expression(ctx.FROM()));
nested.appendExpression(visit(ctx.datetime_expression()));
builder.append(QueryTokens.token(ctx.EXTRACT()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendExpression(visit(ctx.datetime_part()));
builder.append(QueryTokens.expression(ctx.FROM()));
builder.append(visit(ctx.datetime_expression()));
builder.appendInline(nested);
builder.append(TOKEN_CLOSE_PAREN);
return builder;
@@ -2117,18 +2102,6 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
}
}
@Override
public QueryRendererBuilder visitCast_expression(Cast_expressionContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(QueryTokens.token(ctx.CAST()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.string_expression()));
builder.append(QueryTokens.expression(ctx.AS()));
builder.appendInline(visit(ctx.type_literal()));
builder.append(TOKEN_CLOSE_PAREN);
return builder;
}
@Override
public QueryRendererBuilder visitType_literal(Type_literalContext ctx) {
@@ -2222,7 +2195,7 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.append(QueryTokens.expression(ctx.NULLIF()));
builder.append(QueryTokens.token(ctx.NULLIF()));
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.scalar_expression(0)));
builder.append(TOKEN_COMMA);
@@ -2248,7 +2221,9 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
public QueryTokenStream visitIdentification_variable(JpqlParser.Identification_variableContext ctx) {
if (ctx.IDENTIFICATION_VARIABLE() != null) {
return QueryRenderer.from(QueryTokens.expression(ctx.IDENTIFICATION_VARIABLE()));
return QueryRenderer.from(QueryTokens.token(ctx.IDENTIFICATION_VARIABLE()));
} else if (ctx.type_literal() != null) {
return visit(ctx.type_literal());
} else if (ctx.f != null) {
return QueryRenderer.from(QueryTokens.token(ctx.f));
} else {
@@ -2308,7 +2283,18 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
@Override
public QueryTokenStream visitDate_time_timestamp_literal(JpqlParser.Date_time_timestamp_literalContext ctx) {
return QueryRenderer.from(QueryTokens.expression(ctx.STRINGLITERAL()));
if (ctx.STRINGLITERAL() != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.STRINGLITERAL()));
} else if (ctx.DATELITERAL() != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.DATELITERAL()));
} else if (ctx.TIMELITERAL() != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.TIMELITERAL()));
} else if (ctx.TIMESTAMPLITERAL() != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.TIMESTAMPLITERAL()));
} else {
return QueryRenderer.builder();
}
}
@Override
@@ -2421,7 +2407,7 @@ class JpqlQueryRenderer extends JpqlBaseVisitor<QueryTokenStream> {
@Override
public QueryTokenStream visitEntity_name(JpqlParser.Entity_nameContext ctx) {
return QueryTokenStream.concat(ctx.reserved_word(), this::visitReserved_word, TOKEN_DOT);
return QueryTokenStream.concat(ctx.reserved_word(), this::visit, TOKEN_DOT);
}
@Override

View File

@@ -54,16 +54,6 @@ class JpqlSortedQueryTransformer extends JpqlQueryRenderer {
@Override
public QueryTokenStream visitSelect_statement(JpqlParser.Select_statementContext ctx) {
if(ctx.select_query() != null) {
return visitSelect_query(ctx.select_query());
}
return QueryTokenStream.empty();
}
@Override
public QueryTokenStream visitSelect_query(JpqlParser.Select_queryContext ctx) {
QueryRendererBuilder builder = QueryRenderer.builder();
builder.appendExpression(visit(ctx.select_clause()));
@@ -110,7 +100,7 @@ class JpqlSortedQueryTransformer extends JpqlQueryRenderer {
return builder.append(dtoDelegate.transformSelectionList(tokenStream));
}
private void doVisitOrderBy(QueryRendererBuilder builder, JpqlParser.Select_queryContext ctx) {
private void doVisitOrderBy(QueryRendererBuilder builder, JpqlParser.Select_statementContext ctx) {
if (ctx.orderby_clause() != null) {
QueryTokenStream existingOrder = visit(ctx.orderby_clause());
@@ -160,4 +150,5 @@ class JpqlSortedQueryTransformer extends JpqlQueryRenderer {
return tokens;
}
}

View File

@@ -106,7 +106,8 @@ class PostgresStoredProcedureIntegrationTests {
new Employee(4, "Gabriel"));
}
@DisabledOnHibernate("6")
@DisabledOnHibernate(value = "7",
disabledReason = "class org.hibernate.metamodel.model.domain.internal.EntityTypeImpl cannot be cast to class org.hibernate.query.OutputableType (org.hibernate.metamodel.model.domain.internal.EntityTypeImpl and org.hibernate.query.OutputableType are in unnamed module of loader 'app')")
@Test // 2256
void testSingleEntityFromResultSet() {

View File

@@ -98,6 +98,7 @@ class EqlComplianceTests {
assertQuery("SELECT e FROM Employee e JOIN FETCH e.address");
assertQuery("SELECT e FROM Employee e JOIN FETCH e.address a ORDER BY a.city");
assertQuery("SELECT e FROM Employee e JOIN FETCH e.address AS a ORDER BY a.city");
}
@Test
@@ -118,6 +119,16 @@ class EqlComplianceTests {
"SELECT e, c.city FROM Employee e, (SELECT DISTINCT a.city FROM Address a) c WHERE e.address.city = c.city");
}
@Test // GH-3277
void numericLiterals() {
assertQuery("SELECT e FROM Employee e WHERE e.id = 1234");
assertQuery("SELECT e FROM Employee e WHERE e.id = 1234L");
assertQuery("SELECT s FROM Stat s WHERE s.ratio > 3.14");
assertQuery("SELECT s FROM Stat s WHERE s.ratio > 3.14F");
assertQuery("SELECT s FROM Stat s WHERE s.ratio > 3.14e32D");
}
@Test
void orderByClause() {
@@ -442,7 +453,7 @@ class EqlComplianceTests {
@ParameterizedTest // GH-3136
@ValueSource(strings = { "STRING", "INTEGER", "FLOAT", "DOUBLE" })
void jpqlCast(String targetType) {
void cast(String targetType) {
assertQuery("SELECT CAST(e.salary AS %s) FROM Employee e".formatted(targetType));
}
@@ -462,4 +473,5 @@ class EqlComplianceTests {
void stringConcatWithPipes() {
assertQuery("SELECT e.firstname || e.lastname AS name FROM Employee e");
}
}

View File

@@ -1041,6 +1041,59 @@ class EqlQueryRendererTests {
assertQuery("select e.power.id from MyEntity e");
}
@Test // GH-3136
void doublePipeShouldBeValidAsAStringConcatOperator() {
assertQuery("""
select e.name || ' ' || e.title
from Employee e
""");
}
@Test // GH-3136
void combinedSelectStatementsShouldWork() {
assertQuery("""
select e from Employee e where e.last_name = 'Baggins'
intersect
select e from Employee e where e.first_name = 'Samwise'
union
select e from Employee e where e.home = 'The Shire'
except
select e from Employee e where e.home = 'Isengard'
""");
}
@Disabled
@Test // GH-3136
void additionalStringOperationsShouldWork() {
assertQuery("""
select
replace(e.name, 'Baggins', 'Proudfeet'),
left(e.role, 4),
right(e.home, 5),
cast(e.distance_from_home, int)
from Employee e
""");
}
@Test // GH-3136
void orderByWithNullsFirstOrLastShouldWork() {
assertQuery("""
select a
from Element a
order by mutationAm desc nulls first
""");
assertQuery("""
select a
from Element a
order by mutationAm desc nulls last
""");
}
@ParameterizedTest // GH-3342
@ValueSource(strings = { "select 1 from User u", "select -1 from User u", "select +1 from User u",
"select +1 * -100 from User u", "select count(u) * -0.7f from User u",
@@ -1089,4 +1142,5 @@ class EqlQueryRendererTests {
assertQuery("select f from FooEntity f where upper(f.name) IN :names");
assertQuery("select f from FooEntity f where f.size IN :sizes");
}
}

View File

@@ -275,7 +275,7 @@ class EqlSpecificationTests {
assertQuery("""
SELECT b.name, b.ISBN
FROM Order o JOIN TREAT(o.product AS Book) b
""");
""");
}
@Test
@@ -284,7 +284,7 @@ class EqlSpecificationTests {
assertQuery("""
SELECT e FROM Employee e JOIN TREAT(e.projects AS LargeProject) lp
WHERE lp.budget > 1000
""");
""");
}
/**
@@ -299,7 +299,7 @@ class EqlSpecificationTests {
WHERE TREAT(p AS LargeProject).budget > 1000
OR TREAT(p AS SmallProject).name LIKE 'Persist%'
OR p.description LIKE "cost overrun"
""");
""");
}
@Test
@@ -310,7 +310,7 @@ class EqlSpecificationTests {
WHERE TREAT(p AS LargeProject).budget > 1000
OR TREAT(p AS SmallProject).name LIKE 'Persist%'
OR p.description LIKE 'cost overrun'
""");
""");
}
@Test
@@ -320,7 +320,39 @@ class EqlSpecificationTests {
SELECT e FROM Employee e
WHERE TREAT(e AS Exempt).vacationDays > 10
OR TREAT(e AS Contractor).hours > 100
""");
""");
}
@Test // GH-3136
void substring() {
assertQuery("select substring(c.number, 1, 2) " + //
"from Call c");
assertQuery("select substring(c.number, 1) " + //
"from Call c");
}
@Test // GH-3136
void currentDateFunctions() {
assertQuery("select CURRENT_DATE " + //
"from Call c ");
assertQuery("select CURRENT_TIME " + //
"from Call c ");
assertQuery("select CURRENT_TIMESTAMP " + //
"from Call c ");
assertQuery("select LOCAL_DATE " + //
"from Call c ");
assertQuery("select LOCAL_TIME " + //
"from Call c ");
assertQuery("select LOCAL_DATETIME " + //
"from Call c ");
}
@Test
@@ -384,7 +416,7 @@ class EqlSpecificationTests {
WHERE emp.salary > ALL (SELECT m.salary
FROM Manager m
WHERE m.department = emp.department)
""");
""");
}
@Test
@@ -396,7 +428,7 @@ class EqlSpecificationTests {
WHERE EXISTS (SELECT spouseEmp
FROM Employee spouseEmp
WHERE spouseEmp = emp.spouse)
""");
""");
}
@Test
@@ -464,7 +496,7 @@ class EqlSpecificationTests {
WHEN e.rating = 2 THEN e.salary * 1.05
ELSE e.salary * 1.01
END
""");
""");
}
@Test
@@ -477,7 +509,7 @@ class EqlSpecificationTests {
WHEN 2 THEN e.salary * 1.05
ELSE e.salary * 1.01
END
""");
""");
}
@Test
@@ -517,7 +549,7 @@ class EqlSpecificationTests {
SELECT e
FROM Employee e
WHERE TYPE(e) IN (Exempt, Contractor)
""");
""");
}
@Test

View File

@@ -1669,7 +1669,7 @@ class HqlQueryRendererTests {
from Element a
where a.erstelltDurch = :variable
order by mutationAm desc nulls last
""");
""");
}
@Test // GH-3882
@@ -1690,7 +1690,7 @@ class HqlQueryRendererTests {
void roundFunctionShouldWorkLikeAnyOtherFunction() {
assertQuery("""
select round(count(ri)*100/max(ri.receipt.positions), 0) as perc
select round(count(ri) * 100 / max(ri.receipt.positions), 0) as perc
from StockOrderItem oi
right join StockReceiptItem ri
on ri.article = oi.article

View File

@@ -27,6 +27,7 @@ import org.junit.jupiter.params.provider.ValueSource;
* suffix.
*
* @author Christoph Strobl
* @author Mark Paluch
*/
class JpqlComplianceTests {
@@ -50,6 +51,52 @@ class JpqlComplianceTests {
.trim();
}
@Test
void selectQueries() {
assertQuery("Select e FROM Employee e WHERE e.salary > 100000");
assertQuery("Select e FROM Employee e WHERE e.id = :id");
assertQuery("Select MAX(e.salary) FROM Employee e");
assertQuery("Select e.firstName FROM Employee e");
assertQuery("Select e.firstName, e.lastName FROM Employee e");
}
@Test
void selectClause() {
assertQuery("SELECT COUNT(e) FROM Employee e");
assertQuery("SELECT MAX(e.salary) FROM Employee e");
assertQuery("SELECT NEW com.acme.reports.EmpReport(e.firstName, e.lastName, e.salary) FROM Employee e");
}
@Test
void fromClause() {
assertQuery("SELECT e FROM Employee e");
assertQuery("SELECT e, a FROM Employee e, MailingAddress a WHERE e.address = a.address");
assertQuery("SELECT e FROM com.acme.Employee e");
}
@Test
void join() {
assertQuery("SELECT e FROM Employee e JOIN e.address a WHERE a.city = :city");
assertQuery("SELECT e FROM Employee e JOIN e.projects p JOIN e.projects p2 WHERE p.name = :p1 AND p2.name = :p2");
}
@Test
void joinFetch() {
assertQuery("SELECT e FROM Employee e JOIN FETCH e.address");
assertQuery("SELECT e FROM Employee e JOIN FETCH e.address a ORDER BY a.city");
assertQuery("SELECT e FROM Employee e JOIN FETCH e.address AS a ORDER BY a.city");
}
@Test
void leftJoin() {
assertQuery("SELECT e FROM Employee e LEFT JOIN e.address a ORDER BY a.city");
}
@Test // GH-3277
void numericLiterals() {
@@ -65,6 +112,27 @@ class JpqlComplianceTests {
assertQuery("select new com.example.demo.SampleObject(se.id, se.sampleValue, \"java\") from SampleEntity se");
}
@Test
void orderByClause() {
assertQuery("SELECT e FROM Employee e ORDER BY e.lastName ASC, e.firstName ASC"); // Typo in EQL document
assertQuery("SELECT e FROM Employee e LEFT JOIN e.manager m ORDER BY m.lastName NULLS FIRST");
assertQuery("SELECT e FROM Employee e ORDER BY e.address");
}
@Test
void groupByClause() {
assertQuery("SELECT AVG(e.salary), e.address.city FROM Employee e GROUP BY e.address.city");
assertQuery("SELECT e, COUNT(p) FROM Employee e LEFT JOIN e.projects p GROUP BY e");
}
@Test
void havingClause() {
assertQuery(
"SELECT AVG(e.salary), e.address.city FROM Employee e GROUP BY e.address.city HAVING AVG(e.salary) > 100000");
}
@Test // GH-3136
void union() {
@@ -72,6 +140,141 @@ class JpqlComplianceTests {
SELECT MAX(e.salary) FROM Employee e WHERE e.address.city = :city1
UNION SELECT MAX(e.salary) FROM Employee e WHERE e.address.city = :city2
""");
assertQuery("""
SELECT e FROM Employee e JOIN e.phones p WHERE p.areaCode = :areaCode1
INTERSECT SELECT e FROM Employee e JOIN e.phones p WHERE p.areaCode = :areaCode2
""");
assertQuery("""
SELECT e FROM Employee e
EXCEPT SELECT e FROM Employee e WHERE e.salary > e.manager.salary
""");
}
@Test
void whereClause() {
// TBD
}
@Test
void updateQueries() {
assertQuery("UPDATE Employee e SET e.salary = 60000 WHERE e.salary = 50000");
}
@Test
void deleteQueries() {
assertQuery("DELETE FROM Employee e WHERE e.department IS NULL");
}
@Test
void literals() {
assertQuery("SELECT e FROM Employee e WHERE e.name = 'Bob'");
assertQuery("SELECT e FROM Employee e WHERE e.id = 1234");
assertQuery("SELECT e FROM Employee e WHERE e.id = 1234L");
assertQuery("SELECT s FROM Stat s WHERE s.ratio > 3.14F");
assertQuery("SELECT s FROM Stat s WHERE s.ratio > 3.14e32D");
assertQuery("SELECT e FROM Employee e WHERE e.active = TRUE");
assertQuery("SELECT e FROM Employee e WHERE e.startDate = {d'2012-01-03'}");
assertQuery("SELECT e FROM Employee e WHERE e.startTime = {t'09:00:00'}");
assertQuery("SELECT e FROM Employee e WHERE e.version = {ts'2012-01-03 09:00:00.000000001'}");
assertQuery("SELECT e FROM Employee e WHERE e.gender = org.acme.Gender.MALE");
assertQuery("UPDATE Employee e SET e.manager = NULL WHERE e.manager = :manager");
}
@Test
void functionsInSelect() {
assertQuery("SELECT e.salary - 1000 FROM Employee e");
assertQuery("SELECT e.salary + 1000 FROM Employee e");
assertQuery("SELECT e.salary * 2 FROM Employee e");
assertQuery("SELECT e.salary * 2.0 FROM Employee e");
assertQuery("SELECT e.salary / 2 FROM Employee e");
assertQuery("SELECT e.salary / 2.0 FROM Employee e");
assertQuery("SELECT ABS(e.salary - e.manager.salary) FROM Employee e");
assertQuery(
"select e from Employee e where case e.firstName when 'Bob' then 'Robert' when 'Jill' then 'Gillian' else '' end = 'Robert'");
assertQuery(
"select case when e.firstName = 'Bob' then 'Robert' when e.firstName = 'Jill' then 'Gillian' else '' end from Employee e where e.firstName = 'Bob' or e.firstName = 'Jill'");
assertQuery(
"select e from Employee e where case when e.firstName = 'Bob' then 'Robert' when e.firstName = 'Jill' then 'Gillian' else '' end = 'Robert'");
assertQuery("SELECT COALESCE(e.salary, 0) FROM Employee e");
assertQuery("SELECT CONCAT(e.firstName, ' ', e.lastName) FROM Employee e");
assertQuery("SELECT e.name, CURRENT_DATE FROM Employee e");
assertQuery("SELECT e.name, CURRENT_TIME FROM Employee e");
assertQuery("SELECT e.name, CURRENT_TIMESTAMP FROM Employee e");
assertQuery("SELECT LENGTH(e.lastName) FROM Employee e");
assertQuery("SELECT LOWER(e.lastName) FROM Employee e");
assertQuery("SELECT MOD(e.hoursWorked, 8) FROM Employee e");
assertQuery("SELECT NULLIF(e.salary, 0) FROM Employee e");
assertQuery("SELECT SQRT(o.RESULT) FROM Output o");
assertQuery("SELECT SUBSTRING(e.lastName, 0, 2) FROM Employee e");
assertQuery(
"SELECT TRIM(TRAILING FROM e.lastName), TRIM(e.lastName), TRIM(LEADING '-' FROM e.lastName) FROM Employee e");
assertQuery("SELECT UPPER(e.lastName) FROM Employee e");
assertQuery("SELECT CAST(e.salary NUMERIC(10, 2)) FROM Employee e");
assertQuery("SELECT EXTRACT(YEAR FROM e.startDate) FROM Employee e");
}
@Test
void functionsInWhere() {
assertQuery("SELECT e FROM Employee e WHERE e.salary - 1000 > 0");
assertQuery("SELECT e FROM Employee e WHERE e.salary + 1000 > 0");
assertQuery("SELECT e FROM Employee e WHERE e.salary * 2 > 0");
assertQuery("SELECT e FROM Employee e WHERE e.salary * 2.0 > 0.0");
assertQuery("SELECT e FROM Employee e WHERE e.salary / 2 > 0");
assertQuery("SELECT e FROM Employee e WHERE e.salary / 2.0 > 0.0");
assertQuery("SELECT e FROM Employee e WHERE ABS(e.salary - e.manager.salary) > 0");
assertQuery("SELECT e FROM Employee e WHERE COALESCE(e.salary, 0) > 0");
assertQuery("SELECT e FROM Employee e WHERE CONCAT(e.firstName, ' ', e.lastName) = 'Bilbo'");
assertQuery("SELECT e FROM Employee e WHERE CURRENT_DATE > CURRENT_TIME");
assertQuery("SELECT e FROM Employee e WHERE CURRENT_TIME > CURRENT_TIMESTAMP");
assertQuery("SELECT e FROM Employee e WHERE LENGTH(e.lastName) > 0");
assertQuery("SELECT e FROM Employee e WHERE LOWER(e.lastName) = 'bilbo'");
assertQuery("SELECT e FROM Employee e WHERE MOD(e.hoursWorked, 8) > 0");
assertQuery("SELECT e FROM Employee e WHERE SQRT(o.RESULT) > 0.0");
assertQuery("SELECT e FROM Employee e WHERE SUBSTRING(e.lastName, 0, 2) = 'Bilbo'");
assertQuery("SELECT e FROM Employee e WHERE TRIM(TRAILING FROM e.lastName) = 'Bilbo'");
assertQuery("SELECT e FROM Employee e WHERE TRIM(e.lastName) = 'Bilbo'");
assertQuery("SELECT e FROM Employee e WHERE TRIM(LEADING '-' FROM e.lastName) = 'Bilbo'");
assertQuery("SELECT e FROM Employee e WHERE UPPER(e.lastName) = 'BILBO'");
assertQuery("SELECT e FROM Employee e WHERE CAST(e.salary NUMERIC(10, 2)) > 0.0");
assertQuery("SELECT e FROM Employee e WHERE EXTRACT(YEAR FROM e.startDate) = '2023'");
}
@Test
void specialOperators() {
assertQuery("SELECT toDo FROM Employee e JOIN e.toDoList toDo WHERE INDEX(toDo) = 1");
assertQuery("SELECT p FROM Employee e JOIN e.priorities p WHERE KEY(p) = 'high'");
assertQuery("SELECT e FROM Employee e WHERE SIZE(e.managedEmployees) < 2");
assertQuery("SELECT e FROM Employee e WHERE e.managedEmployees IS EMPTY");
assertQuery("SELECT e FROM Employee e WHERE 'write code' MEMBER OF e.responsibilities");
assertQuery("SELECT p FROM Project p WHERE TYPE(p) = LargeProject");
/**
* NOTE: The following query has been altered to properly align with EclipseLink test code despite NOT matching
* their ref docs. See https://github.com/eclipse-ee4j/eclipselink/issues/1949 for more details.
*/
assertQuery("SELECT e FROM Employee e JOIN TREAT(e.projects AS LargeProject) p WHERE p.budget > 1000000");
assertQuery("SELECT p FROM Phone p WHERE FUNCTION('TO_NUMBER', p.areaCode) > 613");
}
@Test // GH-3314
void isNullAndIsNotNull() {
assertQuery("SELECT e FROM Employee e WHERE (e.active IS null OR e.active = true)");
assertQuery("SELECT e FROM Employee e WHERE (e.active IS NULL OR e.active = true)");
assertQuery("SELECT e FROM Employee e WHERE (e.active IS NOT null OR e.active = true)");
assertQuery("SELECT e FROM Employee e WHERE (e.active IS NOT NULL OR e.active = true)");
}
@Test // GH-3496
void lateralShouldBeAValidParameter() {
assertQuery("select e from Employee e where e.lateral = :_lateral");
assertQuery("select te from TestEntity te where te.lateral = :lateral");
}
@Test // GH-3136
@@ -93,13 +296,13 @@ class JpqlComplianceTests {
}
@ParameterizedTest // GH-3136
@ValueSource(strings = {"STRING", "INTEGER", "FLOAT", "DOUBLE"})
@ValueSource(strings = { "STRING", "INTEGER", "FLOAT", "DOUBLE" })
void cast(String targetType) {
assertQuery("SELECT CAST(e.salary AS %s) FROM Employee e".formatted(targetType));
}
@ParameterizedTest // GH-3136
@ValueSource(strings = {"LEFT", "RIGHT"})
@ValueSource(strings = { "LEFT", "RIGHT" })
void leftRightStringFunctions(String keyword) {
assertQuery("SELECT %s(e.name, 3) FROM Employee e".formatted(keyword));
}

View File

@@ -327,6 +327,38 @@ class JpqlSpecificationTests {
""");
}
@Test // GH-3136
void substring() {
assertQuery("select substring(c.number, 1, 2) " + //
"from Call c");
assertQuery("select substring(c.number, 1) " + //
"from Call c");
}
@Test // GH-3136
void currentDateFunctions() {
assertQuery("select CURRENT_DATE " + //
"from Call c ");
assertQuery("select CURRENT_TIME " + //
"from Call c ");
assertQuery("select CURRENT_TIMESTAMP " + //
"from Call c ");
assertQuery("select LOCAL_DATE " + //
"from Call c ");
assertQuery("select LOCAL_TIME " + //
"from Call c ");
assertQuery("select LOCAL_DATETIME " + //
"from Call c ");
}
@Test
void pathExpressionsNamedParametersExample() {