Skip to content

Commit

Permalink
Add support for JPA 3.2 additions to EQL.
Browse files Browse the repository at this point in the history
See: #3136
Original Pull Request: #3695
  • Loading branch information
christophstrobl committed Dec 20, 2024
1 parent b44271d commit fa80414
Show file tree
Hide file tree
Showing 10 changed files with 352 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ scalar_expression
| datetime_expression
| boolean_expression
| case_expression
| cast_function
| entity_type_expression
;

Expand Down Expand Up @@ -450,6 +451,7 @@ string_expression
| case_expression
| function_invocation
| '(' subquery ')'
| string_expression '||' string_expression
;

datetime_expression
Expand Down Expand Up @@ -534,6 +536,9 @@ functions_returning_strings
| TRIM '(' ((trim_specification)? (trim_character)? FROM)? string_expression ')'
| LOWER '(' string_expression ')'
| UPPER '(' string_expression ')'
| REPLACE '(' string_expression ',' string_expression ',' string_expression ')'
| LEFT '(' string_expression ',' arithmetic_expression ')'
| RIGHT '(' string_expression ',' arithmetic_expression ')'
;

trim_specification
Expand All @@ -543,7 +548,7 @@ trim_specification
;

cast_function
: CAST '(' single_valued_path_expression identification_variable ('(' numeric_literal (',' numeric_literal)* ')')? ')'
: CAST '(' single_valued_path_expression (identification_variable)? identification_variable ('(' numeric_literal (',' numeric_literal)* ')')? ')'
;

function_invocation
Expand Down Expand Up @@ -609,6 +614,14 @@ nullif_expression
: NULLIF '(' scalar_expression ',' scalar_expression ')'
;

type_literal
: STRING
| INTEGER
| LONG
| FLOAT
| DOUBLE
;

/*******************
Gaps in the spec.
*******************/
Expand All @@ -621,6 +634,7 @@ trim_character
identification_variable
: IDENTIFICATION_VARIABLE
| f=(COUNT
| AS
| DATE
| FROM
| INNER
Expand All @@ -630,11 +644,13 @@ identification_variable
| ORDER
| OUTER
| POWER
| RIGHT
| FLOOR
| SIGN
| TIME
| TYPE
| VALUE)
| type_literal
;

constructor_name
Expand Down Expand Up @@ -811,6 +827,8 @@ reserved_word
|OR
|ORDER
|OUTER
|REPLACE
|RIGHT
|POWER
|ROUND
|SELECT
Expand Down Expand Up @@ -894,6 +912,7 @@ DATETIME : D A T E T I M E ;
DELETE : D E L E T E;
DESC : D E S C;
DISTINCT : D I S T I N C T;
DOUBLE : D O U B L E;
END : E N D;
ELSE : E L S E;
EMPTY : E M P T Y;
Expand All @@ -906,6 +925,7 @@ EXTRACT : E X T R A C T;
FALSE : F A L S E;
FETCH : F E T C H;
FIRST : F I R S T;
FLOAT : F L O A T;
FLOOR : F L O O R;
FROM : F R O M;
FUNCTION : F U N C T I O N;
Expand All @@ -914,6 +934,7 @@ HAVING : H A V I N G;
IN : I N;
INDEX : I N D E X;
INNER : I N N E R;
INTEGER : I N T E G E R;
INTERSECT : I N T E R S E C T;
IS : I S;
JOIN : J O I N;
Expand All @@ -926,6 +947,7 @@ LIKE : L I K E;
LN : L N;
LOCAL : L O C A L;
LOCATE : L O C A T E;
LONG : L O N G;
LOWER : L O W E R;
MAX : M A X;
MEMBER : M E M B E R;
Expand All @@ -944,13 +966,16 @@ ORDER : O R D E R;
OUTER : O U T E R;
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;
SIGN : S I G N;
SIZE : S I Z E;
SOME : S O M E;
SQRT : S Q R T;
STRING : S T R I N G;
SUBSTRING : S U B S T R I N G;
SUM : S U M;
THEN : T H E N;
Expand All @@ -970,7 +995,6 @@ WHERE : W H E R E;
EQUAL : '=' ;
NOT_EQUAL : '<>' | '!=' ;


