You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by fa...@apache.org on 2009/05/06 02:03:09 UTC

svn commit: r772015 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/ openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/ openjpa-persistence-jdb...

Author: fancy
Date: Wed May  6 00:03:09 2009
New Revision: 772015

URL: http://svn.apache.org/viewvc?rev=772015&view=rev
Log:
OPENJPA-1064 JPA2 Query add support for embeddable of element collection in predicate and subquery

Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualExpression.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
    openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualExpression.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualExpression.java?rev=772015&r1=772014&r2=772015&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualExpression.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/EqualExpression.java Wed May  6 00:03:09 2009
@@ -62,7 +62,7 @@
                     new FilterValueImpl(sel, ctx, bstate.state1, val1),
                     new FilterValueImpl(sel, ctx, bstate.state2, val2));
             } 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));
                 for (int i = 0; i < len; i++) {
                     if (i > 0)

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java?rev=772015&r1=772014&r2=772015&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java Wed May  6 00:03:09 2009
@@ -460,15 +460,17 @@
             // schema's alias, then do not treat it as a projection
             if (selectCount == 1 && selectChild != null &&
                 selectChild.getChildCount() == 1 &&
-                onlyChild(selectChild) != null &&
-                assertSchemaAlias().
-                    equalsIgnoreCase(onlyChild(selectChild).text)) {
-                return null;
-            } else {
-                // JPQL does not filter relational joins for projections
-                exps.distinct &= ~exps.DISTINCT_AUTO;
-                return assignProjections(expNode, exps);
-            }
+                onlyChild(selectChild) != null) {
+                JPQLNode child = onlyChild(selectChild);
+                if (child.id == JJTSCALAREXPRESSION)
+                    child = onlyChild(child);
+                if (assertSchemaAlias().
+                    equalsIgnoreCase(child.text)) 
+                    return null;
+            } 
+            // JPQL does not filter relational joins for projections
+            exps.distinct &= ~exps.DISTINCT_AUTO;
+            return assignProjections(expNode, exps);
         }
     }
 

Modified: openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt?rev=772015&r1=772014&r2=772015&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt (original)
+++ openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt Wed May  6 00:03:09 2009
@@ -945,6 +945,7 @@
 	LOOKAHEAD(path()) path() |
 	LOOKAHEAD(qualified_path()) qualified_path() |
 	LOOKAHEAD(general_identification_variable()) general_identification_variable() |
+	LOOKAHEAD(identification_variable()) identification_variable() |
 	LOOKAHEAD("("  arithmetic_expression()) "("  arithmetic_expression() ")" | 
 	LOOKAHEAD(functions_returning_numerics()) functions_returning_numerics() | 
 	LOOKAHEAD(aggregate_select_expression()) aggregate_select_expression() |	
@@ -1080,9 +1081,10 @@
 
 void string_primary() : { }
 {
-	string_literal() | path() |
+	string_literal() | LOOKAHEAD(path()) path() |
 	LOOKAHEAD(qualified_path()) qualified_path() |	
 	LOOKAHEAD(general_identification_variable()) general_identification_variable() |
+	LOOKAHEAD(identification_variable()) identification_variable() |
 	LOOKAHEAD("(" string_expression()) "(" string_expression() ")" | 
 	functions_returning_strings() | LOOKAHEAD("(" subquery()) "(" subquery() ")"
 	| case_expression()
@@ -1097,9 +1099,10 @@
 
 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(general_identification_variable()) general_identification_variable()
+	| LOOKAHEAD(identification_variable()) identification_variable()
 	| case_expression()
 }
 
@@ -1118,9 +1121,10 @@
 
 void boolean_primary() : { }
 {
-	LOOKAHEAD(2) path() | boolean_literal() | input_parameter()
+	LOOKAHEAD(path()) path() | boolean_literal() | input_parameter()
 	| LOOKAHEAD(qualified_path()) qualified_path()
 	| LOOKAHEAD(general_identification_variable()) general_identification_variable()
+	| LOOKAHEAD(identification_variable()) identification_variable()
 	| case_expression()
 }
 
