You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2011/04/04 10:17:58 UTC

svn commit: r1088500 - in /db/derby/code/trunk/java: client/org/apache/derby/client/am/ testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/

Author: kahatlen
Date: Mon Apr  4 08:17:58 2011
New Revision: 1088500

URL: http://svn.apache.org/viewvc?rev=1088500&view=rev
Log:
DERBY-5170: Client doesn't handle double quotes in savepoint names

Moved helper method that quoted SQL identifiers from ResultSet to a utility class, and made Connection use that method to quote savepoint names.

Modified:
    db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/Utils.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SavepointJdbc30Test.java

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java?rev=1088500&r1=1088499&r2=1088500&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java Mon Apr  4 08:17:58 2011
@@ -1556,8 +1556,9 @@ public abstract class Connection
                 savepointName = dncGeneratedSavepointNamePrefix__ +
                         savepoint.getSavepointId();
             }
-            String sql = "SAVEPOINT \"" + savepointName + "\" ON ROLLBACK RETAIN CURSORS";
-            stmt.executeX(sql);
+            stmt.executeX(
+                    "SAVEPOINT " + Utils.quoteSqlIdentifier(savepointName) +
+                    " ON ROLLBACK RETAIN CURSORS");
         } catch ( SqlException se )
         {
             throw se.getSQLException();
@@ -1615,8 +1616,9 @@ public abstract class Connection
                     savepointName = dncGeneratedSavepointNamePrefix__ +
                             ((Savepoint) savepoint).getSavepointId();
                 }
-                String sql = "ROLLBACK TO SAVEPOINT \"" + savepointName + "\"";
-                stmt.executeX(sql);
+                stmt.executeX(
+                        "ROLLBACK TO SAVEPOINT " +
+                        Utils.quoteSqlIdentifier(savepointName));
             } finally {
                 if (stmt != null) {
                     try {
@@ -1676,8 +1678,9 @@ public abstract class Connection
                     savepointName = dncGeneratedSavepointNamePrefix__ +
                             ((Savepoint) savepoint).getSavepointId();
                 }
-                String sql = "RELEASE SAVEPOINT \"" + savepointName + "\"";
-                stmt.executeX(sql);
+                stmt.executeX(
+                        "RELEASE SAVEPOINT " +
+                        Utils.quoteSqlIdentifier(savepointName));
             } finally {
                 if (stmt != null) {
                     try {

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java?rev=1088500&r1=1088499&r2=1088500&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java Mon Apr  4 08:17:58 2011
@@ -4532,7 +4532,7 @@ public abstract class ResultSet implemen
             }
             //using quotes around the column name to preserve case sensitivity
             try {
-                insertSQL.append(quoteSqlIdentifier(
+                insertSQL.append(Utils.quoteSqlIdentifier(
                         resultSetMetaData_.getColumnName(column)));
             } catch ( SQLException sqle ) {
                 throw new SqlException(sqle);
@@ -4567,7 +4567,7 @@ public abstract class ResultSet implemen
                     updateString.append(",");
                 }
                 try {
-                    updateString.append(quoteSqlIdentifier(
+                    updateString.append(Utils.quoteSqlIdentifier(
                             resultSetMetaData_.getColumnName(column))).append(" = ? ");
                 } catch ( SQLException sqle ) {
                     throw new SqlException(sqle);
@@ -4632,29 +4632,16 @@ public abstract class ResultSet implemen
 
         //dervied column like select 2 from t1, has null schema and table name
         if (resultSetMetaData_.sqlxSchema_[baseTableColumn] != null && !resultSetMetaData_.sqlxSchema_[baseTableColumn].equals("")) {
-            tableName += quoteSqlIdentifier(
+            tableName += Utils.quoteSqlIdentifier(
                     resultSetMetaData_.sqlxSchema_[baseTableColumn]) + ".";
         }
         if (resultSetMetaData_.sqlxBasename_[baseTableColumn] != null) {
-            tableName += quoteSqlIdentifier(
+            tableName += Utils.quoteSqlIdentifier(
                     resultSetMetaData_.sqlxBasename_[baseTableColumn]);
         }
         return tableName;
     }
 
-    private String quoteSqlIdentifier(String orgValue) {
-        int i = 0, start = 0;
-        StringBuffer retValue = new StringBuffer();
-        retValue.append("\"");
-        while ((i = orgValue.indexOf("\"", start) + 1) > 0) {
-            retValue.append(orgValue.substring(start, i)).append("\"");
-            start = i;
-        }
-        retValue.append(orgValue.substring(start, orgValue.length()));
-        retValue.append("\"");
-        return retValue.toString();
-    }
-    
     private String getServerCursorName() throws SqlException {
         return statement_.section_.getServerCursorName();
     }

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Utils.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Utils.java?rev=1088500&r1=1088499&r2=1088500&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Utils.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Utils.java Mon Apr  4 08:17:58 2011
@@ -29,6 +29,37 @@ import org.apache.derby.shared.common.re
 
 public final class Utils {
 
+    /**
+     * Quote an SQL identifier by enclosing it in double-quote characters
+     * and escaping any double-quote characters with an extra double-quote
+     * character.
+     *
+     * @param identifier the identifier to quote
+     * @return the quoted identifier
+     */
+    static String quoteSqlIdentifier(String identifier) {
+        // In the common case the length of the return value is the length of
+        // the identifier plus the two surrounding double quotes. Use that as
+        // the initial capacity of the buffer.
+        StringBuffer retValue = new StringBuffer(identifier.length() + 2);
+
+        final char quote = '"';
+
+        retValue.append(quote);
+
+        for (int i = 0; i < identifier.length(); i++) {
+            char ch = identifier.charAt(i);
+            if (ch == quote) {
+                retValue.append(quote);
+            }
+            retValue.append(ch);
+        }
+
+        retValue.append(quote);
+
+        return retValue.toString();
+    }
+
     static String getStringFromBytes(byte[] bytes) {
         if (bytes == null) {
             return "{}";

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SavepointJdbc30Test.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SavepointJdbc30Test.java?rev=1088500&r1=1088499&r2=1088500&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SavepointJdbc30Test.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SavepointJdbc30Test.java Mon Apr  4 08:17:58 2011
@@ -898,6 +898,30 @@ public class SavepointJdbc30Test extends
         }
     }
 
+    /**
+     * Test that savepoint names can have double-quote characters. The client
+     * driver used to fail with a syntax error when the names contained such
+     * characters. DERBY-5170.
+     */
+    public void testQuotes() throws SQLException {
+        setAutoCommit(false);
+        Statement s = createStatement();
+        s.execute("create table test_quotes(x int)");
+        s.execute("insert into test_quotes values 1");
+
+        Savepoint sp = getConnection().setSavepoint("a \" b ' c");
+
+        s.execute("insert into test_quotes values 2");
+
+        getConnection().rollback(sp);
+
+        JDBC.assertSingleValueResultSet(
+                s.executeQuery("select * from test_quotes"),
+                "1");
+
+        getConnection().releaseSavepoint(sp);
+    }
+
     /** ********************* */
 
     /*