mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-04 12:17:41 +08:00
PL-5590 AST-based QueryTransformer
JPA2 parser and lexer AST tests fixed #PL-5590
This commit is contained in:
parent
65147ef520
commit
acf1a3b36b
@ -4,8 +4,8 @@
|
||||
*/
|
||||
package com.haulmont.cuba.core.sys.jpql;
|
||||
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr.JPALexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr.JPAParser;
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr2.JPA2Lexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr2.JPA2Parser;
|
||||
import org.antlr.runtime.CharStream;
|
||||
import org.antlr.runtime.CommonTokenStream;
|
||||
import org.antlr.runtime.RecognitionException;
|
||||
@ -14,37 +14,37 @@ import org.antlr.runtime.tree.CommonTree;
|
||||
|
||||
public class Parser {
|
||||
public static CommonTree parse(String input) throws RecognitionException {
|
||||
JPAParser parser = createParser(input);
|
||||
JPAParser.ql_statement_return aReturn = parser.ql_statement();
|
||||
JPA2Parser parser = createParser(input);
|
||||
JPA2Parser.ql_statement_return aReturn = parser.ql_statement();
|
||||
return (CommonTree) aReturn.getTree();
|
||||
}
|
||||
|
||||
public static CommonTree parseWhereClause(String input) throws RecognitionException {
|
||||
JPAParser parser = createParser(input);
|
||||
JPAParser.where_clause_return aReturn = parser.where_clause();
|
||||
JPA2Parser parser = createParser(input);
|
||||
JPA2Parser.where_clause_return aReturn = parser.where_clause();
|
||||
return (CommonTree) aReturn.getTree();
|
||||
}
|
||||
|
||||
public static CommonTree parseJoinClause(String join) throws RecognitionException {
|
||||
JPAParser parser = createParser(join);
|
||||
JPAParser.join_return aReturn = parser.join();
|
||||
JPA2Parser parser = createParser(join);
|
||||
JPA2Parser.join_return aReturn = parser.join();
|
||||
return (CommonTree) aReturn.getTree();
|
||||
}
|
||||
|
||||
private static JPAParser createParser(String input) {
|
||||
private static JPA2Parser createParser(String input) {
|
||||
if (input.contains("~"))
|
||||
throw new IllegalArgumentException("Input string cannot contain \"~\"");
|
||||
|
||||
CharStream cs = new AntlrNoCaseStringStream(input);
|
||||
JPALexer lexer = new JPALexer(cs);
|
||||
JPA2Lexer lexer = new JPA2Lexer(cs);
|
||||
TokenStream tstream = new CommonTokenStream(lexer);
|
||||
return new JPAParser(tstream);
|
||||
return new JPA2Parser(tstream);
|
||||
}
|
||||
|
||||
public static CommonTree parseSelectionSource(String input) throws RecognitionException {
|
||||
JPAParser parser = createParser(input);
|
||||
JPAParser.identification_variable_or_collection_declaration_return aReturn =
|
||||
parser.identification_variable_or_collection_declaration();
|
||||
JPA2Parser parser = createParser(input);
|
||||
JPA2Parser.identification_variable_declaration_or_collection_member_declaration_return aReturn =
|
||||
parser.identification_variable_declaration_or_collection_member_declaration();
|
||||
return (CommonTree) aReturn.getTree();
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
package com.haulmont.cuba.core.sys.jpql;
|
||||
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr.JPALexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr2.JPA2Lexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.model.Entity;
|
||||
import com.haulmont.cuba.core.sys.jpql.pointer.EntityPointer;
|
||||
import com.haulmont.cuba.core.sys.jpql.pointer.Pointer;
|
||||
@ -63,7 +63,7 @@ public class QueryTreeAnalyzer {
|
||||
}
|
||||
|
||||
public PathNode getSelectedPathNode() {
|
||||
Tree selectedItems = tree.getFirstChildWithType(JPALexer.T_SELECTED_ITEMS);
|
||||
Tree selectedItems = tree.getFirstChildWithType(JPA2Lexer.T_SELECTED_ITEMS);
|
||||
boolean isDistinct = "DISTINCT".equalsIgnoreCase(selectedItems.getChild(0).getText());
|
||||
SelectedItemNode selectedItemNode;
|
||||
if (isDistinct) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
package com.haulmont.cuba.core.sys.jpql;
|
||||
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr.JPALexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr2.JPA2Lexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.TreeToQueryCapable;
|
||||
import org.antlr.runtime.tree.CommonErrorNode;
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
@ -40,25 +40,25 @@ public class TreeToQuery implements TreeVisitorAction {
|
||||
if (node.token == null)
|
||||
return t;
|
||||
|
||||
if (node.getType() == JPALexer.HAVING ||
|
||||
node.parent != null && node.parent.getType() == JPALexer.T_SIMPLE_CONDITION ||
|
||||
node.parent != null && node.parent.getType() == JPALexer.T_GROUP_BY ||
|
||||
node.parent != null && node.parent.getType() == JPALexer.T_ORDER_BY && node.getType() != JPALexer.T_ORDER_BY_FIELD ||
|
||||
node.parent != null && node.parent.getType() == JPALexer.T_CONDITION && node.getType() == JPALexer.LPAREN && node.childIndex - 1 >= 0 && node.parent.getChild(node.childIndex - 1).getType() != JPALexer.LPAREN ||
|
||||
node.getType() == JPALexer.AND ||
|
||||
node.parent != null && node.parent.getType() == JPALexer.T_ORDER_BY_FIELD ||
|
||||
node.getType() == JPALexer.OR ||
|
||||
node.getType() == JPALexer.DISTINCT && node.childIndex == 0 ||
|
||||
node.getType() == JPALexer.JOIN ||
|
||||
node.getType() == JPALexer.LEFT ||
|
||||
node.getType() == JPALexer.OUTER ||
|
||||
node.getType() == JPALexer.INNER ||
|
||||
node.getType() == JPALexer.FETCH
|
||||
if (node.getType() == JPA2Lexer.HAVING ||
|
||||
node.parent != null && node.parent.getType() == JPA2Lexer.T_SIMPLE_CONDITION ||
|
||||
node.parent != null && node.parent.getType() == JPA2Lexer.T_GROUP_BY ||
|
||||
node.parent != null && node.parent.getType() == JPA2Lexer.T_ORDER_BY && node.getType() != JPA2Lexer.T_ORDER_BY_FIELD ||
|
||||
node.parent != null && node.parent.getType() == JPA2Lexer.T_CONDITION && node.getType() == JPA2Lexer.LPAREN && node.childIndex - 1 >= 0 && node.parent.getChild(node.childIndex - 1).getType() != JPA2Lexer.LPAREN ||
|
||||
node.getType() == JPA2Lexer.AND ||
|
||||
node.parent != null && node.parent.getType() == JPA2Lexer.T_ORDER_BY_FIELD ||
|
||||
node.getType() == JPA2Lexer.OR ||
|
||||
node.getType() == JPA2Lexer.DISTINCT && node.childIndex == 0 ||
|
||||
node.getType() == JPA2Lexer.JOIN ||
|
||||
node.getType() == JPA2Lexer.LEFT ||
|
||||
node.getType() == JPA2Lexer.OUTER ||
|
||||
node.getType() == JPA2Lexer.INNER ||
|
||||
node.getType() == JPA2Lexer.FETCH
|
||||
) {
|
||||
sb.appendSpace();
|
||||
}
|
||||
|
||||
if (node.getType() == JPALexer.T_ORDER_BY_FIELD && node.childIndex - 1 >= 0 && node.parent.getChild(node.childIndex - 1).getType() == JPALexer.T_ORDER_BY_FIELD) {
|
||||
if (node.getType() == JPA2Lexer.T_ORDER_BY_FIELD && node.childIndex - 1 >= 0 && node.parent.getChild(node.childIndex - 1).getType() == JPA2Lexer.T_ORDER_BY_FIELD) {
|
||||
sb.appendString(", ");
|
||||
}
|
||||
|
||||
@ -66,11 +66,11 @@ public class TreeToQuery implements TreeVisitorAction {
|
||||
return ((TreeToQueryCapable) t).treeToQueryPre(sb, invalidNodes);
|
||||
}
|
||||
|
||||
if (node.getType() == JPALexer.T_SELECTED_ITEMS) {
|
||||
if (node.getType() == JPA2Lexer.T_SELECTED_ITEMS) {
|
||||
return t;
|
||||
}
|
||||
|
||||
if (node.getType() == JPALexer.T_SOURCES) {
|
||||
if (node.getType() == JPA2Lexer.T_SOURCES) {
|
||||
sb.appendString("FROM ");
|
||||
return t;
|
||||
}
|
||||
@ -92,7 +92,7 @@ public class TreeToQuery implements TreeVisitorAction {
|
||||
if (node.token == null)
|
||||
return t;
|
||||
|
||||
if (node.getType() == JPALexer.DISTINCT || node.getType() == JPALexer.FETCH)
|
||||
if (node.getType() == JPA2Lexer.DISTINCT || node.getType() == JPA2Lexer.FETCH)
|
||||
sb.appendSpace();
|
||||
|
||||
|
||||
|
477
modules/global/src/com/haulmont/cuba/core/sys/jpql/antlr/JPA.g
Normal file
477
modules/global/src/com/haulmont/cuba/core/sys/jpql/antlr/JPA.g
Normal file
@ -0,0 +1,477 @@
|
||||
|
||||
grammar JPA;
|
||||
|
||||
// Alexander Kunkel
|
||||
// More JPA informations:
|
||||
// http://www.kunkelgmbh.de/jpa/jpa.html
|
||||
// 28.11.2009
|
||||
|
||||
// Alexander Chevelev
|
||||
// 15.10.2010
|
||||
|
||||
options{
|
||||
backtrack=true;
|
||||
output=AST;
|
||||
}
|
||||
|
||||
tokens {
|
||||
T_SELECTED_ITEMS;
|
||||
T_SELECTED_ITEM;
|
||||
T_SOURCES;
|
||||
T_SOURCE;
|
||||
T_SELECTED_FIELD;
|
||||
T_SELECTED_ENTITY;
|
||||
T_ID_VAR;
|
||||
T_JOIN_VAR;
|
||||
T_COLLECTION_MEMBER;
|
||||
T_QUERY;
|
||||
T_CONDITION;
|
||||
T_SIMPLE_CONDITION;
|
||||
T_PARAMETER;
|
||||
T_GROUP_BY;
|
||||
T_ORDER_BY;
|
||||
T_ORDER_BY_FIELD;
|
||||
T_AGGREGATE_EXPR;
|
||||
HAVING = 'HAVING';
|
||||
ASC = 'ASC';
|
||||
DESC = 'DESC';
|
||||
AVG = 'AVG';
|
||||
MAX = 'MAX';
|
||||
MIN = 'MIN';
|
||||
SUM = 'SUM';
|
||||
COUNT = 'COUNT';
|
||||
OR = 'OR';
|
||||
AND = 'AND';
|
||||
LPAREN = '(';
|
||||
RPAREN = ')';
|
||||
DISTINCT = 'DISTINCT';
|
||||
LEFT = 'LEFT';
|
||||
OUTER = 'OUTER';
|
||||
INNER = 'INNER';
|
||||
JOIN = 'JOIN';
|
||||
FETCH = 'FETCH';
|
||||
ORDER = 'ORDER';
|
||||
GROUP = 'GROUP';
|
||||
BY = 'BY';
|
||||
}
|
||||
|
||||
|
||||
@header {
|
||||
package com.haulmont.cuba.core.sys.jpql.antlr;
|
||||
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.QueryNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.SelectedItemNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.PathNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.FromNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.SelectionSourceNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.IdentificationVariableNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.JoinVariableNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.CollectionMemberNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.WhereNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.SimpleConditionNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.ParameterNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.GroupByNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.OrderByNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.OrderByFieldNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.AggregateExpressionNode;
|
||||
}
|
||||
|
||||
@lexer::header {
|
||||
package com.haulmont.cuba.core.sys.jpql.antlr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
ql_statement
|
||||
: select_statement;
|
||||
|
||||
select_statement
|
||||
: sl='SELECT' select_clause from_clause (where_clause)? (groupby_clause)? (having_clause)?(orderby_clause)?
|
||||
-> ^(T_QUERY<QueryNode>[$sl] (select_clause)? from_clause (where_clause)? (groupby_clause)? (having_clause)? (orderby_clause)?);
|
||||
|
||||
from_clause
|
||||
: fr='FROM' identification_variable_declaration (',' identification_variable_or_collection_declaration)*
|
||||
-> ^(T_SOURCES<FromNode>[$fr] identification_variable_declaration identification_variable_or_collection_declaration*);
|
||||
|
||||
identification_variable_or_collection_declaration
|
||||
: identification_variable_declaration
|
||||
| collection_member_declaration -> ^(T_SOURCE<SelectionSourceNode> collection_member_declaration);
|
||||
|
||||
identification_variable_declaration
|
||||
: range_variable_declaration joined_clause*
|
||||
-> ^(T_SOURCE<SelectionSourceNode> range_variable_declaration joined_clause*);
|
||||
|
||||
joined_clause
|
||||
: join | fetch_join;
|
||||
|
||||
range_variable_declaration
|
||||
: range_variable_declaration_source ('AS')? identification_variable
|
||||
-> ^(T_ID_VAR<IdentificationVariableNode>[$identification_variable.text] range_variable_declaration_source )
|
||||
;
|
||||
|
||||
range_variable_declaration_source
|
||||
: abstract_schema_name
|
||||
| lp='(SELECT' select_clause from_clause (where_clause)? (groupby_clause)? (having_clause)?(orderby_clause)? rp=')'
|
||||
-> ^(T_QUERY<QueryNode>[$lp, $rp] (select_clause)? from_clause (where_clause)? (groupby_clause)? (having_clause)? (orderby_clause)?)
|
||||
;
|
||||
|
||||
join
|
||||
: join_spec join_association_path_expression ('AS')? identification_variable
|
||||
-> ^(T_JOIN_VAR<JoinVariableNode>[$join_spec.text, $identification_variable.text] join_association_path_expression )
|
||||
;
|
||||
|
||||
fetch_join
|
||||
: join_spec 'FETCH' join_association_path_expression;
|
||||
|
||||
join_spec
|
||||
:(('LEFT') ('OUTER')? | 'INNER' )? 'JOIN';
|
||||
|
||||
join_association_path_expression
|
||||
: identification_variable '.' (field'.')* field?
|
||||
-> ^(T_SELECTED_FIELD<PathNode>[$identification_variable.text] (field)*)
|
||||
;
|
||||
|
||||
collection_member_declaration
|
||||
: 'IN''(' path_expression ')' ('AS')? identification_variable
|
||||
-> ^(T_COLLECTION_MEMBER<CollectionMemberNode>[$identification_variable.text] path_expression )
|
||||
;
|
||||
|
||||
path_expression
|
||||
: identification_variable '.' (field'.')* (field)?
|
||||
-> ^(T_SELECTED_FIELD<PathNode>[$identification_variable.text] (field)*)
|
||||
;
|
||||
|
||||
select_clause
|
||||
: ('DISTINCT')? select_expression (',' select_expression)*
|
||||
-> ^(T_SELECTED_ITEMS ('DISTINCT')? ^(T_SELECTED_ITEM<SelectedItemNode>[] select_expression)*)
|
||||
;
|
||||
|
||||
select_expression
|
||||
: path_expression
|
||||
| aggregate_expression
|
||||
| identification_variable -> ^(T_SELECTED_ENTITY<PathNode>[$identification_variable.text])
|
||||
| 'OBJECT' '('identification_variable')'
|
||||
| constructor_expression;
|
||||
|
||||
constructor_expression
|
||||
: 'NEW' constructor_name '(' constructor_item (',' constructor_item)* ')';
|
||||
|
||||
constructor_item
|
||||
: path_expression | aggregate_expression;
|
||||
|
||||
aggregate_expression
|
||||
: aggregate_expression_function_name '(' ('DISTINCT')? path_expression')'
|
||||
-> ^(T_AGGREGATE_EXPR<AggregateExpressionNode>[] aggregate_expression_function_name '(' ('DISTINCT')? path_expression')')
|
||||
| 'COUNT' '(' ('DISTINCT')? identification_variable ')'
|
||||
-> ^(T_AGGREGATE_EXPR<AggregateExpressionNode>[] 'COUNT' '(' ('DISTINCT')? identification_variable ')');
|
||||
|
||||
aggregate_expression_function_name
|
||||
: 'AVG' | 'MAX' | 'MIN' |'SUM' | 'COUNT';
|
||||
|
||||
where_clause
|
||||
: wh='WHERE' conditional_expression-> ^(T_CONDITION<WhereNode>[$wh] conditional_expression)
|
||||
| 'WHERE' path_expression -> ^(T_CONDITION<WhereNode>[$wh] path_expression);
|
||||
|
||||
groupby_clause
|
||||
: 'GROUP' 'BY' groupby_item (',' groupby_item)*
|
||||
-> ^(T_GROUP_BY<GroupByNode>[] 'GROUP' 'BY' groupby_item*)
|
||||
;
|
||||
|
||||
groupby_item
|
||||
: path_expression | identification_variable;
|
||||
|
||||
having_clause
|
||||
: 'HAVING' conditional_expression;
|
||||
|
||||
orderby_clause
|
||||
: 'ORDER' 'BY' orderby_item (',' orderby_item)*
|
||||
-> ^(T_ORDER_BY<OrderByNode>[] 'ORDER' 'BY' orderby_item*);
|
||||
|
||||
orderby_item
|
||||
: path_expression ('ASC')?
|
||||
-> ^(T_ORDER_BY_FIELD<OrderByFieldNode>[] path_expression ('ASC')?)
|
||||
| path_expression 'DESC'
|
||||
-> ^(T_ORDER_BY_FIELD<OrderByFieldNode>[] path_expression 'DESC');
|
||||
|
||||
subquery
|
||||
: lp='(SELECT' simple_select_clause subquery_from_clause (where_clause)? (groupby_clause)? (having_clause)? rp=')'
|
||||
-> ^(T_QUERY<QueryNode>[$lp,$rp] simple_select_clause subquery_from_clause (where_clause)? (groupby_clause)? (having_clause)? );
|
||||
|
||||
subquery_from_clause
|
||||
: fr='FROM' subselect_identification_variable_declaration (',' subselect_identification_variable_declaration)*
|
||||
-> ^(T_SOURCES<FromNode>[$fr] ^(T_SOURCE<SelectionSourceNode> subselect_identification_variable_declaration)*);
|
||||
|
||||
subselect_identification_variable_declaration
|
||||
: identification_variable_declaration
|
||||
| association_path_expression ('AS')? identification_variable
|
||||
| collection_member_declaration;
|
||||
|
||||
association_path_expression
|
||||
: path_expression;
|
||||
|
||||
simple_select_clause
|
||||
: ('DISTINCT')? simple_select_expression
|
||||
-> ^(T_SELECTED_ITEMS ^(T_SELECTED_ITEM<SelectedItemNode>[] ('DISTINCT')? simple_select_expression));
|
||||
|
||||
simple_select_expression
|
||||
: path_expression
|
||||
| aggregate_expression
|
||||
| identification_variable;
|
||||
|
||||
conditional_expression
|
||||
: (conditional_term) ('OR' conditional_term)*;
|
||||
|
||||
conditional_term
|
||||
: (conditional_factor) ('AND' conditional_factor)*;
|
||||
|
||||
conditional_factor
|
||||
: ('NOT')? simple_cond_expression -> ^(T_SIMPLE_CONDITION<SimpleConditionNode>[] ('NOT')? simple_cond_expression)
|
||||
| '('conditional_expression')';
|
||||
|
||||
simple_cond_expression
|
||||
: comparison_expression
|
||||
| between_expression
|
||||
| like_expression
|
||||
| in_expression
|
||||
| null_comparison_expression
|
||||
| empty_collection_comparison_expression
|
||||
| collection_member_expression
|
||||
| exists_expression
|
||||
| date_macro_expression;
|
||||
|
||||
date_macro_expression
|
||||
: date_between_macro_expression
|
||||
| date_before_macro_expression
|
||||
| date_after_macro_expression
|
||||
| date_equals_macro_expression
|
||||
| date_today_macro_expression;
|
||||
|
||||
date_between_macro_expression
|
||||
: '@BETWEEN' '(' path_expression ',' 'NOW' (('+' | '-') INT_NUMERAL)? ',' 'NOW' (('+' | '-') INT_NUMERAL)? ',' ('YEAR' | 'MONTH' | 'DAY' | 'HOUR' |'MINUTE' | 'SECOND') ')';
|
||||
|
||||
date_before_macro_expression
|
||||
: '@DATEBEFORE' '(' path_expression ',' (path_expression | input_parameter) ')';
|
||||
|
||||
date_after_macro_expression
|
||||
: '@DATEAFTER' '(' path_expression ',' (path_expression | input_parameter) ')';
|
||||
|
||||
date_equals_macro_expression
|
||||
: '@DATEEQUALS' '(' path_expression ',' (path_expression | input_parameter) ')';
|
||||
|
||||
date_today_macro_expression
|
||||
: '@TODAY' '(' path_expression ')';
|
||||
|
||||
between_expression
|
||||
: arithmetic_expression ('NOT')? 'BETWEEN' arithmetic_expression 'AND' arithmetic_expression
|
||||
| string_expression ('NOT')? 'BETWEEN' string_expression 'AND' string_expression
|
||||
| datetime_expression ('NOT')? 'BETWEEN' datetime_expression 'AND' datetime_expression;
|
||||
|
||||
in_expression
|
||||
: path_expression ('NOT')? 'IN' in_expression_right_part;
|
||||
|
||||
in_expression_right_part
|
||||
: '(' in_item (',' in_item)* ')'
|
||||
| subquery;
|
||||
|
||||
in_item
|
||||
: literal
|
||||
| input_parameter;
|
||||
|
||||
like_expression
|
||||
: string_expression ('NOT')? 'LIKE' (pattern_value | input_parameter)('ESCAPE' ESCAPE_CHARACTER)?;
|
||||
|
||||
null_comparison_expression
|
||||
: (path_expression | input_parameter) 'IS' ('NOT')? 'NULL';
|
||||
|
||||
empty_collection_comparison_expression
|
||||
: path_expression 'IS' ('NOT')? 'EMPTY';
|
||||
|
||||
collection_member_expression
|
||||
: entity_expression ('NOT')? 'MEMBER' ('OF')? path_expression;
|
||||
|
||||
exists_expression
|
||||
: ('NOT')? 'EXISTS' subquery;
|
||||
|
||||
all_or_any_expression
|
||||
: ( 'ALL' | 'ANY' | 'SOME') subquery;
|
||||
|
||||
comparison_expression
|
||||
: string_expression comparison_operator (string_expression | all_or_any_expression)
|
||||
| boolean_expression ('=' | '<>') (boolean_expression | all_or_any_expression)
|
||||
| enum_expression ('='|'<>') (enum_expression | all_or_any_expression)
|
||||
| datetime_expression comparison_operator (datetime_expression | all_or_any_expression)
|
||||
| entity_expression ('=' | '<>') (entity_expression | all_or_any_expression)
|
||||
| arithmetic_expression comparison_operator (arithmetic_expression | all_or_any_expression);
|
||||
|
||||
comparison_operator
|
||||
: '='
|
||||
| '>'
|
||||
| '>='
|
||||
| '<'
|
||||
| '<='
|
||||
| '<>';
|
||||
|
||||
arithmetic_expression
|
||||
: simple_arithmetic_expression
|
||||
| subquery;
|
||||
|
||||
simple_arithmetic_expression
|
||||
: (arithmetic_term) (( '+' | '-' ) arithmetic_term)*;
|
||||
|
||||
arithmetic_term
|
||||
: (arithmetic_factor) (( '*' | '/' ) arithmetic_factor)*;
|
||||
|
||||
arithmetic_factor
|
||||
: ( '+' | '-' )? arithmetic_primary;
|
||||
|
||||
arithmetic_primary
|
||||
: path_expression
|
||||
| numeric_literal
|
||||
| '('simple_arithmetic_expression')'
|
||||
| input_parameter
|
||||
| functions_returning_numerics
|
||||
| aggregate_expression;
|
||||
|
||||
string_expression
|
||||
: string_primary | subquery;
|
||||
|
||||
string_primary
|
||||
: path_expression
|
||||
| STRINGLITERAL
|
||||
| input_parameter
|
||||
| functions_returning_strings
|
||||
| aggregate_expression;
|
||||
|
||||
datetime_expression
|
||||
: datetime_primary
|
||||
| subquery;
|
||||
|
||||
datetime_primary
|
||||
: path_expression
|
||||
| input_parameter
|
||||
| functions_returning_datetime
|
||||
| aggregate_expression;
|
||||
|
||||
boolean_expression
|
||||
: boolean_primary
|
||||
| subquery;
|
||||
|
||||
boolean_primary
|
||||
: path_expression
|
||||
| boolean_literal
|
||||
| input_parameter;
|
||||
|
||||
enum_expression
|
||||
: enum_primary
|
||||
| subquery;
|
||||
|
||||
enum_primary
|
||||
: path_expression
|
||||
| enum_literal
|
||||
| input_parameter;
|
||||
|
||||
entity_expression
|
||||
: path_expression
|
||||
| simple_entity_expression;
|
||||
|
||||
simple_entity_expression
|
||||
: identification_variable
|
||||
| input_parameter;
|
||||
|
||||
functions_returning_numerics
|
||||
: 'LENGTH' '('string_primary')'
|
||||
| 'LOCATE' '('string_primary',' string_primary(',' simple_arithmetic_expression)?')'
|
||||
| 'ABS' '('simple_arithmetic_expression')'
|
||||
| 'SQRT' '('simple_arithmetic_expression')'
|
||||
| 'MOD' '('simple_arithmetic_expression',' simple_arithmetic_expression')'
|
||||
| 'SIZE' '('path_expression')';
|
||||
|
||||
functions_returning_datetime
|
||||
: 'CURRENT_DATE'
|
||||
| 'CURRENT_TIME'
|
||||
| 'CURRENT_TIMESTAMP';
|
||||
|
||||
functions_returning_strings
|
||||
: 'CONCAT' '('string_primary',' string_primary')'
|
||||
| 'SUBSTRING' '('string_primary','simple_arithmetic_expression',' simple_arithmetic_expression')'
|
||||
| 'TRIM' '('((trim_specification)? (TRIM_CHARACTER)? 'FROM')? string_primary')'
|
||||
| 'LOWER' '('string_primary')'
|
||||
| 'UPPER' '('string_primary')';
|
||||
|
||||
trim_specification
|
||||
: 'LEADING'
|
||||
| 'TRAILING'
|
||||
| 'BOTH';
|
||||
|
||||
//my
|
||||
abstract_schema_name
|
||||
: WORD;
|
||||
|
||||
//todo fix pattern value if needed
|
||||
pattern_value
|
||||
: WORD;
|
||||
|
||||
// my
|
||||
numeric_literal
|
||||
: ('0x')? INT_NUMERAL ;
|
||||
|
||||
input_parameter
|
||||
: '?' INT_NUMERAL -> ^(T_PARAMETER<ParameterNode>[] '?' INT_NUMERAL )
|
||||
| NAMED_PARAMETER -> ^(T_PARAMETER<ParameterNode>[] NAMED_PARAMETER )
|
||||
| '${' WORD '}' -> ^(T_PARAMETER<ParameterNode>[] '${' WORD '}');
|
||||
|
||||
literal
|
||||
: WORD;
|
||||
|
||||
constructor_name
|
||||
: WORD;
|
||||
|
||||
enum_literal
|
||||
: WORD;
|
||||
|
||||
boolean_literal
|
||||
: 'true'
|
||||
| 'false';
|
||||
|
||||
// my
|
||||
field
|
||||
: WORD | 'GROUP';
|
||||
|
||||
identification_variable
|
||||
: WORD;
|
||||
|
||||
parameter_name
|
||||
: WORD ('.' WORD)*;
|
||||
|
||||
|
||||
// Lexical Rules
|
||||
//fix trim character
|
||||
TRIM_CHARACTER
|
||||
: '\'.\'';
|
||||
|
||||
STRINGLITERAL
|
||||
: '\'' (~('\'' | '"') )* '\'' ;
|
||||
|
||||
WORD
|
||||
: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'$')*;
|
||||
|
||||
RUSSIAN_SYMBOLS
|
||||
: ('\u0400'..'\u04FF'|'\u0500'..'\u052F' ) {if ( 1 == 1) throw new IllegalArgumentException("Incorrect symbol");};
|
||||
|
||||
NAMED_PARAMETER
|
||||
: ':'('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'$')* (('.') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'$')+)*;
|
||||
|
||||
WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;}
|
||||
;
|
||||
|
||||
COMMENT
|
||||
: '/*' .* '*/' {$channel=HIDDEN;};
|
||||
|
||||
LINE_COMMENT
|
||||
: '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;};
|
||||
|
||||
ESCAPE_CHARACTER
|
||||
: '\'' (~('\''|'\\') ) '\'';
|
||||
|
||||
INT_NUMERAL
|
||||
: ('0'..'9')+;
|
@ -117,49 +117,25 @@ join_association_path_expression
|
||||
//End : here we have simplified joins
|
||||
|
||||
collection_member_declaration
|
||||
: 'IN''(' collection_valued_path_expression ')' ('AS')? identification_variable
|
||||
-> ^(T_COLLECTION_MEMBER<CollectionMemberNode>[$identification_variable.text] collection_valued_path_expression );
|
||||
: 'IN''(' path_expression ')' ('AS')? identification_variable
|
||||
-> ^(T_COLLECTION_MEMBER<CollectionMemberNode>[$identification_variable.text] path_expression );
|
||||
|
||||
qualified_identification_variable
|
||||
: map_field_identification_variable
|
||||
| 'ENTRY('identification_variable')';
|
||||
map_field_identification_variable : 'KEY('identification_variable')' | 'VALUE('identification_variable')';
|
||||
|
||||
//todo start : simplify path expression and use PathNode
|
||||
//Start : here we have simplified paths
|
||||
path_expression
|
||||
: identification_variable '.' (field'.')* (field)?
|
||||
-> ^(T_SELECTED_FIELD<PathNode>[$identification_variable.text] (field)*)
|
||||
;
|
||||
|
||||
single_valued_path_expression
|
||||
: qualified_identification_variable
|
||||
| 'TREAT('qualified_identification_variable 'AS' subtype')'
|
||||
| state_field_path_expression
|
||||
| single_valued_object_path_expression;
|
||||
//todo treated path
|
||||
//End : here we have simplified paths
|
||||
|
||||
general_identification_variable
|
||||
: identification_variable
|
||||
| map_field_identification_variable;
|
||||
general_subpath
|
||||
: simple_subpath
|
||||
| treated_subpath '.' (single_valued_object_field '.')*;
|
||||
simple_subpath
|
||||
: general_identification_variable '.' (single_valued_object_field '.')*
|
||||
;
|
||||
treated_subpath
|
||||
: 'TREAT('general_subpath '.' single_valued_object_field 'AS' subtype ')'
|
||||
| 'TREAT('general_subpath '.' collection_valued_field 'AS' subtype ')';
|
||||
state_field_path_expression
|
||||
: general_subpath state_field;
|
||||
state_valued_path_expression
|
||||
: state_field_path_expression
|
||||
| general_identification_variable;
|
||||
single_valued_object_path_expression
|
||||
: general_subpath single_valued_object_field;
|
||||
collection_valued_path_expression
|
||||
: general_subpath collection_valued_field;
|
||||
//todo end
|
||||
|
||||
update_clause
|
||||
: entity_name (('AS')? identification_variable)? 'SET' update_item (',' update_item)*;
|
||||
update_item
|
||||
@ -176,37 +152,36 @@ select_clause
|
||||
select_item
|
||||
: select_expression (('AS')? result_variable)?;
|
||||
select_expression
|
||||
: single_valued_path_expression
|
||||
: path_expression
|
||||
| identification_variable -> ^(T_SELECTED_ENTITY<PathNode>[$identification_variable.text])
|
||||
| scalar_expression
|
||||
| aggregate_expression
|
||||
| identification_variable
|
||||
| 'OBJECT' '('identification_variable')'
|
||||
| constructor_expression;
|
||||
constructor_expression
|
||||
: 'NEW' constructor_name '(' constructor_item (',' constructor_item)* ')';
|
||||
constructor_item
|
||||
: single_valued_path_expression
|
||||
: path_expression
|
||||
| scalar_expression
|
||||
| aggregate_expression
|
||||
| identification_variable;
|
||||
aggregate_expression
|
||||
: aggregate_expression_function_name '('(DISTINCT)? state_valued_path_expression')'
|
||||
-> ^(T_AGGREGATE_EXPR<AggregateExpressionNode>[] aggregate_expression_function_name '(' ('DISTINCT')? state_valued_path_expression')')
|
||||
: aggregate_expression_function_name '('(DISTINCT)? path_expression')'
|
||||
-> ^(T_AGGREGATE_EXPR<AggregateExpressionNode>[] aggregate_expression_function_name '(' ('DISTINCT')? path_expression')')
|
||||
| 'COUNT' '('(DISTINCT)? count_argument ')'
|
||||
-> ^(T_AGGREGATE_EXPR<AggregateExpressionNode>[] 'COUNT' '(' ('DISTINCT')? count_argument ')')
|
||||
| function_invocation;
|
||||
aggregate_expression_function_name
|
||||
: 'AVG' | 'MAX' | 'MIN' |'SUM' | 'COUNT';
|
||||
count_argument
|
||||
: identification_variable | state_valued_path_expression | single_valued_object_path_expression;
|
||||
: identification_variable | path_expression;
|
||||
where_clause
|
||||
: wh='WHERE' conditional_expression-> ^(T_CONDITION<WhereNode>[$wh] conditional_expression);
|
||||
groupby_clause
|
||||
: 'GROUP BY' groupby_item (',' groupby_item)*
|
||||
: 'GROUP' 'BY' groupby_item (',' groupby_item)*
|
||||
-> ^(T_GROUP_BY<GroupByNode>[] 'GROUP' 'BY' groupby_item*);
|
||||
groupby_item
|
||||
: single_valued_path_expression
|
||||
| identification_variable;
|
||||
: path_expression | identification_variable;
|
||||
having_clause
|
||||
: 'HAVING' conditional_expression;
|
||||
orderby_clause
|
||||
@ -218,10 +193,10 @@ orderby_item
|
||||
| orderby_variable 'DESC'
|
||||
-> ^(T_ORDER_BY_FIELD<OrderByFieldNode>[] orderby_variable 'DESC');
|
||||
orderby_variable
|
||||
: state_field_path_expression | general_identification_variable | result_variable;
|
||||
: path_expression | general_identification_variable | result_variable;
|
||||
|
||||
subquery
|
||||
: lp='(' simple_select_clause subquery_from_clause (where_clause)? (groupby_clause)? (having_clause)? rp=')'
|
||||
: lp='(SELECT' simple_select_clause subquery_from_clause (where_clause)? (groupby_clause)? (having_clause)? rp=')'
|
||||
-> ^(T_QUERY<QueryNode>[$lp,$rp] simple_select_clause subquery_from_clause (where_clause)? (groupby_clause)? (having_clause)? );
|
||||
subquery_from_clause
|
||||
: fr='FROM' subselect_identification_variable_declaration (',' subselect_identification_variable_declaration)*
|
||||
@ -247,10 +222,10 @@ derived_collection_member_declaration
|
||||
: 'IN' superquery_identification_variable'.'(single_valued_object_field '.')*collection_valued_field;
|
||||
|
||||
simple_select_clause
|
||||
: 'SELECT' ('DISTINCT') simple_select_expression
|
||||
: ('DISTINCT')? simple_select_expression
|
||||
-> ^(T_SELECTED_ITEMS ^(T_SELECTED_ITEM<SelectedItemNode>[] ('DISTINCT')? simple_select_expression));
|
||||
simple_select_expression
|
||||
: single_valued_path_expression
|
||||
: path_expression
|
||||
| scalar_expression
|
||||
| aggregate_expression
|
||||
| identification_variable;
|
||||
@ -280,7 +255,9 @@ simple_cond_expression
|
||||
| null_comparison_expression
|
||||
| empty_collection_comparison_expression
|
||||
| collection_member_expression
|
||||
| exists_expression;
|
||||
| exists_expression
|
||||
| date_macro_expression;
|
||||
|
||||
//Start: Here we insert our custom macroses
|
||||
date_macro_expression
|
||||
: date_between_macro_expression
|
||||
@ -310,7 +287,7 @@ between_expression
|
||||
| string_expression ('NOT')? 'BETWEEN' string_expression 'AND' string_expression
|
||||
| datetime_expression ('NOT')? 'BETWEEN' datetime_expression 'AND' datetime_expression;
|
||||
in_expression
|
||||
: (state_valued_path_expression | type_discriminator) ('NOT')? 'IN'
|
||||
: (path_expression | type_discriminator) ('NOT')? 'IN'
|
||||
( '(' in_item (',' in_item)* ')'
|
||||
| subquery
|
||||
| collection_valued_input_parameter );
|
||||
@ -319,14 +296,13 @@ in_item
|
||||
like_expression
|
||||
: string_expression ('NOT')? 'LIKE' (pattern_value | input_parameter)('ESCAPE' escape_character)?;
|
||||
null_comparison_expression
|
||||
: (single_valued_path_expression | input_parameter) 'IS' ('NOT')? 'NULL';
|
||||
: (path_expression | input_parameter) 'IS' ('NOT')? 'NULL';
|
||||
empty_collection_comparison_expression
|
||||
: collection_valued_path_expression 'IS' ('NOT')? 'EMPTY';
|
||||
: path_expression 'IS' ('NOT')? 'EMPTY';
|
||||
collection_member_expression
|
||||
: entity_or_value_expression ('NOT')? 'MEMBER' ('OF')? collection_valued_path_expression;
|
||||
: entity_or_value_expression ('NOT')? 'MEMBER' ('OF')? path_expression;
|
||||
entity_or_value_expression
|
||||
: single_valued_object_path_expression
|
||||
| state_field_path_expression
|
||||
: path_expression
|
||||
| simple_entity_or_value_expression;
|
||||
simple_entity_or_value_expression
|
||||
: identification_variable
|
||||
@ -342,7 +318,8 @@ comparison_expression
|
||||
| enum_expression ('='|'<>') (enum_expression | all_or_any_expression)
|
||||
| datetime_expression comparison_operator (datetime_expression | all_or_any_expression)
|
||||
| entity_expression ('=' | '<>') (entity_expression | all_or_any_expression)
|
||||
| entity_type_expression ('=' | '<>') entity_type_expression;
|
||||
| entity_type_expression ('=' | '<>') entity_type_expression
|
||||
| arithmetic_expression comparison_operator (arithmetic_expression | all_or_any_expression);
|
||||
|
||||
comparison_operator
|
||||
: '='
|
||||
@ -360,7 +337,7 @@ arithmetic_term
|
||||
arithmetic_factor
|
||||
: (( '+' | '-'))? arithmetic_primary;
|
||||
arithmetic_primary
|
||||
: state_valued_path_expression
|
||||
: path_expression
|
||||
| numeric_literal
|
||||
| '('arithmetic_expression')'
|
||||
| input_parameter
|
||||
@ -370,7 +347,7 @@ arithmetic_primary
|
||||
| function_invocation
|
||||
| subquery;
|
||||
string_expression
|
||||
: state_valued_path_expression
|
||||
: path_expression
|
||||
| string_literal
|
||||
| input_parameter
|
||||
| functions_returning_strings
|
||||
@ -379,7 +356,7 @@ string_expression
|
||||
| function_invocation
|
||||
| subquery;
|
||||
datetime_expression
|
||||
: state_valued_path_expression
|
||||
: path_expression
|
||||
| input_parameter
|
||||
| functions_returning_datetime
|
||||
| aggregate_expression
|
||||
@ -388,20 +365,20 @@ datetime_expression
|
||||
| date_time_timestamp_literal
|
||||
| subquery;
|
||||
boolean_expression
|
||||
: state_valued_path_expression
|
||||
: path_expression
|
||||
| boolean_literal
|
||||
| input_parameter
|
||||
| case_expression
|
||||
| function_invocation
|
||||
| subquery;
|
||||
enum_expression
|
||||
: state_valued_path_expression
|
||||
: path_expression
|
||||
| enum_literal
|
||||
| input_parameter
|
||||
| case_expression
|
||||
| subquery;
|
||||
entity_expression
|
||||
: single_valued_object_path_expression
|
||||
: path_expression
|
||||
| simple_entity_expression;
|
||||
simple_entity_expression
|
||||
: identification_variable
|
||||
@ -411,14 +388,14 @@ entity_type_expression
|
||||
| entity_type_literal
|
||||
| input_parameter;
|
||||
type_discriminator
|
||||
: 'TYPE'(general_identification_variable | single_valued_object_path_expression | input_parameter);
|
||||
: 'TYPE'(general_identification_variable | path_expression | input_parameter);
|
||||
functions_returning_numerics
|
||||
: 'LENGTH('string_expression')'
|
||||
| 'LOCATE(' string_expression',' string_expression(','arithmetic_expression)?')'
|
||||
| 'ABS('arithmetic_expression')'
|
||||
| 'SQRT('arithmetic_expression')'
|
||||
| 'MOD('arithmetic_expression',' arithmetic_expression')'
|
||||
| 'SIZE('collection_valued_path_expression')'
|
||||
| 'SIZE('path_expression')'
|
||||
| 'INDEX('identification_variable')';
|
||||
functions_returning_datetime
|
||||
: 'CURRENT_DATE'
|
||||
@ -436,7 +413,7 @@ function_invocation
|
||||
: 'FUNCTION('function_name (',' function_arg)* ')';
|
||||
function_arg
|
||||
: literal
|
||||
| state_valued_path_expression
|
||||
| path_expression
|
||||
| input_parameter
|
||||
| scalar_expression;
|
||||
case_expression
|
||||
@ -451,7 +428,7 @@ when_clause
|
||||
simple_case_expression
|
||||
: 'CASE' case_operand simple_when_clause (simple_when_clause)* 'ELSE' scalar_expression 'END';
|
||||
case_operand
|
||||
: state_valued_path_expression
|
||||
: path_expression
|
||||
| type_discriminator;
|
||||
simple_when_clause
|
||||
: 'WHEN' scalar_expression 'THEN' scalar_expression;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@ package com.haulmont.cuba.core.sys.jpql.transform;
|
||||
|
||||
import com.haulmont.cuba.core.global.QueryTransformer;
|
||||
import com.haulmont.cuba.core.sys.jpql.*;
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr.JPALexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr2.JPA2Lexer;
|
||||
import org.antlr.runtime.RecognitionException;
|
||||
import org.antlr.runtime.tree.CommonErrorNode;
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
@ -117,7 +117,7 @@ public class QueryTransformerAstBased implements QueryTransformer {
|
||||
EntityReference ref = inferer.infer(queryAnalyzer);
|
||||
try {
|
||||
CommonTree statementTree = Parser.parse(statement);
|
||||
CommonTree whereClause = (CommonTree) statementTree.getFirstChildWithType(JPALexer.T_CONDITION);
|
||||
CommonTree whereClause = (CommonTree) statementTree.getFirstChildWithType(JPA2Lexer.T_CONDITION);
|
||||
addWhere(whereClause, ref, true);
|
||||
} catch (RecognitionException e) {
|
||||
throw new RuntimeException(e);
|
||||
|
@ -6,7 +6,7 @@
|
||||
package com.haulmont.cuba.core.sys.jpql.transform;
|
||||
|
||||
import com.haulmont.cuba.core.sys.jpql.QueryTreeAnalyzer;
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr.JPALexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr2.JPA2Lexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.*;
|
||||
import org.antlr.runtime.CommonToken;
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
@ -27,9 +27,9 @@ public class QueryTreeTransformer extends QueryTreeAnalyzer {
|
||||
|
||||
|
||||
public void mixinWhereConditionsIntoTree(CommonTree whereTreeToMixIn) {
|
||||
CommonTree whereTreeToMixWithin = (CommonTree) tree.getFirstChildWithType(JPALexer.T_CONDITION);
|
||||
CommonTree whereTreeToMixWithin = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_CONDITION);
|
||||
if (whereTreeToMixWithin == null) {
|
||||
FromNode fromNode = (FromNode) tree.getFirstChildWithType(JPALexer.T_SOURCES);
|
||||
FromNode fromNode = (FromNode) tree.getFirstChildWithType(JPA2Lexer.T_SOURCES);
|
||||
List<Tree> endingNodes = new ArrayList<Tree>();
|
||||
int deletionCount = tree.getChildCount() - (fromNode.getChildIndex() + 1);
|
||||
for (int i = 0; i < deletionCount; i++) {
|
||||
@ -41,7 +41,7 @@ public class QueryTreeTransformer extends QueryTreeAnalyzer {
|
||||
}
|
||||
tree.freshenParentAndChildIndexes();
|
||||
} else {
|
||||
CommonTree and = new CommonTree(new CommonToken(JPALexer.AND, "and"));
|
||||
CommonTree and = new CommonTree(new CommonToken(JPA2Lexer.AND, "and"));
|
||||
whereTreeToMixWithin.addChild(and);
|
||||
for (Object o : whereTreeToMixIn.getChildren()) {
|
||||
CommonTree t = (CommonTree) o;
|
||||
@ -52,7 +52,7 @@ public class QueryTreeTransformer extends QueryTreeAnalyzer {
|
||||
}
|
||||
|
||||
public void mixinJoinIntoTree(CommonTree joinClause, EntityReference entityRef, boolean renameVariable) {
|
||||
CommonTree from = (CommonTree) tree.getFirstChildWithType(JPALexer.T_SOURCES);
|
||||
CommonTree from = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_SOURCES);
|
||||
for (int i = 0; i < from.getChildCount(); i++) {
|
||||
SelectionSourceNode sourceNode = (SelectionSourceNode) from.getChild(i);
|
||||
if (sourceNode.getChild(0) instanceof IdentificationVariableNode) {
|
||||
@ -74,13 +74,13 @@ public class QueryTreeTransformer extends QueryTreeAnalyzer {
|
||||
}
|
||||
|
||||
public void addSelectionSource(CommonTree selectionSource) {
|
||||
CommonTree from = (CommonTree) tree.getFirstChildWithType(JPALexer.T_SOURCES);
|
||||
CommonTree from = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_SOURCES);
|
||||
from.addChild(selectionSource);
|
||||
from.freshenParentAndChildIndexes();
|
||||
}
|
||||
|
||||
public void replaceWithCount(EntityReference entityRef) {
|
||||
Tree selectedItems = tree.getFirstChildWithType(JPALexer.T_SELECTED_ITEMS);
|
||||
Tree selectedItems = tree.getFirstChildWithType(JPA2Lexer.T_SELECTED_ITEMS);
|
||||
boolean isDistinct = "DISTINCT".equalsIgnoreCase(selectedItems.getChild(0).getText());
|
||||
if (!(isDistinct && selectedItems.getChildCount() == 2 ||
|
||||
selectedItems.getChildCount() == 1))
|
||||
@ -95,7 +95,7 @@ public class QueryTreeTransformer extends QueryTreeAnalyzer {
|
||||
selectedItemNode.deleteChild(0);
|
||||
selectedItemNode.addChild(countNode);
|
||||
|
||||
Tree orderBy = tree.getFirstChildWithType(JPALexer.T_ORDER_BY);
|
||||
Tree orderBy = tree.getFirstChildWithType(JPA2Lexer.T_ORDER_BY);
|
||||
if (orderBy != null) {
|
||||
tree.deleteChild(orderBy.getChildIndex());
|
||||
}
|
||||
@ -103,18 +103,18 @@ public class QueryTreeTransformer extends QueryTreeAnalyzer {
|
||||
}
|
||||
|
||||
public void replaceOrderBy(PathEntityReference orderingFieldRef, boolean desc) {
|
||||
CommonTree orderBy = (CommonTree) tree.getFirstChildWithType(JPALexer.T_ORDER_BY);
|
||||
CommonTree orderBy = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_ORDER_BY);
|
||||
OrderByFieldNode orderByField;
|
||||
if (orderBy == null) {
|
||||
orderByField = new OrderByFieldNode(JPALexer.T_ORDER_BY_FIELD);
|
||||
orderByField = new OrderByFieldNode(JPA2Lexer.T_ORDER_BY_FIELD);
|
||||
|
||||
orderBy = new OrderByNode(JPALexer.T_ORDER_BY);
|
||||
orderBy.addChild(new CommonTree(new CommonToken(JPALexer.ORDER, "order")));
|
||||
orderBy.addChild(new CommonTree(new CommonToken(JPALexer.BY, "by")));
|
||||
orderBy = new OrderByNode(JPA2Lexer.T_ORDER_BY);
|
||||
orderBy.addChild(new CommonTree(new CommonToken(JPA2Lexer.ORDER, "order")));
|
||||
orderBy.addChild(new CommonTree(new CommonToken(JPA2Lexer.BY, "by")));
|
||||
orderBy.addChild(orderByField);
|
||||
tree.addChild(orderBy);
|
||||
} else {
|
||||
orderByField = (OrderByFieldNode) orderBy.getFirstChildWithType(JPALexer.T_ORDER_BY_FIELD);
|
||||
orderByField = (OrderByFieldNode) orderBy.getFirstChildWithType(JPA2Lexer.T_ORDER_BY_FIELD);
|
||||
if (orderByField == null)
|
||||
throw new IllegalStateException("No ordering field found");
|
||||
|
||||
@ -130,35 +130,35 @@ public class QueryTreeTransformer extends QueryTreeAnalyzer {
|
||||
CommonTree lastNode = (CommonTree) pathNode.deleteChild(pathNode.getChildCount() - 1);
|
||||
String variableName = pathNode.asPathString('_');
|
||||
|
||||
PathNode orderingNode = new PathNode(JPALexer.T_SELECTED_FIELD, variableName);
|
||||
PathNode orderingNode = new PathNode(JPA2Lexer.T_SELECTED_FIELD, variableName);
|
||||
orderingNode.addDefaultChild(lastNode.getText());
|
||||
orderByField.addChild(orderingNode);
|
||||
|
||||
JoinVariableNode joinNode = new JoinVariableNode(JPALexer.T_JOIN_VAR, "left join", variableName);
|
||||
JoinVariableNode joinNode = new JoinVariableNode(JPA2Lexer.T_JOIN_VAR, "left join", variableName);
|
||||
joinNode.addChild(pathNode);
|
||||
|
||||
CommonTree from = (CommonTree) tree.getFirstChildWithType(JPALexer.T_SOURCES);
|
||||
CommonTree from = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_SOURCES);
|
||||
from.getChild(0).addChild(joinNode); // assumption
|
||||
} else {
|
||||
orderByField.addChild(orderingFieldRef.createNode());
|
||||
}
|
||||
|
||||
if (desc) {
|
||||
orderByField.addChild(new CommonTree(new CommonToken(JPALexer.DESC, "DESC")));
|
||||
orderByField.addChild(new CommonTree(new CommonToken(JPA2Lexer.DESC, "DESC")));
|
||||
}
|
||||
orderByField.freshenParentAndChildIndexes();
|
||||
}
|
||||
|
||||
private AggregateExpressionNode createCountNode(EntityReference ref, boolean distinct) {
|
||||
AggregateExpressionNode result = new AggregateExpressionNode(JPALexer.T_AGGREGATE_EXPR);
|
||||
AggregateExpressionNode result = new AggregateExpressionNode(JPA2Lexer.T_AGGREGATE_EXPR);
|
||||
|
||||
result.addChild(new CommonTree(new CommonToken(JPALexer.COUNT, "COUNT")));
|
||||
result.addChild(new CommonTree(new CommonToken(JPALexer.LPAREN, "(")));
|
||||
result.addChild(new CommonTree(new CommonToken(JPA2Lexer.COUNT, "COUNT")));
|
||||
result.addChild(new CommonTree(new CommonToken(JPA2Lexer.LPAREN, "(")));
|
||||
if (distinct) {
|
||||
result.addChild(new CommonTree(new CommonToken(JPALexer.DISTINCT, "DISTINCT")));
|
||||
result.addChild(new CommonTree(new CommonToken(JPA2Lexer.DISTINCT, "DISTINCT")));
|
||||
}
|
||||
result.addChild(ref.createNode());
|
||||
result.addChild(new CommonTree(new CommonToken(JPALexer.RPAREN, ")")));
|
||||
result.addChild(new CommonTree(new CommonToken(JPA2Lexer.RPAREN, ")")));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
package com.haulmont.cuba.core.sys.jpql.transform;
|
||||
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr.JPALexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr2.JPA2Lexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.IdentificationVariableNode;
|
||||
import com.haulmont.cuba.core.sys.jpql.tree.PathNode;
|
||||
import org.antlr.runtime.CommonToken;
|
||||
@ -35,7 +35,7 @@ public class VariableEntityReference implements EntityReference {
|
||||
}
|
||||
|
||||
public Tree createNode() {
|
||||
return new CommonTree(new CommonToken(JPALexer.WORD, entityVariableName));
|
||||
return new CommonTree(new CommonToken(JPA2Lexer.WORD, entityVariableName));
|
||||
}
|
||||
|
||||
public boolean isJoinableTo(IdentificationVariableNode node) {
|
||||
@ -44,7 +44,7 @@ public class VariableEntityReference implements EntityReference {
|
||||
|
||||
|
||||
public PathEntityReference addFieldPath(String fieldPath) {
|
||||
PathNode pathNode = new PathNode(JPALexer.T_SELECTED_FIELD, entityVariableName);
|
||||
PathNode pathNode = new PathNode(JPA2Lexer.T_SELECTED_FIELD, entityVariableName);
|
||||
pathNode.addDefaultChildren(fieldPath);
|
||||
return new PathEntityReference(pathNode, entityName);
|
||||
}
|
||||
|
@ -5,14 +5,10 @@
|
||||
|
||||
package com.haulmont.cuba.core.sys.jpql.tree;
|
||||
|
||||
import com.haulmont.cuba.core.sys.jpql.ErrorRec;
|
||||
import org.antlr.runtime.CommonToken;
|
||||
import org.antlr.runtime.Token;
|
||||
import org.antlr.runtime.tree.CommonTree;
|
||||
import org.antlr.runtime.tree.Tree;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Author: Alexander Chevelev
|
||||
* Date: 30.10.2010
|
||||
|
@ -6,7 +6,7 @@
|
||||
package com.haulmont.cuba.core.sys.jpql.tree;
|
||||
|
||||
import com.haulmont.cuba.core.sys.jpql.*;
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr.JPALexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr2.JPA2Lexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.pointer.Pointer;
|
||||
import org.antlr.runtime.CommonToken;
|
||||
import org.antlr.runtime.Token;
|
||||
@ -93,11 +93,11 @@ public class PathNode extends BaseCustomNode {
|
||||
public void addDefaultChildren(String fieldPath) {
|
||||
String[] strings = fieldPath.split("\\.");
|
||||
for (String string : strings) {
|
||||
addChild(new CommonTree(new CommonToken(JPALexer.WORD, string)));
|
||||
addChild(new CommonTree(new CommonToken(JPA2Lexer.WORD, string)));
|
||||
}
|
||||
}
|
||||
|
||||
public void addDefaultChild(String field) {
|
||||
addChild(new CommonTree(new CommonToken(JPALexer.WORD, field)));
|
||||
addChild(new CommonTree(new CommonToken(JPA2Lexer.WORD, field)));
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2015 Haulmont. All rights reserved.
|
||||
* Use is subject to license terms, see http://www.cuba-platform.com/license for details.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.core.sys.jpql;
|
||||
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr2.*;
|
||||
import org.antlr.runtime.CharStream;
|
||||
import org.antlr.runtime.CommonTokenStream;
|
||||
import org.antlr.runtime.TokenStream;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author degtyarjov
|
||||
* @version $Id$
|
||||
*/
|
||||
public class Jpa2GrammarTest {
|
||||
|
||||
@Test
|
||||
public void testParser() throws Exception {
|
||||
CharStream cs = new AntlrNoCaseStringStream(
|
||||
"select u.login " +
|
||||
"from sec$User u " +
|
||||
"where u.login = 'admin' " +
|
||||
"group by u.login having u.version > 0" +
|
||||
"order by u.login");
|
||||
JPA2Lexer lexer = new JPA2Lexer(cs);
|
||||
TokenStream tstream = new CommonTokenStream(lexer);
|
||||
JPA2Parser jpa2Parser = new JPA2Parser(tstream);
|
||||
JPA2Parser.ql_statement_return aReturn = jpa2Parser.ql_statement();
|
||||
System.out.println();
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ package com.haulmont.cuba.gui.autocomplete.impl;
|
||||
|
||||
import com.haulmont.cuba.core.sys.jpql.DomainModel;
|
||||
import com.haulmont.cuba.core.sys.jpql.Parser;
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr.JPALexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.antlr2.JPA2Lexer;
|
||||
import com.haulmont.cuba.core.sys.jpql.model.Entity;
|
||||
import com.haulmont.cuba.core.sys.jpql.model.EntityBuilder;
|
||||
import com.haulmont.cuba.core.sys.jpql.transform.PathEntityReference;
|
||||
@ -32,12 +32,12 @@ public class QueryAnalyzerTest {
|
||||
DomainModel model = prepareDomainModel();
|
||||
|
||||
QueryTreeTransformer qa = new QueryTreeTransformer();
|
||||
qa.prepare(model, "select f from sec$SearchFolder f " +
|
||||
String query = "select f from sec$SearchFolder f " +
|
||||
"left join f.user u " +
|
||||
"left join f.presentation p " +
|
||||
"where (f.user.id = ?1 or f.user is null) " +
|
||||
"order by f.sortOrder, f.name");
|
||||
System.out.println("");
|
||||
"order by f.sortOrder, f.name";
|
||||
qa.prepare(model, query);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -48,17 +48,17 @@ public class QueryAnalyzerTest {
|
||||
qa.prepare(model, "select c from Car c");
|
||||
|
||||
CommonTree tree = qa.getTree();
|
||||
CommonTree sources = (CommonTree) tree.getFirstChildWithType(JPALexer.T_SOURCES);
|
||||
CommonTree sources = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_SOURCES);
|
||||
assertEquals(1, sources.getChildCount());
|
||||
assertTrue(sources.getChild(0) instanceof SelectionSourceNode);
|
||||
CommonTree source = (CommonTree) sources.getFirstChildWithType(JPALexer.T_SOURCE);
|
||||
CommonTree source = (CommonTree) sources.getFirstChildWithType(JPA2Lexer.T_SOURCE);
|
||||
assertTrue(source.getChild(0) instanceof IdentificationVariableNode);
|
||||
|
||||
JoinVariableNode join = (JoinVariableNode) Parser.parseJoinClause("join a.drivers d");
|
||||
qa.mixinJoinIntoTree(join, new VariableEntityReference("Car", "c"), true);
|
||||
|
||||
tree = qa.getTree();
|
||||
sources = (CommonTree) tree.getFirstChildWithType(JPALexer.T_SOURCES);
|
||||
sources = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_SOURCES);
|
||||
assertEquals(1, sources.getChildCount());
|
||||
SelectionSourceNode sourceNode = (SelectionSourceNode) sources.getChild(0);
|
||||
assertEquals(2, sourceNode.getChildCount());
|
||||
@ -95,7 +95,7 @@ public class QueryAnalyzerTest {
|
||||
qa.prepare(model, "select d.name from Car c, in(c.drivers) d");
|
||||
|
||||
CommonTree tree = qa.getTree();
|
||||
CommonTree sources = (CommonTree) tree.getFirstChildWithType(JPALexer.T_SOURCES);
|
||||
CommonTree sources = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_SOURCES);
|
||||
assertEquals(2, sources.getChildCount());
|
||||
|
||||
assertTrue(sources.getChild(0) instanceof SelectionSourceNode);
|
||||
@ -110,7 +110,7 @@ public class QueryAnalyzerTest {
|
||||
qa.mixinJoinIntoTree(join, new VariableEntityReference("Car", "c"), true);
|
||||
|
||||
tree = qa.getTree();
|
||||
sources = (CommonTree) tree.getFirstChildWithType(JPALexer.T_SOURCES);
|
||||
sources = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_SOURCES);
|
||||
assertEquals(2, sources.getChildCount());
|
||||
assertTrue(sources.getChild(0) instanceof SelectionSourceNode);
|
||||
source0 = (CommonTree) sources.getChild(0);
|
||||
@ -134,12 +134,12 @@ public class QueryAnalyzerTest {
|
||||
WhereNode where = (WhereNode) Parser.parseWhereClause("where c.model = ?1");
|
||||
|
||||
CommonTree tree = qa.getTree();
|
||||
assertNull(tree.getFirstChildWithType(JPALexer.T_CONDITION));
|
||||
assertNull(tree.getFirstChildWithType(JPA2Lexer.T_CONDITION));
|
||||
|
||||
qa.mixinWhereConditionsIntoTree(where);
|
||||
|
||||
tree = qa.getTree();
|
||||
assertNotNull(tree.getFirstChildWithType(JPALexer.T_CONDITION));
|
||||
assertNotNull(tree.getFirstChildWithType(JPA2Lexer.T_CONDITION));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -150,14 +150,14 @@ public class QueryAnalyzerTest {
|
||||
qa.prepare(model, "select c from Car c order by c.model");
|
||||
|
||||
CommonTree tree = qa.getTree();
|
||||
CommonTree orderByNode = (CommonTree) tree.getFirstChildWithType(JPALexer.T_ORDER_BY);
|
||||
Tree orderByField = orderByNode.getFirstChildWithType(JPALexer.T_ORDER_BY_FIELD);
|
||||
CommonTree orderByNode = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_ORDER_BY);
|
||||
Tree orderByField = orderByNode.getFirstChildWithType(JPA2Lexer.T_ORDER_BY_FIELD);
|
||||
assertEquals(1, orderByField.getChildCount());
|
||||
PathNode pathNode = (PathNode) orderByField.getChild(0);
|
||||
assertEquals("c", pathNode.getEntityVariableName());
|
||||
assertEquals("model", pathNode.getChild(0).getText());
|
||||
|
||||
pathNode = new PathNode(JPALexer.T_SELECTED_FIELD, "c");
|
||||
pathNode = new PathNode(JPA2Lexer.T_SELECTED_FIELD, "c");
|
||||
pathNode.addDefaultChild("regNumber");
|
||||
qa.replaceOrderBy(new PathEntityReference(pathNode, "Car"), true);
|
||||
|
||||
@ -176,14 +176,14 @@ public class QueryAnalyzerTest {
|
||||
qa.prepare(model, "select c from Car c order by c.model");
|
||||
|
||||
CommonTree tree = qa.getTree();
|
||||
CommonTree selectedItems = (CommonTree) tree.getFirstChildWithType(JPALexer.T_SELECTED_ITEMS);
|
||||
Tree selectedItem = selectedItems.getFirstChildWithType(JPALexer.T_SELECTED_ITEM);
|
||||
CommonTree selectedItems = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_SELECTED_ITEMS);
|
||||
Tree selectedItem = selectedItems.getFirstChildWithType(JPA2Lexer.T_SELECTED_ITEM);
|
||||
PathNode pathNode = (PathNode) selectedItem.getChild(0);
|
||||
assertEquals("c", pathNode.getEntityVariableName());
|
||||
assertEquals(0, pathNode.getChildCount());
|
||||
CommonTree orderByNode = (CommonTree) tree.getFirstChildWithType(JPALexer.T_ORDER_BY);
|
||||
CommonTree orderByNode = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_ORDER_BY);
|
||||
|
||||
assertNotNull(orderByNode.getFirstChildWithType(JPALexer.T_ORDER_BY_FIELD));
|
||||
assertNotNull(orderByNode.getFirstChildWithType(JPA2Lexer.T_ORDER_BY_FIELD));
|
||||
|
||||
qa.replaceWithCount(new VariableEntityReference("Car", "c"));
|
||||
|
||||
@ -193,7 +193,7 @@ public class QueryAnalyzerTest {
|
||||
assertEquals("COUNT", countExpr.getChild(0).getText());
|
||||
assertEquals("c", countExpr.getChild(2).getText());
|
||||
assertEquals(4, countExpr.getChildCount());
|
||||
assertNull(orderByNode.getFirstChildWithType(JPALexer.T_ORDER_BY));
|
||||
assertNull(orderByNode.getFirstChildWithType(JPA2Lexer.T_ORDER_BY));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -204,20 +204,20 @@ public class QueryAnalyzerTest {
|
||||
qa.prepare(model, "select distinct d from Car c, in(c.drivers) d order by d.name");
|
||||
|
||||
CommonTree tree = qa.getTree();
|
||||
CommonTree selectedItems = (CommonTree) tree.getFirstChildWithType(JPALexer.T_SELECTED_ITEMS);
|
||||
Tree selectedItem = selectedItems.getFirstChildWithType(JPALexer.T_SELECTED_ITEM);
|
||||
CommonTree selectedItems = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_SELECTED_ITEMS);
|
||||
Tree selectedItem = selectedItems.getFirstChildWithType(JPA2Lexer.T_SELECTED_ITEM);
|
||||
PathNode pathNode = (PathNode) selectedItem.getChild(0);
|
||||
assertEquals("d", pathNode.getEntityVariableName());
|
||||
assertEquals(0, pathNode.getChildCount());
|
||||
CommonTree orderByNode = (CommonTree) tree.getFirstChildWithType(JPALexer.T_ORDER_BY);
|
||||
CommonTree orderByNode = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_ORDER_BY);
|
||||
|
||||
assertNotNull(orderByNode.getFirstChildWithType(JPALexer.T_ORDER_BY_FIELD));
|
||||
assertNotNull(orderByNode.getFirstChildWithType(JPA2Lexer.T_ORDER_BY_FIELD));
|
||||
|
||||
qa.replaceWithCount(new VariableEntityReference("Driver", "d"));
|
||||
|
||||
selectedItems = (CommonTree) tree.getFirstChildWithType(JPALexer.T_SELECTED_ITEMS);
|
||||
selectedItems = (CommonTree) tree.getFirstChildWithType(JPA2Lexer.T_SELECTED_ITEMS);
|
||||
assertEquals(1, selectedItems.getChildCount());
|
||||
selectedItem = selectedItems.getFirstChildWithType(JPALexer.T_SELECTED_ITEM);
|
||||
selectedItem = selectedItems.getFirstChildWithType(JPA2Lexer.T_SELECTED_ITEM);
|
||||
assertTrue(selectedItem.getChild(0) instanceof AggregateExpressionNode);
|
||||
AggregateExpressionNode countExpr = (AggregateExpressionNode) selectedItem.getChild(0);
|
||||
|
||||
@ -225,7 +225,7 @@ public class QueryAnalyzerTest {
|
||||
assertEquals("DISTINCT", countExpr.getChild(2).getText());
|
||||
assertEquals("d", countExpr.getChild(3).getText());
|
||||
assertEquals(5, countExpr.getChildCount());
|
||||
assertNull(orderByNode.getFirstChildWithType(JPALexer.T_ORDER_BY));
|
||||
assertNull(orderByNode.getFirstChildWithType(JPA2Lexer.T_ORDER_BY));
|
||||
}
|
||||
|
||||
private DomainModel prepareDomainModel() {
|
||||
|
@ -133,7 +133,6 @@ public class QueryTransformerAstBasedTest {
|
||||
|
||||
QueryTransformerAstBased transformerAstBased = new QueryTransformerAstBased(model, "SELECT p FROM Player p left join p.team as t WHERE t.name = 'KS FC'", "Player");
|
||||
String result = transformerAstBased.getResult();
|
||||
System.out.println(result);
|
||||
assertEquals("SELECT p FROM Player p left join p.team t WHERE t.name = 'KS FC'", result);
|
||||
}
|
||||
|
||||
@ -238,8 +237,48 @@ public class QueryTransformerAstBasedTest {
|
||||
assertTransformsToSame(model, "select distinct m from Player p left join p.team.manager m");
|
||||
}
|
||||
|
||||
// The following functions are not supported by JPA2 JPQL (see jpql21.bnf)
|
||||
// @Test
|
||||
// public void getResult_noChangesMade_withSubqueries() throws RecognitionException {
|
||||
// EntityBuilder builder = new EntityBuilder();
|
||||
// Entity teamEntity = builder.produceImmediately("Team", "name", "owner");
|
||||
//
|
||||
// builder.startNewEntity("Player");
|
||||
// builder.addStringAttribute("name");
|
||||
// builder.addStringAttribute("nickname");
|
||||
// builder.addReferenceAttribute("team", "Team");
|
||||
// Entity playerEntity = builder.produce();
|
||||
//
|
||||
// DomainModel model = new DomainModel(playerEntity, teamEntity);
|
||||
//
|
||||
// assertTransformsToSame(model, "select p.name from (select t.name from Team t) p");
|
||||
// assertTransformsToSame(model, "select p.owner from (select t.name, t.owner from Team t) p");
|
||||
// assertTransformsToSame(model, "select g.owner from (select t.name, t.owner from Team t) p, (select t.name from Team t) g");
|
||||
// }
|
||||
|
||||
// The following functions are not supported by JPA2 JPQL (see jpql21.bnf)
|
||||
// @Test
|
||||
// public void getResult_noChangesMade_severalLevelsOfSubquery() throws RecognitionException {
|
||||
// EntityBuilder builder = new EntityBuilder();
|
||||
// Entity teamEntity = builder.produceImmediately("Team", "name", "owner");
|
||||
//
|
||||
// builder.startNewEntity("Player");
|
||||
// builder.addStringAttribute("name");
|
||||
// builder.addStringAttribute("nickname");
|
||||
// builder.addReferenceAttribute("team", "Team");
|
||||
// Entity playerEntity = builder.produce();
|
||||
//
|
||||
// DomainModel model = new DomainModel(playerEntity, teamEntity);
|
||||
//
|
||||
// assertTransformsToSame(model, "select p.owner from (select t from Team t where t.name in (select a.name from Player a)) p");
|
||||
// // 'as' опускается
|
||||
// QueryTransformerAstBased transformerAstBased = new QueryTransformerAstBased(model, "select p.owner from (select t.owner from Team as t where t.name = '1') p", "AsdfAsdfAsdf");
|
||||
// String result = transformerAstBased.getResult();
|
||||
// assertEquals("select p.owner from (select t.owner from Team t where t.name = '1') p", result);
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void getResult_noChangesMade_withSubqueries() throws RecognitionException {
|
||||
public void getResult_noChangesMade_subqueries() throws RecognitionException {
|
||||
EntityBuilder builder = new EntityBuilder();
|
||||
Entity teamEntity = builder.produceImmediately("Team", "name", "owner");
|
||||
|
||||
@ -251,29 +290,9 @@ public class QueryTransformerAstBasedTest {
|
||||
|
||||
DomainModel model = new DomainModel(playerEntity, teamEntity);
|
||||
|
||||
assertTransformsToSame(model, "select p.name from (select t.name from Team t) p");
|
||||
assertTransformsToSame(model, "select p.owner from (select t.name, t.owner from Team t) p");
|
||||
assertTransformsToSame(model, "select g.owner from (select t.name, t.owner from Team t) p, (select t.name from Team t) g");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getResult_noChangesMade_severalLevelsOfSubquery() throws RecognitionException {
|
||||
EntityBuilder builder = new EntityBuilder();
|
||||
Entity teamEntity = builder.produceImmediately("Team", "name", "owner");
|
||||
|
||||
builder.startNewEntity("Player");
|
||||
builder.addStringAttribute("name");
|
||||
builder.addStringAttribute("nickname");
|
||||
builder.addReferenceAttribute("team", "Team");
|
||||
Entity playerEntity = builder.produce();
|
||||
|
||||
DomainModel model = new DomainModel(playerEntity, teamEntity);
|
||||
|
||||
assertTransformsToSame(model, "select p.owner from (select t from Team t where t.name in (select a.name from Player a)) p");
|
||||
// 'as' опускается
|
||||
QueryTransformerAstBased transformerAstBased = new QueryTransformerAstBased(model, "select p.owner from (select t.owner from Team as t where t.name = '1') p", "AsdfAsdfAsdf");
|
||||
String result = transformerAstBased.getResult();
|
||||
assertEquals("select p.owner from (select t.owner from Team t where t.name = '1') p", result);
|
||||
assertTransformsToSame(model, "select p.owner from Player pl where exists (select t from Team t where t.name = 'Team1' and pl.team.id = t.id)");
|
||||
assertTransformsToSame(model, "select p.owner from Player pl where pl.team.id in (select t.id from Team t where t.name = 'Team1')");
|
||||
assertTransformsToSame(model, "select t.name from Team t where (select count(p) from Player p where p.team.id = t.id) > 10");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user