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 2006/09/07 21:29:01 UTC

svn commit: r441185 - in /db/derby/code/trunk/java: client/org/apache/derby/client/am/ engine/org/apache/derby/impl/jdbc/ testing/org/apache/derbyTesting/functionTests/suites/ testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/

Author: kahatlen
Date: Thu Sep  7 12:29:00 2006
New Revision: 441185

URL: http://svn.apache.org/viewvc?view=rev&rev=441185
Log:
DERBY-1767: insertRow(), updateRow() and deleteRow() cannot handle
table names and column names containing double quotes

Patch contributed by Fernanda Pizzorno.

Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/UpdatableResultSetTest.java   (with props)
Modified:
    db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall

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?view=diff&rev=441185&r1=441184&r2=441185
==============================================================================
--- 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 Thu Sep  7 12:29:00 2006
@@ -4392,7 +4392,8 @@
             }
             //using quotes around the column name to preserve case sensitivity
             try {
-                insertSQL.append("\"" + resultSetMetaData_.getColumnName(column) + "\"");
+                insertSQL.append(quoteSqlIdentifier(
+                        resultSetMetaData_.getColumnName(column)));
             } catch ( SQLException sqle ) {
                 throw new SqlException(sqle);
             }
@@ -4425,7 +4426,9 @@
                     updateString += ",";
                 }
                 try {
-                    updateString += "\"" + resultSetMetaData_.getColumnName(column) + "\" = ? ";
+                    updateString += quoteSqlIdentifier(
+                            resultSetMetaData_.getColumnName(column)) + 
+                            " = ? ";
                 } catch ( SQLException sqle ) {
                     throw new SqlException(sqle);
                 }
@@ -4489,14 +4492,27 @@
 
         //dervied column like select 2 from t1, has null schema and table name
         if (resultSetMetaData_.sqlxSchema_[baseTableColumn] != null && !resultSetMetaData_.sqlxSchema_[baseTableColumn].equals("")) {
-            tableName += "\"" + resultSetMetaData_.sqlxSchema_[baseTableColumn] + "\".";
+            tableName += quoteSqlIdentifier(
+                    resultSetMetaData_.sqlxSchema_[baseTableColumn]) + ".";
         }
         if (resultSetMetaData_.sqlxBasename_[baseTableColumn] != null) {
-            tableName += "\"" + resultSetMetaData_.sqlxBasename_[baseTableColumn] + "\"";
+            tableName += quoteSqlIdentifier(
+                    resultSetMetaData_.sqlxBasename_[baseTableColumn]);
         }
         return tableName;
     }
 
+    private String quoteSqlIdentifier(String orgValue) {
+        int i = 0, start = 0;
+        String retValue = "";
+        while ((i = orgValue.indexOf("\"", start) + 1) > 0) {
+            retValue += orgValue.substring(start, i) + "\"";
+            start = i;
+        }
+        retValue += orgValue.substring(start, orgValue.length());
+        return "\"" + retValue + "\"";
+    }
+    
     private String getServerCursorName() throws SqlException {
         return statement_.section_.getServerCursorName();
     }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java?view=diff&rev=441185&r1=441184&r2=441185
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java Thu Sep  7 12:29:00 2006
@@ -3629,8 +3629,8 @@
                     }
                     // using quotes around the column name 
                     // to preserve case sensitivity
-                    insertSQL.append("\"" + 
-                            rd.getColumnDescriptor(i).getName() + "\"");
+                    insertSQL.append(quoteSqlIdentifier(
+                            rd.getColumnDescriptor(i).getName()));
                     if (columnGotUpdated[i-1]) { 
                         valuesSQL.append("?");
                     } else {
@@ -3677,6 +3677,8 @@
             } catch (StandardException t) {
                 throw closeOnTransactionError(t);
             } finally {
+                if (statementContext != null)
+                    lcc.popStatementContext(statementContext, null);
                 restoreContextStack();
             }
         }
@@ -3721,12 +3723,14 @@
                     if (foundOneColumnAlready)
                         updateWhereCurrentOfSQL.append(",");
                     //using quotes around the column name to preserve case sensitivity
-                    updateWhereCurrentOfSQL.append("\"" + rd.getColumnDescriptor(i).getName() + "\"=?");
+                    updateWhereCurrentOfSQL.append(quoteSqlIdentifier(
+                            rd.getColumnDescriptor(i).getName()) + "=?");
                     foundOneColumnAlready = true;
                 }
             }
             //using quotes around the cursor name to preserve case sensitivity
-            updateWhereCurrentOfSQL.append(" WHERE CURRENT OF \"" + getCursorName() + "\"");
+            updateWhereCurrentOfSQL.append(" WHERE CURRENT OF " + 
+                    quoteSqlIdentifier(getCursorName()));
             lcc = getEmbedConnection().getLanguageConnection();
 
             // Context used for preparing, don't set any timeout (use 0)
@@ -3783,18 +3787,23 @@
             checkNotOnInsertRow();
 
             setupContextStack();
+            
+            LanguageConnectionContext lcc = null;
+            StatementContext statementContext = null;
+            
             //now construct the delete where current of sql
             try {
                 StringBuffer deleteWhereCurrentOfSQL = new StringBuffer("DELETE FROM ");
                 CursorActivation activation = getEmbedConnection().getLanguageConnection().lookupCursorActivation(getCursorName());
                 deleteWhereCurrentOfSQL.append(getFullBaseTableName(activation.getPreparedStatement().getTargetTable()));//get the underlying (schema.)table name
                 //using quotes around the cursor name to preserve case sensitivity
-                deleteWhereCurrentOfSQL.append(" WHERE CURRENT OF \"" + getCursorName() + "\"");
-
-                LanguageConnectionContext lcc = getEmbedConnection().getLanguageConnection();
+                deleteWhereCurrentOfSQL.append(" WHERE CURRENT OF " + 
+                        quoteSqlIdentifier(getCursorName()));
 
+                lcc = getEmbedConnection().getLanguageConnection();
+                
                 // Context used for preparing, don't set any timeout (use 0)
-                StatementContext statementContext = lcc.pushStatementContext(isAtomic, false, deleteWhereCurrentOfSQL.toString(), null, false, 0L);
+                statementContext = lcc.pushStatementContext(isAtomic, false, deleteWhereCurrentOfSQL.toString(), null, false, 0L);
                 org.apache.derby.iapi.sql.PreparedStatement ps = lcc.prepareInternalStatement(deleteWhereCurrentOfSQL.toString());
                 // Get activation, so that we can get the warning from it
                 Activation act = ps.getActivation(lcc, false);
@@ -3815,6 +3824,8 @@
             } catch (StandardException t) {
                     throw closeOnTransactionError(t);
             } finally {
+                if (statementContext != null)
+                    lcc.popStatementContext(statementContext, null);
                 restoreContextStack();
                 initializeUpdateRowModifiers();
             }
@@ -3824,12 +3835,23 @@
 	private String getFullBaseTableName(ExecCursorTableReference targetTable) {
 		//using quotes to preserve case sensitivity
 		if (targetTable.getSchemaName() != null)
-			return "\"" + targetTable.getSchemaName() + "\".\""
-					+ targetTable.getBaseName() + "\"";
+			return quoteSqlIdentifier(targetTable.getSchemaName()) + "." + 
+					quoteSqlIdentifier(targetTable.getBaseName());
 		else
-			return "\"" + targetTable.getBaseName() + "\"";
+			return quoteSqlIdentifier(targetTable.getBaseName());
 	}
 
+    private String quoteSqlIdentifier(String orgValue) {
+        int i = 0, start = 0;
+        String retValue = "";
+        while ((i = orgValue.indexOf("\"", start) + 1) > 0) {
+            retValue += orgValue.substring(start, i) + "\"";
+            start = i;
+        }
+        retValue += orgValue.substring(start, orgValue.length());
+        return "\"" + retValue + "\"";
+    }
+    
 	/**
 	 * JDBC 2.0
 	 * 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude?view=diff&rev=441185&r1=441184&r2=441185
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude Thu Sep  7 12:29:00 2006
@@ -15,6 +15,7 @@
 #           regardless of framework
 # excluding largedata/LobLimits.java to run with the network server because currently lobs are materialized and this test tests for 2G lobs.
 # 			see DERBY-326 and DERBY-550 issues
+# excluding jdbcapi/UpdatableResultSetTest.java - Test fails with JCC
 jdbcapi/resultsetStream.java
 lang/errorStream.java
 lang/scrollCursors2.java
@@ -45,3 +46,4 @@
 # DERBY-1691: when run against JCC, exceptions in blobclob4BLOB can appear in
 # different places in the output.
 jdbcapi/blobclob4BLOB.java
+jdbcapi/UpdatableResultSetTest.junit

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall?view=diff&rev=441185&r1=441184&r2=441185
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall Thu Sep  7 12:29:00 2006
@@ -22,3 +22,4 @@
 jdbcapi/Stream.java
 jdbcapi/SURTest_ij.sql
 jdbcapi/_Suite.junit
+jdbcapi/UpdatableResultSetTest.junit

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/UpdatableResultSetTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/UpdatableResultSetTest.java?view=auto&rev=441185
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/UpdatableResultSetTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/UpdatableResultSetTest.java Thu Sep  7 12:29:00 2006
@@ -0,0 +1,363 @@
+/*
+ *
+ * Derby - Class UpdatableResultSetTest
+ *
+ * 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.derbyTesting.functionTests.tests.jdbcapi;
+import org.apache.derbyTesting.functionTests.util.TestUtil;
+import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.JDBC;
+
+import junit.framework.*;
+import java.sql.*;
+
+/**
+ * Tests updatable result sets.
+ *
+ * DERBY-1767 - Test that the deleteRow, insertRow and updateRow methods 
+ * with column/table/schema/cursor names containing quotes.
+ *
+ */
+public class UpdatableResultSetTest extends BaseJDBCTestCase {
+    
+    /** Creates a new instance of UpdatableResultSetTest */
+    public UpdatableResultSetTest(String name) {
+        super(name);
+    }
+
+    private Connection conn = null;
+    
+    protected void setUp() throws SQLException {
+        conn = getConnection();
+        conn.setAutoCommit(false);
+        Statement stmt = conn.createStatement();
+        
+        // Quoted table
+        stmt.executeUpdate("create table \"my \"\"quoted\"\" table\" (x int)");
+        stmt.executeUpdate("insert into \"my \"\"quoted\"\" table\" (x) " +
+                "values (1), (2), (3)");
+        
+        // Quoted columns
+        stmt.executeUpdate("create table \"my quoted columns\" " +
+                "(\"my \"\"quoted\"\" column\" int)");
+        stmt.executeUpdate("insert into \"my quoted columns\" " +
+                "values (1), (2), (3) ");
+        
+        // Quoted schema
+        stmt.executeUpdate("create table \"my \"\"quoted\"\" schema\"." +
+                "\"my quoted schema\" (x int)");
+        stmt.executeUpdate("insert into \"my \"\"quoted\"\" schema\"." +
+                "\"my quoted schema\" values (1), (2), (3) ");
+        
+        // No quotes, use with quoted cursor
+        stmt.executeUpdate("create table \"my table\" (x int)");
+        stmt.executeUpdate("insert into \"my table\" values (1), (2), (3) ");
+        
+        
+        
+        stmt.close();
+    }
+
+    protected void tearDown() throws SQLException {
+        conn.rollback();
+        conn.close();
+    }
+    
+    
+    /**
+     * Tests insertRow with table name containing quotes
+     */
+    public void testInsertRowOnQuotedTable() throws SQLException {
+        ResultSet rs = null;
+        Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
+                ResultSet.CONCUR_UPDATABLE);
+        rs = stmt.executeQuery("select * from \"my \"\"quoted\"\" table\"");
+        rs.next();
+        rs.moveToInsertRow();
+        rs.updateInt(1, 4);
+        rs.insertRow();
+        rs.moveToCurrentRow();
+        rs.close();
+        
+        rs = stmt.executeQuery("select * from \"my \"\"quoted\"\" table\" " +
+                "order by x");
+        for (int i=1; i<=4; i++) {
+            assertTrue("there is a row", rs.next());
+            assertEquals("row contains correct value", i, rs.getInt(1));
+        }
+        rs.close();
+        stmt.close();
+    }
+
+    /**
+     * Tests updateRow with table name containing quotes
+     */
+    public void testUpdateRowOnQuotedTable() throws SQLException {
+        ResultSet rs = null;
+        Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
+                ResultSet.CONCUR_UPDATABLE);
+        rs = stmt.executeQuery("select * from \"my \"\"quoted\"\" table\"");
+        rs.next();
+        rs.updateInt(1, 4);
+        rs.updateRow();
+        rs.close();
+        
+        rs = stmt.executeQuery("select * from \"my \"\"quoted\"\" table\" " +
+                "order by x");
+        for (int i=2; i<=4; i++) {
+            assertTrue("there is a row", rs.next());
+            assertEquals("row contains correct value", i, rs.getInt(1));
+        }
+        rs.close();
+        stmt.close();        
+    }
+
+    /**
+     * Tests deleteRow with table name containing quotes
+     */
+    public void testDeleteRowOnQuotedTable() throws SQLException {
+        ResultSet rs = null;
+        Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
+                ResultSet.CONCUR_UPDATABLE);
+        rs = stmt.executeQuery("select * from \"my \"\"quoted\"\" table\"");
+        rs.next();
+        rs.deleteRow();
+        rs.close();
+        
+        rs = stmt.executeQuery("select * from \"my \"\"quoted\"\" table\" " +
+                "order by x");
+        for (int i=2; i<=3; i++) {
+            assertTrue("there is a row", rs.next());
+            assertEquals("row contains correct value", i, rs.getInt(1));
+        }
+        rs.close();
+        stmt.close();                
+    }
+
+    /**
+     * Tests insertRow with column name containing quotes
+     */    
+    public void testInsertRowOnQuotedColumn() throws SQLException {
+        ResultSet rs = null;
+        Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
+                ResultSet.CONCUR_UPDATABLE);
+        rs = stmt.executeQuery("select * from \"my quoted columns\"");
+        rs.next();
+        rs.moveToInsertRow();
+        rs.updateInt(1, 4);
+        rs.insertRow();
+        rs.moveToCurrentRow();
+        rs.close();
+        
+        rs = stmt.executeQuery("select * from \"my quoted columns\" " +
+                "order by \"my \"\"quoted\"\" column\"");
+        for (int i=1; i<=4; i++) {
+            assertTrue("there is a row", rs.next());
+            assertEquals("row contains correct value", i, rs.getInt(1));
+        }
+        rs.close();
+        stmt.close();
+    }
+
+    /**
+     * Tests updateRow with column name containing quotes
+     */    
+    public void testUpdateRowOnQuotedColumn() throws SQLException {
+        ResultSet rs = null;
+        Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
+                ResultSet.CONCUR_UPDATABLE);
+        rs = stmt.executeQuery("select * from \"my quoted columns\"");
+        rs.next();
+        rs.updateInt(1, 4);
+        rs.updateRow();
+        rs.close();
+        
+        rs = stmt.executeQuery("select * from \"my quoted columns\" " +
+                "order by \"my \"\"quoted\"\" column\"");
+        for (int i=2; i<=4; i++) {
+            assertTrue("there is a row", rs.next());
+            assertEquals("row contains correct value", i, rs.getInt(1));
+        }
+        rs.close();
+        stmt.close();        
+    }
+
+    /**
+     * Tests deleteRow with column name containing quotes
+     */    
+    public void testDeleteRowOnQuotedColumn() throws SQLException {
+        ResultSet rs = null;
+        Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
+                ResultSet.CONCUR_UPDATABLE);
+        rs = stmt.executeQuery("select * from \"my quoted columns\"");
+        rs.next();
+        rs.deleteRow();
+        rs.close();
+        
+        rs = stmt.executeQuery("select * from \"my quoted columns\" " +
+                "order by \"my \"\"quoted\"\" column\"");
+        for (int i=2; i<=3; i++) {
+            assertTrue("there is a row", rs.next());
+            assertEquals("row contains correct value", i, rs.getInt(1));
+        }
+        rs.close();
+        stmt.close();                
+    }
+
+    /**
+     * Tests insertRow with schema name containing quotes
+     */    
+    public void testInsertRowOnQuotedSchema() throws SQLException {
+        ResultSet rs = null;
+        Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
+                ResultSet.CONCUR_UPDATABLE);
+        rs = stmt.executeQuery("select * from \"my \"\"quoted\"\" schema\"." +
+                "\"my quoted schema\"");
+        rs.next();
+        rs.moveToInsertRow();
+        rs.updateInt(1, 4);
+        rs.insertRow();
+        rs.moveToCurrentRow();
+        rs.close();
+        
+        rs = stmt.executeQuery("select * from \"my \"\"quoted\"\" schema\"." +
+                "\"my quoted schema\" order by x");
+        for (int i=1; i<=4; i++) {
+            assertTrue("there is a row", rs.next());
+            assertEquals("row contains correct value", i, rs.getInt(1));
+        }
+        rs.close();
+        stmt.close();
+    }
+
+    /**
+     * Tests updateRow with schema name containing quotes
+     */    
+    public void testUpdateRowOnQuotedSchema() throws SQLException {
+        ResultSet rs = null;
+        Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
+                ResultSet.CONCUR_UPDATABLE);
+        rs = stmt.executeQuery("select * from \"my \"\"quoted\"\" schema\"." +
+                "\"my quoted schema\"");
+        rs.next();
+        rs.updateInt(1, 4);
+        rs.updateRow();
+        rs.close();
+        
+        rs = stmt.executeQuery("select * from \"my \"\"quoted\"\" schema\"." +
+                "\"my quoted schema\" order by x");
+        for (int i=2; i<=4; i++) {
+            assertTrue("there is a row", rs.next());
+            assertEquals("row contains correct value", i, rs.getInt(1));
+        }
+        rs.close();
+        stmt.close();        
+    }
+
+    /**
+     * Tests deleteRow with schema name containing quotes
+     */    
+    public void testDeleteRowOnQuotedSchema() throws SQLException {
+        ResultSet rs = null;
+        Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
+                ResultSet.CONCUR_UPDATABLE);
+        rs = stmt.executeQuery("select * from \"my \"\"quoted\"\" schema\"." +
+                "\"my quoted schema\"");
+        rs.next();
+        rs.deleteRow();
+        rs.close();
+        
+        rs = stmt.executeQuery("select * from \"my \"\"quoted\"\" schema\"." +
+                "\"my quoted schema\" order by x");
+        for (int i=2; i<=3; i++) {
+            assertTrue("there is a row", rs.next());
+            assertEquals("row contains correct value", i, rs.getInt(1));
+        }
+        rs.close();
+        stmt.close();                
+    }
+
+    /**
+     * Tests insertRow with cursor name containing quotes
+     */    
+    public void testInsertRowOnQuotedCursor() throws SQLException {
+        ResultSet rs = null;
+        Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
+                ResultSet.CONCUR_UPDATABLE);
+        stmt.setCursorName("my \"\"\"\"quoted\"\"\"\" cursor\"\"");
+        rs = stmt.executeQuery("select * from \"my table\"");
+        rs.next();
+        rs.moveToInsertRow();
+        rs.updateInt(1, 4);
+        rs.insertRow();
+        rs.moveToCurrentRow();
+        rs.close();
+        
+        rs = stmt.executeQuery("select * from \"my table\" order by x");
+        for (int i=1; i<=4; i++) {
+            assertTrue("there is a row", rs.next());
+            assertEquals("row contains correct value", i, rs.getInt(1));
+        }
+        rs.close();
+        stmt.close();
+    }
+
+    /**
+     * Tests updateRow with cursor name containing quotes
+     */    
+    public void testUpdateRowOnQuotedCursor() throws SQLException {
+        ResultSet rs = null;
+        Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
+                ResultSet.CONCUR_UPDATABLE);
+        stmt.setCursorName("\"\"my quoted cursor");
+        rs = stmt.executeQuery("select * from \"my table\"");
+        rs.next();
+        rs.updateInt(1, 4);
+        rs.updateRow();
+        rs.close();
+        
+        rs = stmt.executeQuery("select * from \"my table\" order by x");
+        for (int i=2; i<=4; i++) {
+            assertTrue("there is a row", rs.next());
+            assertEquals("row contains correct value", i, rs.getInt(1));
+        }
+        rs.close();
+        stmt.close();        
+    }
+
+    /**
+     * Tests deleteRow with cursor name containing quotes
+     */    
+    public void testDeleteRowOnQuotedCursor() throws SQLException {
+        ResultSet rs = null;
+        Statement stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
+                ResultSet.CONCUR_UPDATABLE);
+        stmt.setCursorName("\"\"my quoted cursor\"\"");
+        rs = stmt.executeQuery("select * from \"my table\"");
+        rs.next();
+        rs.deleteRow();
+        rs.close();
+        
+        rs = stmt.executeQuery("select * from \"my table\" order by x");
+        for (int i=2; i<=3; i++) {
+            assertTrue("there is a row", rs.next());
+            assertEquals("row contains correct value", i, rs.getInt(1));
+        }
+        rs.close();
+        stmt.close();                
+    }
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/UpdatableResultSetTest.java
------------------------------------------------------------------------------
    svn:eol-style = native