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/03/14 04:28:15 UTC

svn commit: r753596 - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestEJBQLFunction.java

Author: faywang
Date: Sat Mar 14 03:28:14 2009
New Revision: 753596

URL: http://svn.apache.org/viewvc?rev=753596&view=rev
Log:
OPENJPA-978: make the third argument in substring function
optional.

Modified:
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestEJBQLFunction.java

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=753596&r1=753595&r2=753596&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 Sat Mar 14 03:28:14 2009
@@ -1071,12 +1071,18 @@
                 return factory.concat(val1, val2);
 
             case JJTSUBSTRING:
-                val1 = getValue(child(node, 0, 3));
-                val2 = getValue(child(node, 1, 3));
-                val3 = getValue(child(node, 2, 3));
+                if (node.children.length == 3) {
+                    val1 = getValue(child(node, 0, 3));
+                    val2 = getValue(child(node, 1, 3));
+                    val3 = getValue(child(node, 2, 3));
+                } else if (node.children.length == 2) {
+                    val1 = getValue(child(node, 0, 2));
+                    val2 = getValue(child(node, 1, 2));
+                }
                 setImplicitType(val1, TYPE_STRING);
                 setImplicitType(val2, Integer.TYPE);
-                setImplicitType(val3, Integer.TYPE);
+                if (node.children.length == 3)
+                    setImplicitType(val3, Integer.TYPE);
 
                 // the semantics of the JPQL substring() function
                 // are that arg2 is the 1-based start index, and arg3 is
@@ -1086,28 +1092,35 @@
                 // arg2 is the end index): we perform the translation by
                 // adding one to the first argument, and then adding the
                 // first argument to the second argument to get the endIndex
-                Value start;
-                Value end;
-                if (val2 instanceof Literal && val3 instanceof Literal) {
+                Value start = null;
+                Value end = null;
+                if (val2 instanceof Literal && 
+                    (val3 == null || val3 instanceof Literal)) {
                     // optimize SQL for the common case of two literals
                     long jpqlStart = ((Number) ((Literal) val2).getValue())
                         .longValue();
-                    long length = ((Number) ((Literal) val3).getValue())
-                        .longValue();
                     start = factory.newLiteral(new Long(jpqlStart - 1),
                         Literal.TYPE_NUMBER);
+                    if (val3 != null) {
+                    	long length = ((Number) ((Literal) val3).getValue())
+                            .longValue();
                     long endIndex = length + (jpqlStart - 1);
                     end = factory.newLiteral(new Long(endIndex),
                         Literal.TYPE_NUMBER);
+                    }
                 } else {
                     start = factory.subtract(val2, factory.newLiteral
                         (Numbers.valueOf(1), Literal.TYPE_NUMBER));
+                    if (val3 != null)
                     end = factory.add(val3,
                         (factory.subtract(val2, factory.newLiteral
                             (Numbers.valueOf(1), Literal.TYPE_NUMBER))));
                 }
+                if (val3 != null)
                 return factory.substring(val1, factory.newArgumentList(
                     start, end));
+                else
+                    return factory.substring(val1, start);
 
             case JJTLOCATE:
                 // as with SUBSTRING (above), the semantics for LOCATE differ

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestEJBQLFunction.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestEJBQLFunction.java?rev=753596&r1=753595&r2=753596&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestEJBQLFunction.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/functions/TestEJBQLFunction.java Sat Mar 14 03:28:14 2009
@@ -94,6 +94,19 @@
         assertEquals("the users name is not AblahumSeet", "Ablahumeeth",
             user.getName());
 
+        query = "UPDATE CompUser e SET e.name = " +
+            "CONCAT('XYZ', SUBSTRING(e.name, LOCATE('e', e.name))) " +
+            "WHERE e.name='Ablahumeeth'";
+        result = em.createQuery(query).executeUpdate();
+
+        assertEquals("the result is not 1", 1, result);
+
+        user = em.find(CompUser.class, userid1);
+        em.refresh(user);
+
+        assertNotNull("the user is null", user);
+        assertEquals("the users name is not Ablahumeeth", "XYZeeth",
+            user.getName());
         endTx(em);
         endEm(em);
     }