db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhille...@apache.org
Subject svn commit: r718381 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/sql/compile/ testing/org/apache/derbyTesting/functionTests/tests/lang/
Date Mon, 17 Nov 2008 21:07:13 GMT
Author: rhillegas
Date: Mon Nov 17 13:07:13 2008
New Revision: 718381

URL: http://svn.apache.org/viewvc?rev=718381&view=rev
Log:
DERBY-3950: Prevent driving SELECTs from overriding the values of generated columns.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/InsertNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/InsertNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/InsertNode.java?rev=718381&r1=718380&r2=718381&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/InsertNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/InsertNode.java Mon
Nov 17 13:07:13 2008
@@ -600,7 +600,7 @@
 				resultSet.enhanceRCLForInsert(
 						numTableColumns, colMap, dataDictionary,
 						targetTableDescriptor, targetVTI);
-			resultColumnList.checkAutoincrement(resultSet.getResultColumns());
+			resultColumnList.forbidOverrides(resultSet.getResultColumns());
 		}
 	}
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java?rev=718381&r1=718380&r2=718381&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumn.java Mon
Nov 17 13:07:13 2008
@@ -88,6 +88,7 @@
 	boolean			updated;
 	boolean			updatableByCursor;
 	private boolean defaultColumn;
+    private boolean wasDefault;
 
 	// tells us if this ResultColumn is a placeholder for a generated
 	// autoincrement value for an insert statement.
@@ -208,6 +209,20 @@
 	}
 
 	/**
+	 * Returns TRUE if the ResultColumn used to stand in for a DEFAULT keyword in
+	 * an insert/update statement.
+	 */
+	public boolean wasDefaultColumn()
+	{
+		return wasDefault;
+	}
+
+	public void setWasDefaultColumn(boolean value)
+	{
+		wasDefault = value;
+	}
+
+	/**
 	 * Return TRUE if this result column matches the provided column name.
 	 *
 	 * This function is used by ORDER BY column resolution. For the
@@ -505,6 +520,8 @@
 			return "exposedName: " + exposedName + "\n" +
 				"name: " + name + "\n" +
 				"tableName: " + tableName + "\n" +
+				"isDefaultColumn: " + defaultColumn + "\n" +
+				"wasDefaultColumn: " + wasDefault + "\n" +
 				"isNameGenerated: " + isNameGenerated + "\n" +
 				"sourceTableName: " + sourceTableName + "\n" +
 				"type: " + getTypeServices() + "\n" +

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java?rev=718381&r1=718380&r2=718381&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java
Mon Nov 17 13:07:13 2008
@@ -3919,7 +3919,6 @@
 							defaultInfo.getDefaultText(),
 							getLanguageConnectionContext(),
 							getCompilerContext()));
-
 				}
 				else
 				{
@@ -3927,8 +3926,9 @@
 						(ValueNode) getNodeFactory().getNode(
 										C_NodeTypes.UNTYPED_NULL_CONSTANT_NODE,
 										getContextManager()));
+                    rc.setWasDefaultColumn( true );
 				}
-				rc.setDefaultColumn(false);
+                rc.setDefaultColumn(false);
 			}
 		}
 	}
@@ -4056,13 +4056,13 @@
 	}
 	
 	/**
-	 * check if any autoincrement columns exist in the result column list.
+	 * check if any autoincrement or generated columns exist in the result column list.
 	 * called from insert or update where you cannot insert/update the value
-	 * of an autoincrement column.
+	 * of a generated or autoincrement column.
 	 *
 	 * @exception StandardException		If the column is an ai column
 	 */
