mirror of https://github.com/apache/openjpa.git
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:
parent
0392538775
commit
ed82fda48c
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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++) {
|
||||||
|
|
Loading…
Reference in New Issue