mirror of https://github.com/apache/openjpa.git
OPENJPA-967 JPA2 JPQL allow KEY(e) of basic types appear in conditional expression
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@755102 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6b40e72683
commit
7c9ef84fb9
|
@ -83,6 +83,7 @@ public class PCPath
|
||||||
private Class _cast = null;
|
private Class _cast = null;
|
||||||
private boolean _cid = false;
|
private boolean _cid = false;
|
||||||
private FieldMetaData _xmlfield = null;
|
private FieldMetaData _xmlfield = null;
|
||||||
|
private FieldMetaData _mapfield = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a path starting with the 'this' ptr.
|
* Return a path starting with the 'this' ptr.
|
||||||
|
@ -361,6 +362,7 @@ public class PCPath
|
||||||
if (_cid)
|
if (_cid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
_mapfield = last();
|
||||||
// change the last action to a get key
|
// change the last action to a get key
|
||||||
Action action = (Action) _actions.getLast();
|
Action action = (Action) _actions.getLast();
|
||||||
action.op = Action.GET_KEY;
|
action.op = Action.GET_KEY;
|
||||||
|
@ -402,7 +404,8 @@ public class PCPath
|
||||||
if (act != null && act.op == Action.GET_XPATH)
|
if (act != null && act.op == Action.GET_XPATH)
|
||||||
return ((XMLMetaData) act.data).getType();
|
return ((XMLMetaData) act.data).getType();
|
||||||
|
|
||||||
FieldMetaData fld = (act == null || act.op == Action.GET_KEY) ? null :
|
FieldMetaData fld = act == null ? null :
|
||||||
|
act.op == Action.GET_KEY ? _mapfield :
|
||||||
(FieldMetaData) act.data;
|
(FieldMetaData) act.data;
|
||||||
boolean key = act != null && act.op == Action.GET_KEY;
|
boolean key = act != null && act.op == Action.GET_KEY;
|
||||||
if (fld != null) {
|
if (fld != null) {
|
||||||
|
|
|
@ -970,6 +970,8 @@ public class JPQLExpressionBuilder
|
||||||
|
|
||||||
case JJTGENERALIDENTIFIER:
|
case JJTGENERALIDENTIFIER:
|
||||||
// KEY(e), VALUE(e)
|
// KEY(e), VALUE(e)
|
||||||
|
if (node.parent.parent.id == JJTWHERE)
|
||||||
|
return getGeneralIdentifier(onlyChild(node), true);
|
||||||
return getQualifiedIdentifier(onlyChild(node));
|
return getQualifiedIdentifier(onlyChild(node));
|
||||||
|
|
||||||
case JJTNOT:
|
case JJTNOT:
|
||||||
|
@ -1458,6 +1460,24 @@ public class JPQLExpressionBuilder
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Value getGeneralIdentifier(JPQLNode node, boolean inWhereClause) {
|
||||||
|
JPQLNode id = onlyChild(node);
|
||||||
|
if (inWhereClause && node.id == JJTVALUE)
|
||||||
|
throw parseException(EX_USER, "bad-general-identifier",
|
||||||
|
new Object[]{ id.text, "VALUE" }, null);
|
||||||
|
|
||||||
|
Path path = (Path) validateMapPath(node, id);
|
||||||
|
FieldMetaData fld = path.last();
|
||||||
|
path = (Path) factory.getKey(path);
|
||||||
|
ClassMetaData meta = fld.getKey().getTypeMetaData();
|
||||||
|
if (inWhereClause && meta != null)
|
||||||
|
// check basic type
|
||||||
|
throw parseException(EX_USER, "bad-general-identifier",
|
||||||
|
new Object[]{ id.text, "KEY" }, null);
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
private Value getQualifiedIdentifier(JPQLNode node) {
|
private Value getQualifiedIdentifier(JPQLNode node) {
|
||||||
JPQLNode id = onlyChild(node);
|
JPQLNode id = onlyChild(node);
|
||||||
Path path = (Path) validateMapPath(node, id);
|
Path path = (Path) validateMapPath(node, id);
|
||||||
|
|
|
@ -944,6 +944,7 @@ void arithmetic_factor() : { }
|
||||||
input_parameter() |
|
input_parameter() |
|
||||||
LOOKAHEAD(path()) path() |
|
LOOKAHEAD(path()) path() |
|
||||||
LOOKAHEAD(qualified_path()) qualified_path() |
|
LOOKAHEAD(qualified_path()) qualified_path() |
|
||||||
|
LOOKAHEAD(general_identification_variable()) general_identification_variable() |
|
||||||
LOOKAHEAD(2) "(" arithmetic_expression() ")" |
|
LOOKAHEAD(2) "(" arithmetic_expression() ")" |
|
||||||
functions_returning_numerics() |
|
functions_returning_numerics() |
|
||||||
aggregate_select_expression() |
|
aggregate_select_expression() |
|
||||||
|
@ -1078,7 +1079,9 @@ void string_expression() : { }
|
||||||
|
|
||||||
void string_primary() : { }
|
void string_primary() : { }
|
||||||
{
|
{
|
||||||
string_literal() | path() | LOOKAHEAD(2) "(" string_expression() ")" |
|
string_literal() | path() |
|
||||||
|
LOOKAHEAD(general_identification_variable()) general_identification_variable() |
|
||||||
|
LOOKAHEAD(2) "(" string_expression() ")" |
|
||||||
functions_returning_strings() | LOOKAHEAD(2) "(" subquery() ")"
|
functions_returning_strings() | LOOKAHEAD(2) "(" subquery() ")"
|
||||||
| case_expression()
|
| case_expression()
|
||||||
}
|
}
|
||||||
|
@ -1093,6 +1096,7 @@ void datetime_expression() : { }
|
||||||
void datetime_primary() : { }
|
void datetime_primary() : { }
|
||||||
{
|
{
|
||||||
path() | functions_returning_datetime() | input_parameter() | aggregate_select_expression()
|
path() | functions_returning_datetime() | input_parameter() | aggregate_select_expression()
|
||||||
|
| LOOKAHEAD(general_identification_variable()) general_identification_variable()
|
||||||
| case_expression()
|
| case_expression()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,4 +76,5 @@ not-type-literal: The specified node ("{0}") is not a valid entity type literal.
|
||||||
bad-qualified-identifier: The identifier "{0}" in "{1}" operator is not \
|
bad-qualified-identifier: The identifier "{0}" in "{1}" operator is not \
|
||||||
referring to an association field of type java.util.Map.
|
referring to an association field of type java.util.Map.
|
||||||
bad-qualified-path: Attemp to navigate a basic type of Key("{0}").
|
bad-qualified-path: Attemp to navigate a basic type of Key("{0}").
|
||||||
|
bad-general-identifier: The identitier "{0}" in "{1}" operator is not valid \
|
||||||
|
in conditional expression.
|
|
@ -88,6 +88,13 @@ public class TestMany2ManyMapEx8 extends SingleEMFTestCase {
|
||||||
|
|
||||||
assertTrue(d.equals(me.getKey()));
|
assertTrue(d.equals(me.getKey()));
|
||||||
|
|
||||||
|
// test KEY(e) of basic type in conditional expression
|
||||||
|
sql.clear();
|
||||||
|
query = "select KEY(e) from PhoneNumber p, " +
|
||||||
|
" in (p.emps) e where KEY(e) like '%1'";
|
||||||
|
rs = em.createQuery(query).getResultList();
|
||||||
|
assertTrue(sql.get(0).toUpperCase().indexOf("LIKE") > 0);
|
||||||
|
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,13 @@ public class TestSpec10_1_26_Ex1 extends SingleEMFTestCase {
|
||||||
|
|
||||||
assertTrue(d.equals(me.getKey()));
|
assertTrue(d.equals(me.getKey()));
|
||||||
|
|
||||||
|
// test KEY(e) of basic type in conditional expression
|
||||||
|
sql.clear();
|
||||||
|
query = "select KEY(e) from Department d, " +
|
||||||
|
" in (d.empMap) e where KEY(e) > 1";
|
||||||
|
rs = em.createQuery(query).getResultList();
|
||||||
|
assertTrue(sql.get(0).toUpperCase().indexOf(">") > 0);
|
||||||
|
|
||||||
em.close();
|
em.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue