You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by ht...@apache.org on 2013/08/12 22:41:36 UTC

svn commit: r1513249 - in /openjpa/branches/2.1.x/openjpa-jdbc/src: main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java test/java/org/apache/openjpa/jdbc/kernel/TestSQLStoreParamsSubstitution.java

Author: hthomann
Date: Mon Aug 12 20:41:36 2013
New Revision: 1513249

URL: http://svn.apache.org/r1513249
Log:
OPENJPA-2376: Escape character in JPQL with parameter substitution generates incorrect SQL - committed a patch sent to me by Albert Lee.

Added:
    openjpa/branches/2.1.x/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestSQLStoreParamsSubstitution.java
Modified:
    openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java

Modified: openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java?rev=1513249&r1=1513248&r2=1513249&view=diff
==============================================================================
--- openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java (original)
+++ openjpa/branches/2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java Mon Aug 12 20:41:36 2013
@@ -365,6 +365,7 @@ public class SQLStoreQuery
             if (sql.indexOf("?") == -1)
                 return sql;
 
+            sql = sql.replaceAll("\\\\", "\\\\\\\\");
             paramOrder.clear();
             StreamTokenizer tok = new StreamTokenizer(new StringReader(sql));
             tok.resetSyntax();
@@ -396,6 +397,14 @@ public class SQLStoreQuery
                             buf.append(tok.sval);
                             buf.append('\'');
                         }
+//                        // StreamTokenizer can not differentiate the last quoted token as in ^.*'.*$ and ^.*',*'$
+//                        // need to check the last quote ends with "'" and process accordingly.
+//                        if(endsWithQuote) {
+//                            buf.append('\'');                        	
+//                        } else if (tok.nextToken() != StreamTokenizer.TT_EOF) {
+//                        	tok.pushBack();
+//                            buf.append('\'');                        	
+//                        }
                         break;
                     default:
                         buf.append((char) ttype);

Added: openjpa/branches/2.1.x/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestSQLStoreParamsSubstitution.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.1.x/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestSQLStoreParamsSubstitution.java?rev=1513249&view=auto
==============================================================================
--- openjpa/branches/2.1.x/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestSQLStoreParamsSubstitution.java (added)
+++ openjpa/branches/2.1.x/openjpa-jdbc/src/test/java/org/apache/openjpa/jdbc/kernel/TestSQLStoreParamsSubstitution.java Mon Aug 12 20:41:36 2013
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.kernel;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+/**
+ * <p>
+ * Tests SQLStoreQuery.substituteParams() behavior.
+ * </p>
+ */
+
+public class TestSQLStoreParamsSubstitution extends TestCase {
+
+    /**
+     * Tests parameter substitution algorithm to make sure the input sql is NOT transformed
+     * especially escape characters.
+     */
+    public void testParamSubstitute() {
+
+        String sqlNrtns[][] = { 
+                {
+                    "like '5@%' escape '@'",
+                    "[]"
+                },
+//                {
+//                    "like '%#####_#%%' escape '#' WHERE ? = 'ab",
+//                    "[1]"
+//                },
+                {
+            		"SELECT 'TRUE' AS VAL FROM DUAL WHERE '\\' = ? AND 'Y' = 'Y'",
+                    "[1]"
+                },
+                {
+                    "like '*_n' escape '*' WHERE x = ? and y = ?",
+                    "[1, 2]"
+                },
+                {
+                    "like '%80@%%' escape '@' WHERE x = ? and y = ? or z=?" ,
+                    "[1, 2, 3]"
+                },
+                {
+                    "like '*_sql**%' escape '*" ,
+                    "[]"
+                },
+                {   "SELECT 'TRUE' AS VAL FROM DUAL WHERE '\\' = ?",
+                    "[1]",
+                },
+                {  "SELECT * FROM ("
+                     + "SELECT FOLDER_ID, SYS_CONNECT_BY_PATH(NAME,'\\') AS PATH FROM PROJECT_FOLDER "
+                     + "START WITH PARENT_ID IS NULL CONNECT BY PRIOR FOLDER_ID = PARENT_ID"
+                     + ") WHERE PATH LIKE ?",
+                   "[1]"
+                }
+            };
+        try {
+            List<Integer> paramOrder = new ArrayList<Integer>();
+
+            for (String sqlNrtn[] : sqlNrtns) {
+                paramOrder.clear();
+                String rtnSql = SQLStoreQuery.substituteParams(sqlNrtn[0], paramOrder);
+                assertEquals(sqlNrtn[0], rtnSql);
+                assertEquals(sqlNrtn[1], paramOrder.toString());
+            }
+        } catch (IOException e) {
+            fail("Unexpected Exception:" + e);
+        }
+    }
+}