OPENJPA-1064 JPA2 Query add support for embeddable of element collection in predicate and subquery

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@772015 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Catalina Wei 2009-05-06 00:03:09 +00:00
parent 0392538775
commit ed82fda48c
4 changed files with 87 additions and 13 deletions

View File

@ -62,7 +62,7 @@ class EqualExpression
new FilterValueImpl(sel, ctx, bstate.state1, val1), new FilterValueImpl(sel, ctx, bstate.state1, val1),
new FilterValueImpl(sel, ctx, bstate.state2, val2)); new FilterValueImpl(sel, ctx, bstate.state2, val2));
} else { } else {
int len = java.lang.Math.max(val1.length(sel, ctx, int len = java.lang.Math.min(val1.length(sel, ctx,
bstate.state1), val2.length(sel, ctx, bstate.state2)); bstate.state1), val2.length(sel, ctx, bstate.state2));
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (i > 0) if (i > 0)

View File

@ -460,17 +460,19 @@ public class JPQLExpressionBuilder
// schema's alias, then do not treat it as a projection // schema's alias, then do not treat it as a projection
if (selectCount == 1 && selectChild != null && if (selectCount == 1 && selectChild != null &&
selectChild.getChildCount() == 1 && selectChild.getChildCount() == 1 &&
onlyChild(selectChild) != null && onlyChild(selectChild) != null) {
assertSchemaAlias(). JPQLNode child = onlyChild(selectChild);
equalsIgnoreCase(onlyChild(selectChild).text)) { if (child.id == JJTSCALAREXPRESSION)
child = onlyChild(child);
if (assertSchemaAlias().
equalsIgnoreCase(child.text))
return null; return null;
} else { }
// JPQL does not filter relational joins for projections // JPQL does not filter relational joins for projections
exps.distinct &= ~exps.DISTINCT_AUTO; exps.distinct &= ~exps.DISTINCT_AUTO;
return assignProjections(expNode, exps); return assignProjections(expNode, exps);
} }
} }
}
private String assertSchemaAlias() { private String assertSchemaAlias() {
String alias = ctx().schemaAlias; String alias = ctx().schemaAlias;

View File

@ -945,6 +945,7 @@ void arithmetic_factor() : { }
LOOKAHEAD(path()) path() | LOOKAHEAD(path()) path() |
LOOKAHEAD(qualified_path()) qualified_path() | LOOKAHEAD(qualified_path()) qualified_path() |
LOOKAHEAD(general_identification_variable()) general_identification_variable() | LOOKAHEAD(general_identification_variable()) general_identification_variable() |
LOOKAHEAD(identification_variable()) identification_variable() |
LOOKAHEAD("(" arithmetic_expression()) "(" arithmetic_expression() ")" | LOOKAHEAD("(" arithmetic_expression()) "(" arithmetic_expression() ")" |
LOOKAHEAD(functions_returning_numerics()) functions_returning_numerics() | LOOKAHEAD(functions_returning_numerics()) functions_returning_numerics() |
LOOKAHEAD(aggregate_select_expression()) aggregate_select_expression() | LOOKAHEAD(aggregate_select_expression()) aggregate_select_expression() |
@ -1080,9 +1081,10 @@ void string_expression() : { }
void string_primary() : { } void string_primary() : { }
{ {
string_literal() | path() | string_literal() | LOOKAHEAD(path()) path() |
LOOKAHEAD(qualified_path()) qualified_path() | LOOKAHEAD(qualified_path()) qualified_path() |
LOOKAHEAD(general_identification_variable()) general_identification_variable() | LOOKAHEAD(general_identification_variable()) general_identification_variable() |
LOOKAHEAD(identification_variable()) identification_variable() |
LOOKAHEAD("(" string_expression()) "(" string_expression() ")" | LOOKAHEAD("(" string_expression()) "(" string_expression() ")" |
functions_returning_strings() | LOOKAHEAD("(" subquery()) "(" subquery() ")" functions_returning_strings() | LOOKAHEAD("(" subquery()) "(" subquery() ")"
| case_expression() | case_expression()
@ -1097,9 +1099,10 @@ void datetime_expression() : { }
void datetime_primary() : { } void datetime_primary() : { }
{ {
path() | functions_returning_datetime() | input_parameter() | aggregate_select_expression() LOOKAHEAD(path()) path() | functions_returning_datetime() | input_parameter() | aggregate_select_expression()
| LOOKAHEAD(qualified_path()) qualified_path() | LOOKAHEAD(qualified_path()) qualified_path()
| LOOKAHEAD(general_identification_variable()) general_identification_variable() | LOOKAHEAD(general_identification_variable()) general_identification_variable()
| LOOKAHEAD(identification_variable()) identification_variable()
| case_expression() | case_expression()
} }
@ -1118,9 +1121,10 @@ void boolean_expression() : { }
void boolean_primary() : { } void boolean_primary() : { }
{ {
LOOKAHEAD(2) path() | boolean_literal() | input_parameter() LOOKAHEAD(path()) path() | boolean_literal() | input_parameter()
| LOOKAHEAD(qualified_path()) qualified_path() | LOOKAHEAD(qualified_path()) qualified_path()
| LOOKAHEAD(general_identification_variable()) general_identification_variable() | LOOKAHEAD(general_identification_variable()) general_identification_variable()
| LOOKAHEAD(identification_variable()) identification_variable()
| case_expression() | case_expression()
} }
@ -1138,6 +1142,7 @@ void enum_primary() : { }
| LOOKAHEAD(input_parameter()) input_parameter() | LOOKAHEAD(input_parameter()) input_parameter()
| LOOKAHEAD(qualified_path()) qualified_path() | LOOKAHEAD(qualified_path()) qualified_path()
| LOOKAHEAD(general_identification_variable()) general_identification_variable() | LOOKAHEAD(general_identification_variable()) general_identification_variable()
| LOOKAHEAD(identification_variable()) identification_variable()
| case_expression() | case_expression()
} }

View File

@ -1136,6 +1136,11 @@ public class TestEmbeddable extends SingleEMFTestCase {
"select a from " + "select a from " +
" EntityA_Coll_String a " + " EntityA_Coll_String a " +
" WHERE a.nickNames IS EMPTY order by a", " WHERE a.nickNames IS EMPTY order by a",
"select a from " +
" EntityA_Coll_String a " +
" WHERE exists (select n from EntityA_Coll_String a, " +
" in (a.nickNames) n where n like '%1') " +
" order by a",
}; };
List rs = null; List rs = null;
for (int i = 0; i < query.length; i++) { for (int i = 0; i < query.length; i++) {
@ -1148,6 +1153,7 @@ public class TestEmbeddable extends SingleEMFTestCase {
assertTrue(obj instanceof String); assertTrue(obj instanceof String);
break; break;
case 2: case 2:
case 3:
assertTrue(rs.size() == 0); assertTrue(rs.size() == 0);
} }
em.clear(); em.clear();
@ -1172,6 +1178,8 @@ public class TestEmbeddable extends SingleEMFTestCase {
String[] query = { String[] query = {
"select a.embed from " + "select a.embed from " +
" EntityA_Embed_ToOne a ", " EntityA_Embed_ToOne a ",
// "select a.embed from " +
// " EntityA_Embed_ToOne a ",
"select e from EntityA_Embed_ToOne a " + "select e from EntityA_Embed_ToOne a " +
" join a.embed e join e.b b where e.b.id > 0 order by a.id", " join a.embed e join e.b b where e.b.id > 0 order by a.id",
"select a.embed from " + "select a.embed from " +
@ -1179,6 +1187,11 @@ public class TestEmbeddable extends SingleEMFTestCase {
"select a.embed from " + "select a.embed from " +
" EntityA_Embed_ToOne a WHERE a.embed.b IS NOT NULL " + " EntityA_Embed_ToOne a WHERE a.embed.b IS NOT NULL " +
" ORDER BY a.embed", " ORDER BY a.embed",
"select a.embed from " +
" EntityA_Embed_ToOne a WHERE exists " +
" (select a from EntityA_Embed_ToOne a" +
" where a.embed.b IS NOT NULL) " +
" ORDER BY a.embed",
}; };
for (int i = 0; i < query.length; i++) { for (int i = 0; i < query.length; i++) {
List<Object[]> rs = null; List<Object[]> rs = null;
@ -1217,6 +1230,11 @@ public class TestEmbeddable extends SingleEMFTestCase {
" EntityA_Embed_MappedToOne a WHERE a.embed IS NOT NULL", " EntityA_Embed_MappedToOne a WHERE a.embed IS NOT NULL",
"select a.embed from " + "select a.embed from " +
" EntityA_Embed_MappedToOne a WHERE a.embed.bm IS NOT NULL", " EntityA_Embed_MappedToOne a WHERE a.embed.bm IS NOT NULL",
"select a.embed from " +
" EntityA_Embed_MappedToOne a " +
" WHERE exists " +
" (select a from EntityA_Embed_MappedToOne a " +
" where a.embed.bm IS NOT NULL)",
}; };
for (int i = 0; i < query.length; i++) { for (int i = 0; i < query.length; i++) {
List<Object[]> rs = null; List<Object[]> rs = null;
@ -1264,6 +1282,18 @@ public class TestEmbeddable extends SingleEMFTestCase {
" a.embed1s IS NOT EMPTY and " + " a.embed1s IS NOT EMPTY and " +
" e.b IS NOT NULL " + " e.b IS NOT NULL " +
" order by e", " order by e",
// the following query works in DB2 but not in Derby:
// because Derby subquery is only allowed to
// return a single column.
/*
"select e, e.b.id from " +
" EntityA_Coll_Embed_ToOne a " +
" , in (a.embed1s) e where " +
" exists (select a.embed1s from " +
" EntityA_Coll_Embed_ToOne a) and " +
" exists (select e.b from a.embed1s e) " +
" order by e",
*/
}; };
List<Object[]> rs = null; List<Object[]> rs = null;
for (int i = 0; i < query.length; i++) { for (int i = 0; i < query.length; i++) {
@ -1312,6 +1342,9 @@ public class TestEmbeddable extends SingleEMFTestCase {
" b ORDER BY b", " b ORDER BY b",
"select e from EntityA_Embed_ToMany a join a.embed e " + "select e from EntityA_Embed_ToMany a join a.embed e " +
" WHERE e.bs IS NOT EMPTY ORDER BY e", " WHERE e.bs IS NOT EMPTY ORDER BY e",
"select a from EntityA_Embed_ToMany a " +
" WHERE exists (select a.embed from EntityA_Embed_ToMany a" +
" where a.embed.bs IS NOT EMPTY) ORDER BY a",
}; };
List rs = null; List rs = null;
for (int i = 0; i < query.length; i++) { for (int i = 0; i < query.length; i++) {
@ -1331,6 +1364,8 @@ public class TestEmbeddable extends SingleEMFTestCase {
case 6: case 6:
assertTrue(obj instanceof EntityB1); assertTrue(obj instanceof EntityB1);
break; break;
case 8:
break;
} }
em.clear(); em.clear();
} }
@ -1369,6 +1404,9 @@ public class TestEmbeddable extends SingleEMFTestCase {
" where a.embed.embed.name1 like '%1' ORDER BY e", " where a.embed.embed.name1 like '%1' ORDER BY e",
"select a.embed from EntityA_Embed_Embed_ToMany a " + "select a.embed from EntityA_Embed_Embed_ToMany a " +
" where a.embed.embed.bs IS NOT EMPTY", " where a.embed.embed.bs IS NOT EMPTY",
"select a.embed from EntityA_Embed_Embed_ToMany a " +
" where exists (select a.embed.embed.bs from " +
" EntityA_Embed_Embed_ToMany a)",
}; };
List rs = null; List rs = null;
for (int i = 0; i < query.length; i++) { for (int i = 0; i < query.length; i++) {
@ -1380,6 +1418,7 @@ public class TestEmbeddable extends SingleEMFTestCase {
case 1: case 1:
case 7: case 7:
case 9: case 9:
case 10:
assertTrue(obj instanceof Embed_Embed_ToMany); assertTrue(obj instanceof Embed_Embed_ToMany);
assertTrue(((Embed_Embed_ToMany) obj).getEmbed().getEntityBs(). assertTrue(((Embed_Embed_ToMany) obj).getEmbed().getEntityBs().
size() > 0); size() > 0);
@ -1431,6 +1470,13 @@ public class TestEmbeddable extends SingleEMFTestCase {
" EntityA_Embed_Coll_Integer a " + " EntityA_Embed_Coll_Integer a " +
" , in (a.embed.otherIntVals) e " + " , in (a.embed.otherIntVals) e " +
" WHERE a.embed.otherIntVals IS NOT EMPTY order by e", " WHERE a.embed.otherIntVals IS NOT EMPTY order by e",
"select e, a.embed.intVal2 from " +
" EntityA_Embed_Coll_Integer a " +
" , in (a.embed.otherIntVals) e " +
" WHERE exists (select a from " +
" EntityA_Embed_Coll_Integer a " +
" , in (a.embed.otherIntVals) e " +
" where e > 0) order by e",
}; };
List<Object[]> rs = null; List<Object[]> rs = null;
for (int i = 0; i < query.length; i++) { for (int i = 0; i < query.length; i++) {
@ -1464,6 +1510,10 @@ public class TestEmbeddable extends SingleEMFTestCase {
"select a.embed as e from EntityA_Embed_Embed a ORDER BY e", "select a.embed as e from EntityA_Embed_Embed a ORDER BY e",
"select a.embed from EntityA_Embed_Embed a WHERE a.embed.embed " + "select a.embed from EntityA_Embed_Embed a WHERE a.embed.embed " +
" IS NOT NULL", " IS NOT NULL",
"select a.embed from EntityA_Embed_Embed a " +
" WHERE exists " +
" (select a.embed.embed from EntityA_Embed_Embed a" +
" where a.embed IS NOT NULL) ",
}; };
List rs = null; List rs = null;
for (int i = 0; i < query.length; i++) { for (int i = 0; i < query.length; i++) {
@ -1473,6 +1523,7 @@ public class TestEmbeddable extends SingleEMFTestCase {
case 0: case 0:
case 2: case 2:
case 3: case 3:
case 4:
assertTrue(rs.get(0) instanceof Embed_Embed); assertTrue(rs.get(0) instanceof Embed_Embed);
break; break;
case 1: case 1:
@ -1510,6 +1561,16 @@ public class TestEmbeddable extends SingleEMFTestCase {
" EntityA_Coll_Embed_Embed a " + " EntityA_Coll_Embed_Embed a " +
" , in (a.embeds) e WHERE a.embeds IS NOT EMPTY " + " , in (a.embeds) e WHERE a.embeds IS NOT EMPTY " +
" order by e.intVal3", " order by e.intVal3",
// the following query works in DB2 but not in Derby,
// because Derby subquery is only allowed to
// return a single column.
/*
"select e, e.intVal1, e.embed.intVal2 from " +
" EntityA_Coll_Embed_Embed a " +
" , in (a.embeds) e WHERE exists (select a.embeds " +
" from EntityA_Coll_Embed_Embed a) " +
" order by e.intVal3",
*/
}; };
List rs = null; List rs = null;
for (int i = 0; i < query.length; i++) { for (int i = 0; i < query.length; i++) {
@ -1553,6 +1614,12 @@ public class TestEmbeddable extends SingleEMFTestCase {
" EntityA_Embed_Coll_Embed a " + " EntityA_Embed_Coll_Embed a " +
" , in (a.embed.embeds) e where a.embed.embeds IS NOT EMPTY" + " , in (a.embed.embeds) e where a.embed.embeds IS NOT EMPTY" +
" order by e", " order by e",
"select e, e.intVal1, e.intVal2 from " +
" EntityA_Embed_Coll_Embed a " +
" , in (a.embed.embeds) e where exists (select e.intVal1 " +
" from EntityA_Embed_Coll_Embed a, in (a.embed.embeds) e " +
" where e.intVal2 = 105) " +
" order by e",
}; };
List<Object[]> rs = null; List<Object[]> rs = null;
for (int i = 0; i < query.length; i++) { for (int i = 0; i < query.length; i++) {