CHARACTER : '\'' (~ ('\'' | '\\')) '\'' ;
IDENTIFICATION_VARIABLE : ('a' .. 'z' | 'A' .. 'Z' | '\u0080' .. '\ufffe' | '$' | '_') ('a' .. 'z' | 'A' .. 'Z' | '\u0080' .. '\ufffe' | '0' .. '9' | '$' | '_')* ;
STRINGLITERAL : '\'' (~ ('\'' | '\\')|'\\')* '\'' ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,25 @@ ql_statement
;

select_statement
: select_clause from_clause (where_clause)? (groupby_clause)? (having_clause)? (orderby_clause)? (setOperator_with_select_statement)*
: select_query
;

setOperator_with_select_statement
: INTERSECT select_statement
| UNION select_statement
| EXCEPT select_statement
select_query
: select_clause from_clause (where_clause)? (groupby_clause)? (having_clause)? (orderby_clause)? (set_fuction)?
;

setOperator
: UNION ALL?
| INTERSECT ALL?
| EXCEPT ALL?
;

set_fuction
: setOperator set_function_select
;

set_function_select
: select_query
;

update_statement
Expand Down Expand Up @@ -303,6 +315,7 @@ scalar_expression
| datetime_expression
| boolean_expression
| case_expression
| cast_expression
| entity_type_expression
;

Expand Down Expand Up @@ -442,6 +455,7 @@ string_expression
| function_invocation
| string_expression op='||' string_expression
| '(' subquery ')'
| string_expression '||' string_expression
;

datetime_expression
Expand Down Expand Up @@ -525,7 +539,10 @@ 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 ')'
| LEFT '(' string_expression ',' arithmetic_expression ')'
| RIGHT '(' string_expression ',' arithmetic_expression ')'
;

trim_specification
Expand Down Expand Up @@ -598,6 +615,10 @@ nullif_expression
: NULLIF '(' scalar_expression ',' scalar_expression ')'
;

cast_expression
: CAST '(' string_expression AS type_literal ')'
;

/*******************
Gaps in the spec.
*******************/
Expand All @@ -619,6 +640,7 @@ identification_variable
| ORDER
| OUTER
| POWER
| RIGHT
| FLOOR
| SIGN
| TIME
Expand Down Expand Up @@ -668,6 +690,14 @@ numeric_literal
| LONGLITERAL
;

type_literal
: STRING
| INTEGER
| LONG
| FLOAT
| DOUBLE
;

boolean_literal
: TRUE
| FALSE
Expand Down Expand Up @@ -799,6 +829,8 @@ reserved_word
|ORDER
|OUTER
|POWER
|REPLACE
|RIGHT
|ROUND
|SELECT
|SET
Expand Down Expand Up @@ -868,6 +900,7 @@ BETWEEN : B E T W E E N;
BOTH : B O T H;
BY : B Y;
CASE : C A S E;
CAST : C A S T;
CEILING : C E I L I N G;
COALESCE : C O A L E S C E;
CONCAT : C O N C A T;
Expand All @@ -880,6 +913,7 @@ DATETIME : D A T E T I M E ;
DELETE : D E L E T E;
DESC : D E S C;
DISTINCT : D I S T I N C T;
DOUBLE : D O U B L E;
END : E N D;
ELSE : E L S E;
EMPTY : E M P T Y;
Expand All @@ -892,6 +926,7 @@ EXTRACT : E X T R A C T;
FALSE : F A L S E;
FETCH : F E T C H;
FIRST : F I R S T;
FLOAT : F L O A T;
FLOOR : F L O O R;
FROM : F R O M;
FUNCTION : F U N C T I O N;
Expand All @@ -900,6 +935,7 @@ HAVING : H A V I N G;
IN : I N;
INDEX : I N D E X;
INNER : I N N E R;
INTEGER : I N T E G E R;
INTERSECT : I N T E R S E C T;
IS : I S;
JOIN : J O I N;
Expand All @@ -912,6 +948,7 @@ LIKE : L I K E;
LN : L N;
LOCAL : L O C A L;
LOCATE : L O C A T E;
LONG : L O N G;
LOWER : L O W E R;
MAX : M A X;
MEMBER : M E M B E R;
Expand All @@ -928,6 +965,8 @@ 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;
ROUND : R O U N D;
SELECT : S E L E C T;
Expand All @@ -936,6 +975,7 @@ SIGN : S I G N;
SIZE : S I Z E;
SOME : S O M E;
SQRT : S Q R T;
STRING : S T R I N G;
SUBSTRING : S U B S T R I N G;
SUM : S U M;
THEN : T H E N;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.antlr.v4.runtime.tree.ParseTree;

