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:
Catalina Wei 2009-03-17 03:13:10 +00:00
parent 6b40e72683
commit 7c9ef84fb9
6 changed files with 45 additions and 3 deletions

View File

@ -83,6 +83,7 @@ public class PCPath
private Class _cast = null;
private boolean _cid = false;
private FieldMetaData _xmlfield = null;
private FieldMetaData _mapfield = null;
/**
* Return a path starting with the 'this' ptr.
@ -361,6 +362,7 @@ public class PCPath
if (_cid)
return;
_mapfield = last();
// change the last action to a get key
Action action = (Action) _actions.getLast();
action.op = Action.GET_KEY;
@ -402,7 +404,8 @@ public class PCPath
if (act != null && act.op == Action.GET_XPATH)
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;
boolean key = act != null && act.op == Action.GET_KEY;
if (fld != null) {

View File

@ -970,6 +970,8 @@ public class JPQLExpressionBuilder
case JJTGENERALIDENTIFIER:
// KEY(e), VALUE(e)
if (node.parent.parent.id == JJTWHERE)
return getGeneralIdentifier(onlyChild(node), true);
return getQualifiedIdentifier(onlyChild(node));
case JJTNOT:
@ -1458,6 +1460,24 @@ public class JPQLExpressionBuilder
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) {
JPQLNode id = onlyChild(node);
Path path = (Path) validateMapPath(node, id);

View File

@ -944,6 +944,7 @@ void arithmetic_factor() : { }
input_parameter() |
LOOKAHEAD(path()) path() |
LOOKAHEAD(qualified_path()) qualified_path() |
LOOKAHEAD(general_identification_variable()) general_identification_variable() |
LOOKAHEAD(2) "(" arithmetic_expression() ")" |
functions_returning_numerics() |
aggregate_select_expression() |
@ -1078,7 +1079,9 @@ void string_expression() : { }
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() ")"
| case_expression()
}
@ -1093,6 +1096,7 @@ void datetime_expression() : { }
void datetime_primary() : { }
{
path() | functions_returning_datetime() | input_parameter() | aggregate_select_expression()
| LOOKAHEAD(general_identification_variable()) general_identification_variable()
| case_expression()
}

View File

@ -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 \
referring to an association field of type java.util.Map.
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.

View File

@ -88,6 +88,13 @@ public class TestMany2ManyMapEx8 extends SingleEMFTestCase {
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();
}

View File

@ -73,6 +73,13 @@ public class TestSpec10_1_26_Ex1 extends SingleEMFTestCase {
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();
}