-	public void checkAutoincrement(ResultColumnList sourceRSRCL)
+	public void forbidOverrides(ResultColumnList sourceRSRCL)
 		throws StandardException
 	{
 		int size = size();
@@ -4073,6 +4073,14 @@
 			ResultColumn sourceRC = 
 				(ResultColumn)((sourceRSRCL == null) ? null : sourceRSRCL.elementAt(index));
 			ColumnDescriptor cd = rc.getTableColumnDescriptor();
+
+            if ( (cd != null) && cd.hasGenerationClause() )
+            {
+                if ( (sourceRC != null) && !sourceRC.hasGenerationClause() &&
!sourceRC.wasDefaultColumn() )
+                {
+                    throw StandardException.newException(SQLState.LANG_CANT_OVERRIDE_GENERATION_CLAUSE,
rc.getName());
+                }
+            }
 			
 			if ((cd != null) && (cd.isAutoincrement()))
 			{

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java?rev=718381&r1=718380&r2=718381&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java Mon
Nov 17 13:07:13 2008
@@ -379,7 +379,7 @@
         
 		LanguageConnectionContext lcc = getLanguageConnectionContext();
 		if (lcc.getAutoincrementUpdate() == false)
-			resultSet.getResultColumns().checkAutoincrement(null);
+			resultSet.getResultColumns().forbidOverrides(null);
 
 		/*
 		** Mark the columns in this UpdateNode's result column list as

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java?rev=718381&r1=718380&r2=718381&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java
Mon Nov 17 13:07:13 2008
@@ -79,6 +79,7 @@
     protected static  final   String  LACK_COLUMN_PRIV = "42502";
     protected static  final   String  LACK_EXECUTE_PRIV = "42504";
     protected static  final   String  CANT_ADD_IDENTITY = "42601";
+    protected static  final   String  CANT_MODIFY_IDENTITY = "42Z23";
     
     protected static  final   String  CASCADED_COLUMN_DROP_WARNING = "01009";
     protected static  final   String  CONSTRAINT_DROPPED_WARNING = "01500";

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsTest.java?rev=718381&r1=718380&r2=718381&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsTest.java
Mon Nov 17 13:07:13 2008
@@ -4181,6 +4181,156 @@
 
     }
     
+    /**
+     * <p>
+     * Test that you cannot override the value of a generated column via
+     * a driving SELECT--except where the value in the driving SELECT is the
+     * DEFAULT literal. Make sure that generation clauses behave like
+     * autoincrement columns in this respect.
+     * </p>
+     */
+    public  void    test_023_drivingSelect()
+        throws Exception
+    {
+        Connection  conn = getConnection();
+
+        //
+        // Schema and pre-population.
+        //
+        goodStatement
+            (
+             conn,
+             "create table t_ds_source( a int, b int )"
+             );
+        goodStatement
+            (
+             conn,
+             "create table t_ds_id( a int, b int generated always as identity )"
+             );
+        goodStatement
+            (
+             conn,
+             "create table t_ds_gc( a int, b generated always as ( -a ) )"
+             );
+        goodStatement
+            (
+             conn,
+             "insert into t_ds_source( a, b ) values ( 1, 1 )"
+             );
+        
+        //
+        // DEFAULT literals ok.
+        //
+        goodStatement
+            (
+             conn,
+             "insert into t_ds_id values ( 3, default )"
+             );
+        goodStatement
+            (
+             conn,
+             "insert into t_ds_gc values ( 3, default )"
+             );
+        
+        //
+        // Inserts into non-generated columns OK.
+        //
+        goodStatement
+            (
+             conn,
+             "insert into t_ds_id( a ) select a from t_ds_source"
+             );
+        goodStatement
+            (
+             conn,
+             "insert into t_ds_gc( a ) select a from t_ds_source"
+             );
+        
+        //
+        // Other literals raise an error.
+        //
+        expectCompilationError
+            (
+             CANT_MODIFY_IDENTITY,
+             "insert into t_ds_id values ( 2, 2 )"
+             );
+        expectCompilationError
+            (
+             CANT_OVERRIDE_GENERATION_CLAUSE,
+             "insert into t_ds_gc values ( 2, 2 )"
+             );
+        
+        //
+        // You can't stuff an overriding value from a nested SELECT
+        //
+        expectCompilationError
+            (
+             CANT_MODIFY_IDENTITY,
+             "insert into t_ds_id select * from t_ds_source"
+             );
+        expectCompilationError
+            (
+             CANT_OVERRIDE_GENERATION_CLAUSE,
+             "insert into t_ds_gc select * from t_ds_source"
+             );
+        
+        //
+        // You can't stuff an overriding value from a literal in a nested SELECT
+        //
+        expectCompilationError
+            (
+             CANT_MODIFY_IDENTITY,
+             "insert into t_ds_id select a, 3 from t_ds_source"
+             );
+        expectCompilationError
+            (
+             CANT_OVERRIDE_GENERATION_CLAUSE,
+             "insert into t_ds_gc select a, 3 from t_ds_source"
+             );
+
+        //
+        // DEFAULT literal in the SELECT list is just a syntax error.
+        //
+        expectCompilationError
+            (
+             SYNTAX_ERROR,
+             "insert into t_ds_id select a, default from t_ds_source"
+             );
+        expectCompilationError
+            (
+             SYNTAX_ERROR,
+             "insert into t_ds_gc select a, default from t_ds_source"
+             );
+
+        //
+        // Verify contents of tables.
+        //
+        assertResults
+            (
+             conn,
+             "select * from t_ds_id order by b",
+             new String[][]
+             {
+                 { "3", "1", },
+                 { "1", "2", },
+             },
+             false
+             );
+        assertResults
+            (
+             conn,
+             "select * from t_ds_gc order by b",
+             new String[][]
+             {
+                 { "3", "-3", },
+                 { "1", "-1", },
+             },
+             false
+             );
+
+    }
+    
+
     ///////////////////////////////////////////////////////////////////////////////////
     //
     // MINIONS



Mime
View raw message