@@ -1138,6 +1142,7 @@
 	| LOOKAHEAD(input_parameter()) input_parameter()
 	| LOOKAHEAD(qualified_path()) qualified_path()
 	| LOOKAHEAD(general_identification_variable()) general_identification_variable()
+	| LOOKAHEAD(identification_variable()) identification_variable()
 	| case_expression()
 }
 

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java?rev=772015&r1=772014&r2=772015&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/embed/TestEmbeddable.java Wed May  6 00:03:09 2009
@@ -1136,6 +1136,11 @@
                 "select a from " +
                     " EntityA_Coll_String 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;
         for (int i = 0; i < query.length; i++) {
@@ -1148,6 +1153,7 @@
                 assertTrue(obj instanceof String);
                 break;
             case 2:
+            case 3:
                 assertTrue(rs.size() == 0);
             }
             em.clear();
@@ -1172,6 +1178,8 @@
         String[] query = {
             "select a.embed from " +
                 " EntityA_Embed_ToOne a ",
+//            "select a.embed 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",
             "select a.embed from " +
@@ -1179,6 +1187,11 @@
             "select a.embed from " +
                 " EntityA_Embed_ToOne a WHERE a.embed.b IS NOT NULL " +
                 " 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++) {
             List<Object[]> rs = null;
@@ -1217,6 +1230,11 @@
                 " EntityA_Embed_MappedToOne a WHERE a.embed IS NOT NULL",
             "select a.embed from " +
                 " 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++) {
             List<Object[]> rs = null;
@@ -1264,6 +1282,18 @@
                 " a.embed1s IS NOT EMPTY and " +
                 " e.b IS NOT NULL " +
                 " 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;
         for (int i = 0; i < query.length; i++) {
@@ -1312,6 +1342,9 @@
                 " b ORDER BY b",
             "select e from EntityA_Embed_ToMany a join a.embed 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;
         for (int i = 0; i < query.length; i++) {
@@ -1331,6 +1364,8 @@
             case 6:
                 assertTrue(obj instanceof EntityB1);
                 break;
+            case 8:
+                break;
             }
             em.clear();
         }
@@ -1369,6 +1404,9 @@
                 " where a.embed.embed.name1 like '%1' ORDER BY e",
             "select a.embed from EntityA_Embed_Embed_ToMany a " +
                 " 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;
         for (int i = 0; i < query.length; i++) {
@@ -1380,6 +1418,7 @@
             case 1:
             case 7:
             case 9:
+            case 10:
                 assertTrue(obj instanceof Embed_Embed_ToMany);
                 assertTrue(((Embed_Embed_ToMany) obj).getEmbed().getEntityBs().
                     size() > 0);
@@ -1431,6 +1470,13 @@
                 " EntityA_Embed_Coll_Integer a " +
                 " , in (a.embed.otherIntVals) 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;
         for (int i = 0; i < query.length; i++) {
@@ -1464,6 +1510,10 @@
             "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 " +
                 " 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;
         for (int i = 0; i < query.length; i++) {
@@ -1473,6 +1523,7 @@
             case 0:
             case 2:
             case 3:
+            case 4:
                 assertTrue(rs.get(0) instanceof Embed_Embed);
                 break;
             case 1:
@@ -1510,6 +1561,16 @@
                 " EntityA_Coll_Embed_Embed a " +
                 " , in (a.embeds) e WHERE a.embeds IS NOT EMPTY " +
                 " 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;
         for (int i = 0; i < query.length; i++) {
@@ -1553,6 +1614,12 @@
                 " EntityA_Embed_Coll_Embed a " +
                 " , in (a.embed.embeds) e where a.embed.embeds IS NOT EMPTY" +
                 " 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;
         for (int i = 0; i < query.length; i++) {