import org.springframework.data.jpa.repository.query.QueryRenderer.QueryRendererBuilder;
import org.springframework.util.ObjectUtils;

/**
* An ANTLR {@link org.antlr.v4.runtime.tree.ParseTreeVisitor} that renders an EQL query without making any changes.
Expand Down Expand Up @@ -1008,6 +1009,8 @@ public QueryTokenStream visitScalar_expression(EqlParser.Scalar_expressionContex
builder.append(visit(ctx.case_expression()));
} else if (ctx.entity_type_expression() != null) {
builder.append(visit(ctx.entity_type_expression()));
} else if (ctx.cast_function() != null) {
return (visit(ctx.cast_function()));
}

return builder;
Expand Down Expand Up @@ -1595,6 +1598,11 @@ public QueryTokenStream visitString_expression(EqlParser.String_expressionContex
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.subquery()));
builder.append(TOKEN_CLOSE_PAREN);
} else if (!ObjectUtils.isEmpty(ctx.string_expression())) {

builder.appendInline(visit(ctx.string_expression(0)));
builder.append(TOKEN_DOUBLE_PIPE);
builder.appendExpression(visit(ctx.string_expression(1)));
}

return builder;
Expand Down Expand Up @@ -1926,6 +1934,32 @@ public QueryTokenStream visitFunctions_returning_strings(EqlParser.Functions_ret
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(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)));
builder.append(TOKEN_COMMA);
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)));
builder.append(TOKEN_COMMA);
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)));
builder.append(TOKEN_COMMA);
builder.appendInline(visit(ctx.string_expression(1)));
builder.append(TOKEN_COMMA);
builder.appendInline(visit(ctx.string_expression(2)));
builder.append(TOKEN_CLOSE_PAREN);
}

return builder;
Expand All @@ -1952,9 +1986,9 @@ public QueryTokenStream visitCast_function(EqlParser.Cast_functionContext ctx) {
builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(visit(ctx.single_valued_path_expression()));
builder.append(TOKEN_SPACE);
builder.appendInline(visit(ctx.identification_variable()));
builder.appendInline(QueryTokenStream.concat(ctx.identification_variable(), this::visit, TOKEN_SPACE));

if (ctx.numeric_literal() != null) {
if (!ObjectUtils.isEmpty(ctx.numeric_literal())) {

builder.append(TOKEN_OPEN_PAREN);
builder.appendInline(QueryTokenStream.concat(ctx.numeric_literal(), this::visit, TOKEN_COMMA));
Expand Down Expand Up @@ -2055,6 +2089,14 @@ public QueryTokenStream visitCase_expression(EqlParser.Case_expressionContext ct
}
}

@Override
public QueryRendererBuilder visitType_literal(EqlParser.Type_literalContext ctx) {

QueryRendererBuilder builder = QueryRenderer.builder();
ctx.children.forEach(it -> builder.append(QueryTokens.expression(it.getText())));
return builder;
}

@Override
public QueryTokenStream visitGeneral_case_expression(EqlParser.General_case_expressionContext ctx) {

Expand Down Expand Up @@ -2175,9 +2217,11 @@ public QueryTokenStream visitIdentification_variable(EqlParser.Identification_va
return QueryRendererBuilder.from(QueryTokens.expression(ctx.IDENTIFICATION_VARIABLE()));
} else if (ctx.f != null) {
return QueryRendererBuilder.from(QueryTokens.expression(ctx.f));
} else {
return QueryRenderer.builder();
} else if (ctx.type_literal() != null) {
return visit(ctx.type_literal());
}

return QueryRenderer.builder();
}

@Override
Expand Down
Loading

0 comments on commit fa80414

Please sign in to comment.