db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bpendle...@apache.org
Subject svn commit: r487414 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/sql/compile/ testing/org/apache/derbyTesting/functionTests/master/ testing/org/apache/derbyTesting/functionTests/tests/lang/
Date Fri, 15 Dec 2006 01:01:15 GMT
Author: bpendleton
Date: Thu Dec 14 17:01:14 2006
New Revision: 487414

URL: http://svn.apache.org/viewvc?view=rev&rev=487414
Log:
DERBY-1644: NPE when inserting values to tbl w/ identity col gen by default

When the VALUES clause encounters multiple rows, it generates a UNION
node tree to combine the rows to be inserted. InsertNode notices the
top-level UNION node and calls the special checkAutoincrementUnion()
method which knows how to recursively traverse the Union tree and
call checkAutoIncrement() on the underlying RowResultSetNode instances
at the leaf level of the tree.

HOWEVER, when the number of columns in the rows in the VALUES clause
is a subset of the number of columns in the table we're inserting into,
the top node of the tree is not a UnionNode, but is rather a
ProjectRestrictNode. This means that we skip past the UnionNode test and
just call checkAutoincrement(), which processes the PRN but doesn't
go down to the RowResultSetNode(s) at the leaf level.

This leaves the ResultColumn instance at the leaf level with a NULL column
descriptor, which causes the NPE during the code generation phase.

And, there is a second, related problem. The enhanceRCLForInsert() call
is also only made at the top level of the tree. However, this call is a
necessary pre-condition for calling checkAutoincrement() because
enhanceRCLForInsert() ensures that the proper ResultColumnList values are
in place prior to the checkAutoincrement() reconciliation of the column lists.

The patch solves these problems by merging the code from InsertNode.bind
together with the current recursive processing in
ResultColumnList.checkAutoincrementUnion() to produce a new recursive
routine, which I have called enhanceAndCheckForAutoincrement(), which will
recursively traverse the ResultSet tree, calling *both* enhanceRCLForInsert()
and checkAutoincrement() on the various nodes in the tree.

Thus the primary ideas involved in this patch are:
 - When an INSERT statement will insert multiple rows from the VALUES
   clause, the compiler will compile the various values into a tree of
   UnionNodes with RowResultSetNodes at the leaves of the three
 - The columns specified in the INSERT statement may be a subset
   of the rows in the table. The "extra" columns need to be constructed by
   the INSERT statement, either by generating NULL values for those
   columns which are nullable, or by compiling a default values for those
   columns which have DEFAULT values, or by generating a value for an IDENTITY
   column which is GENERATED. The work of constructing these extra
   column values is done by genNewRCForInsert.
 - For columns which are GENERATED ALWAYS, we must make sure that
   the INSERT statement doesn't allow the user to insert their own value for
   the generated column.
 - The columns which are specified in the INSERT column spec may not match
   the order in which the columns arise in the table. Therefore, the column
   values may need to be re-ordered by the INSERT statement so that they
   occur in the proper order.
 - In the case when the ResultSet which provides the values for the INSERT
   statement is not just a single node, but is rather a tree of UnionNodes, the
   above processing needs to happen throughout the tree, not just at
   the root node. 

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/ResultColumnList.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultSetNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SetOperatorNode.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/autoincrement.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/autoincrement.sql

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?view=diff&rev=487414&r1=487413&r2=487414
==============================================================================
--- 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 Thu
Dec 14 17:01:14 2006
@@ -411,45 +411,10 @@
 			}
 		}
 
-		// colmap[x] == y means that column x in the target table
-		// maps to column y in the source result set.
-		// colmap[x] == -1 means that column x in the target table
-		// maps to its default value.
-		// both colmap indexes and values are 0-based.
+		enhanceAndCheckForAutoincrement(resultSet, inOrder,
+				numTableColumns, colMap, dataDictionary,
+				targetTableDescriptor, targetVTI);
 
-		/* if the list is in order and complete, we don't have to change
-		 * the tree. If it is not, then we call RSN.enhanceRCLForInsert() 
-		 * which will either
-		 * (reorder and/or "enhance" the source RCL within the same RSN) or
-		 * (generate and return a PRN with a new reordered/enhanced RCL above
-		 * the existing RSN).  This way, RSN's that understand how to do projections
-		 * can avoid the additional PRN while those that do not will get one.
-		 */
-		/* NOTE - javascope gives confusing branch coverage info here.  By
-		 * breaking apart the following if condition, I have verified that
-		 * we test all cases.  (Jerry 7/17/97)
-		 */
-		if (! inOrder || resultSet.resultColumns.size() < numTableColumns)
-		{
-			// one thing we do know is that all of the resultsets underneath
-			// us have their resultColumn names filled in with the names of
-			// the target table columns.  That makes generating the mapping
-			// "easier" -- we simply generate the names of the target table columns
-			// that are included.  For the missing columns, we generate default
-			// value expressions.
-
-			resultSet = resultSet.enhanceRCLForInsert(numTableColumns, colMap, 
-													  dataDictionary,
-													  targetTableDescriptor, targetVTI);
-		}
-
-		if (resultSet instanceof UnionNode)
-		{
-			// If we are inserting a number of rows in VALUES clause, we need to
-			// examine each row for 'autoincrement'.
-			resultColumnList.checkAutoincrementUnion(resultSet);
-		}
-		else resultColumnList.checkAutoincrement(resultSet.getResultColumns());
 		resultColumnList.checkStorableExpressions(resultSet.getResultColumns());
 		/* Insert a NormalizeResultSetNode above the source if the source
 		 * and target column types and lengths do not match.
@@ -527,6 +492,104 @@
 		}
         
 		getCompilerContext().popCurrentPrivType();
+	}
+
+	/**
+	 * Process ResultSet column lists for projection and autoincrement.
+	 *
+	 * This method recursively descends the result set node tree. When
+	 * it finds a simple result set, it processes any autoincrement
+	 * columns in that rs by calling checkAutoIncrement. When it finds
+	 * a compound result set, like a Union or a PRN, it recursively
+	 * descends to the child(ren) nodes. Union nodes can arise due to
+	 * multi-rows in VALUES clause), PRN nodes can arise when the set
+	 * of columns being inserted is a subset of the set of columns in 
+	 * the table.
+	 *
+	 * In addition to checking for autoincrement columns in the result set,
+	 * we may need to enhance and re-order the column list to match the
+	 * column list of the table we are inserting into. This work is handled
+	 * by ResultsetNode.enhanceRCLForInsert.
+	 *
+	 * Note that, at the leaf level, we need to enhance the RCL first, then
+	 * check for autoincrement columns. At the non-leaf levels, we have
+	 * to enhance the RCL, but we don't have to check for autoincrement
+	 * columns, since they only occur at the leaf level.
+	 *
+	 * This way, all ColumnDescriptor of all rows will be set properly.
+	 *
+	 * @param resultSet			current node in the result set tree
+	 * @param inOrder			FALSE if the column list needs reordering
+	 * @param numTableColumns   # of columns in target RCL
+	 * @param colMap            correspondence between RCLs
+	 * @param dataDictionary    DataDictionary to use
+	 * @param targetTD          Table Descriptor for target
+	 * @param targetVTI         Target description if it is a VTI
+	 *
+	 * @exception StandardException Thrown on error
+	 */
+	private void enhanceAndCheckForAutoincrement(ResultSetNode resultSet, 
+			boolean inOrder, int numTableColumns, int []colMap, 
+			DataDictionary dataDictionary,
+			TableDescriptor targetTableDescriptor,
+			FromVTI targetVTI)
+		throws StandardException
+	{
+		/*
+		 * Some implementation notes:
+		 * 
+		 * colmap[x] == y means that column x in the target table
+		 * maps to column y in the source result set.
+		 * colmap[x] == -1 means that column x in the target table
+		 * maps to its default value.
+		 * both colmap indexes and values are 0-based.
+		 *
+		 * if the list is in order and complete, we don't have to change
+		 * the tree. If it is not, then we call RSN.enhanceRCLForInsert() 
+		 * which will reorder ("enhance") the source RCL within the same RSN)
+		 *
+		 * one thing we do know is that all of the resultsets underneath
+		 * us have their resultColumn names filled in with the names of
+		 * the target table columns.  That makes generating the mapping
+		 * "easier" -- we simply generate the names of the target table columns
+		 * that are included.  For the missing columns, we generate default
+		 * value expressions.
+		 */
+
+		if (resultSet instanceof SingleChildResultSetNode)
+		{
+			enhanceAndCheckForAutoincrement(
+				((SingleChildResultSetNode)resultSet).getChildResult(),
+				inOrder, numTableColumns, colMap, dataDictionary,
+				targetTableDescriptor, targetVTI);
+			if (! inOrder || resultSet.resultColumns.size() < numTableColumns)
+				resultSet.enhanceRCLForInsert(
+						numTableColumns, colMap, dataDictionary,
+						targetTableDescriptor, targetVTI);
+		}
+		else if (resultSet instanceof UnionNode)
+		{
+			enhanceAndCheckForAutoincrement(
+				((TableOperatorNode)resultSet).getLeftResultSet(),
+				inOrder, numTableColumns, colMap, dataDictionary,
+				targetTableDescriptor, targetVTI);
+			enhanceAndCheckForAutoincrement(
+				((TableOperatorNode)resultSet).getRightResultSet(),
+				inOrder, numTableColumns, colMap, dataDictionary,
+				targetTableDescriptor, targetVTI);
+			if (! inOrder || resultSet.resultColumns.size() < numTableColumns)
+				resultSet.enhanceRCLForInsert(
+						numTableColumns, colMap, dataDictionary,
+						targetTableDescriptor, targetVTI);
+		}
+		else
+		{
+			if (! inOrder || resultSet.resultColumns.size() < numTableColumns)
+				resultSet.enhanceRCLForInsert(
+						numTableColumns, colMap, dataDictionary,
+						targetTableDescriptor, targetVTI);
+			resultColumnList.checkAutoincrement(resultSet.getResultColumns());
+		}
 	}
 
 	int getPrivType()

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?view=diff&rev=487414&r1=487413&r2=487414
==============================================================================
--- 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
Thu Dec 14 17:01:14 2006
@@ -2253,36 +2253,6 @@
 	}
 
 	/**
-	 * If the resultset is a UnionNode (e.g., multi-rows in VALUES clause), we recursively call
itself.
-	 * checkAutoincrement() will set ColumnDescriptor for autoincrement columns.
-	 * This way, all ColumnDescriptor of all rows will be set properly.
-	 */
-	public void	checkAutoincrementUnion(ResultSetNode rs)
-		throws StandardException
-	{
-		ResultSetNode lrs = ((TableOperatorNode)rs).getLeftResultSet();
-		ResultSetNode rrs = ((TableOperatorNode)rs).getRightResultSet();
-
-		if (lrs instanceof UnionNode)
-		{
-			this.checkAutoincrementUnion(lrs);
-		}
-		else
-		{
-			this.checkAutoincrement(lrs.getResultColumns());
-		}
-
-		if (rrs instanceof UnionNode)
-		{
-			this.checkAutoincrementUnion(rrs);
-		}
-		else
-		{
-			this.checkAutoincrement(rrs.getResultColumns());
-		}
-	}
-
-	/**
 	 * Do the 2 RCLs have the same type & length.
 	 * This is useful for UNIONs when deciding whether a NormalizeResultSet is required.
 	 *

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultSetNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultSetNode.java?view=diff&rev=487414&r1=487413&r2=487414
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultSetNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultSetNode.java Thu
Dec 14 17:01:14 2006
@@ -1044,9 +1044,7 @@
 	 * This ResultSet is the source for an Insert.  The target RCL
 	 * is in a different order and/or a superset of this RCL.  In most cases
 	 * we will reorder and/or add defaults to the current RCL so that is
-	 * matches the target RCL.  Those RSNs whose generate() method does
-	 * not handle projects will insert a PRN, with a new RCL which matches
-	 * the target RCL, above the current RSN.
+	 * matches the target RCL.
 	 * NOTE - The new or enhanced RCL will be fully bound.
 	 *
 	 * @param numTargetColumns	# of columns in target RCL
@@ -1057,11 +1055,9 @@
 	 * @param targetTD			TableDescriptor for target if the target is not a VTI, null if a VTI
      * @param targetVTI         Target description if it is a VTI, null if not a VTI
 	 *
-	 * @return ResultSetNode	The new top of the tree
-	 *
 	 * @exception StandardException		Thrown on error
 	 */
-	public ResultSetNode enhanceRCLForInsert(int numTargetColumns, int[] colMap, 
+	public void enhanceRCLForInsert(int numTargetColumns, int[] colMap, 
 											 DataDictionary dataDictionary,
 											 TableDescriptor targetTD,
                                              FromVTI targetVTI)
@@ -1072,7 +1068,6 @@
 							(ResultColumnList) getNodeFactory().getNode(
 												C_NodeTypes.RESULT_COLUMN_LIST,
 												getContextManager());
-		int numResultSetColumns = resultColumns.size();
 
 		/* Create a massaged version of the source RCL.
 		 * (Much simpler to build new list and then assign to source,
@@ -1098,8 +1093,6 @@
 
 		/* Set the source RCL to the massaged version */
 		resultColumns = newResultCols;
-
-		return this;
 	}
 
 	/**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SetOperatorNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SetOperatorNode.java?view=diff&rev=487414&r1=487413&r2=487414
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SetOperatorNode.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SetOperatorNode.java
Thu Dec 14 17:01:14 2006
@@ -884,108 +884,6 @@
 	}
 
 	/**
-	 * This ResultSet is the source for an Insert.  The target RCL
-	 * is in a different order and/or a superset of this RCL.  In most cases
-	 * we will reorder and/or add defaults to the current RCL so that is
-	 * matches the target RCL.  Those RSNs whose generate() method does
-	 * not handle projects will insert a PRN, with a new RCL which matches
-	 * the target RCL, above the current RSN.
-	 * NOTE - The new or enhanced RCL will be fully bound.
-	 *
-	 * @param numTargetColumns	# of columns in target RCL
-	 * @param colMap			int array representation of correspondence between
-	 *							RCLs - colmap[i] = -1 -> missing in current RCL
-	 *								   colmap[i] = j -> targetRCL(i) <-> thisRCL(j+1)
-	 * @param dataDictionary	DataDictionary to use
-	 * @param targetTD			TableDescriptor for target if the target is not a VTI, null if a VTI
-     * @param targetVTI         Target description if it is a VTI, null if not a VTI
-	 *
-	 * @return ResultSetNode	The new top of the tree
-	 *
-	 * @exception StandardException		Thrown on error
-	 */
-	public ResultSetNode enhanceRCLForInsert(int numTargetColumns, int[] colMap, 
-											 DataDictionary dataDictionary,
-											 TableDescriptor targetTD,
-                                             FromVTI targetVTI)
-			throws StandardException
-	{
-		// our newResultCols are put into the bound form straight away.
-		ResultColumnList newResultCols =
-								(ResultColumnList) getNodeFactory().getNode(
-												C_NodeTypes.RESULT_COLUMN_LIST,
-												getContextManager());
-		int numResultSetColumns = resultColumns.size();
-
-		/* Create a massaged version of the source RCL.
-		 * (Much simpler to build new list and then assign to source,
-		 * rather than massage the source list in place.)
-		 */
-		for (int index = 0; index < numTargetColumns; index++)
-		{
-			ResultColumn	newResultColumn;
-			ResultColumn	oldResultColumn;
-			ColumnReference newColumnReference;
-
-			if (colMap[index] != -1)
-			{
-				// getResultColumn uses 1-based positioning, so offset the colMap entry appropriately
-				oldResultColumn = resultColumns.getResultColumn(colMap[index]+1);
-
-				newColumnReference = (ColumnReference) getNodeFactory().getNode(
-												C_NodeTypes.COLUMN_REFERENCE,
-												oldResultColumn.getName(),
-												null,
-												getContextManager());
-				/* The ColumnReference points to the source of the value */
-				newColumnReference.setSource(oldResultColumn);
-				// colMap entry is 0-based, columnId is 1-based.
-				newColumnReference.setType(oldResultColumn.getExpressionType());
-
-				// Source of an insert, so nesting levels must be 0
-				newColumnReference.setNestingLevel(0);
-				newColumnReference.setSourceLevel(0);
-
-				// because the insert already copied the target table's
-				// column descriptors into the result, we grab it from there.
-				// alternatively, we could do what the else clause does,
-				// and look it up in the DD again.
-				newResultColumn = (ResultColumn) getNodeFactory().getNode(
-						C_NodeTypes.RESULT_COLUMN,
-						oldResultColumn.getType(),
-						newColumnReference,
-						getContextManager());
-			}
-			else
-			{
-				newResultColumn = genNewRCForInsert(targetTD, targetVTI, index + 1, dataDictionary);
-			}
-
-			newResultCols.addResultColumn(newResultColumn);
-		}
-
-		/* The generated ProjectRestrictNode now has the ResultColumnList
-		 * in the order that the InsertNode expects.
-		 * NOTE: This code here is an exception to several "rules":
-		 *		o  This is the only ProjectRestrictNode that is currently
-		 *		   generated outside of preprocess().
-		 *	    o  The UnionNode is the only node which is not at the
-		 *		   top of the query tree which has ColumnReferences under
-		 *		   its ResultColumnList prior to expression push down.
-		 */
-		return (ResultSetNode) getNodeFactory().getNode(
-									C_NodeTypes.PROJECT_RESTRICT_NODE,
-									this,
-									newResultCols,
-									null,
-									null,
-									null,
-									null,
-									tableProperties,
-									getContextManager());
-	}
-
-	/**
 	 * Evaluate whether or not the subquery in a FromSubquery is flattenable.  
 	 * Currently, a FSqry is flattenable if all of the following are true:
 	 *		o  Subquery is a SelectNode. (ie, not a RowResultSetNode or a UnionNode)

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/autoincrement.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/autoincrement.out?view=diff&rev=487414&r1=487413&r2=487414
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/autoincrement.out
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/autoincrement.out
Thu Dec 14 17:01:14 2006
@@ -1929,4 +1929,98 @@
 1 row inserted/updated/deleted
 ij(CONN2)> INSERT INTO derby_1645 (TableId, StringValue) VALUES (-999, 'test3');
 1 row inserted/updated/deleted
+ij(CONN2)> -- Test cases related to DERBY-1644, which involve:
+--  a) multi-row VALUES clauses
+--  b) GENERATED BY DEFAULT autoincrement fields
+--  c) insert statements which mention only a subset of the table's columns
+-- First we have the actual case from the bug report. Then we have a number
+-- of other similar cases, to try to cover the code area in question
+create table D1644 (c1 int, c2 int generated by default as identity);
+0 rows inserted/updated/deleted
+ij(CONN2)> insert into D1644 (c2) values default, 10;
+2 rows inserted/updated/deleted
+ij(CONN2)> insert into D1644 (c2) values (11);
+1 row inserted/updated/deleted
+ij(CONN2)> insert into D1644 (c2) values default;
+1 row inserted/updated/deleted
+ij(CONN2)> insert into D1644 (c2) values (default);
+1 row inserted/updated/deleted
+ij(CONN2)> insert into D1644 (c2) values 12, 13, 14;
+3 rows inserted/updated/deleted
+ij(CONN2)> insert into D1644 (c2) values 15, 16, default;
+3 rows inserted/updated/deleted
+ij(CONN2)> insert into D1644 values (17, 18);
+1 row inserted/updated/deleted
+ij(CONN2)> insert into D1644 values (19, default);
+1 row inserted/updated/deleted
+ij(CONN2)> insert into D1644 values (20, default), (21, 22), (23, 24), (25, default);
+4 rows inserted/updated/deleted
+ij(CONN2)> insert into D1644 (c2, c1) values (default, 26);
+1 row inserted/updated/deleted
+ij(CONN2)> insert into D1644 (c2, c1) values (27, 28), (default, 29), (30, 31);
+3 rows inserted/updated/deleted
+ij(CONN2)> insert into D1644 (c2) values default, default, default, default;
+4 rows inserted/updated/deleted
+ij(CONN2)> insert into D1644 (c2, c1) values (default, 128),(default, 129),(default, 131);
+3 rows inserted/updated/deleted
+ij(CONN2)> select * from D1644;
+C1         |C2         
+-----------------------
+NULL       |1          
+NULL       |10         
+NULL       |11         
+NULL       |2          
+NULL       |3          
+NULL       |12         
+NULL       |13         
+NULL       |14         
+NULL       |15         
+NULL       |16         
+NULL       |4          
+17         |18         
+19         |5          
+20         |6          
+21         |22         
+23         |24         
+25         |7          
+26         |8          
+28         |27         
+29         |9          
+31         |30         
+NULL       |10         
+NULL       |11         
+NULL       |12         
+NULL       |13         
+128        |14         
+129        |15         
+131        |16         
+ij(CONN2)> create table D1644_A (c1 int, c2 int generated by default as identity, c3 int);
+0 rows inserted/updated/deleted
+ij(CONN2)> insert into D1644_A (c3, c1, c2) values (1, 2, default);
+1 row inserted/updated/deleted
+ij(CONN2)> insert into D1644_A (c3, c1, c2) values (3,4,5), (6,7,default);
+2 rows inserted/updated/deleted
+ij(CONN2)> insert into D1644_A (c3, c2) values (8, default), (9, 10);
+2 rows inserted/updated/deleted
+ij(CONN2)> select * from D1644_A;
+C1         |C2         |C3         
+-----------------------------------
+2          |1          |1          
+4          |5          |3          
+7          |2          |6          
+NULL       |3          |8          
+NULL       |10         |9          
+ij(CONN2)> create table D1644_B (c1 int generated by default as identity);
+0 rows inserted/updated/deleted
+ij(CONN2)> insert into D1644_B (c1) values default, 10;
+2 rows inserted/updated/deleted
+ij(CONN2)> insert into D1644_B values default, 10;
+2 rows inserted/updated/deleted
+ij(CONN2)> select * from D1644_B;
+C1         
+-----------
+1          
+10         
+2          
+10         
 ij(CONN2)> 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/autoincrement.sql
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/autoincrement.sql?view=diff&rev=487414&r1=487413&r2=487414
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/autoincrement.sql
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/autoincrement.sql
Thu Dec 14 17:01:14 2006
@@ -1027,3 +1027,36 @@
 INSERT INTO derby_1645 (StringValue) VALUES ('test53');
 INSERT INTO derby_1645 (TableId, StringValue) VALUES (-999, 'test3');
 
+-- Test cases related to DERBY-1644, which involve:
+--  a) multi-row VALUES clauses
+--  b) GENERATED BY DEFAULT autoincrement fields
+--  c) insert statements which mention only a subset of the table's columns
+-- First we have the actual case from the bug report. Then we have a number
+-- of other similar cases, to try to cover the code area in question
+create table D1644 (c1 int, c2 int generated by default as identity);
+insert into D1644 (c2) values default, 10;
+
+insert into D1644 (c2) values (11);
+insert into D1644 (c2) values default;
+insert into D1644 (c2) values (default);
+insert into D1644 (c2) values 12, 13, 14;
+insert into D1644 (c2) values 15, 16, default;
+insert into D1644 values (17, 18);
+insert into D1644 values (19, default);
+insert into D1644 values (20, default), (21, 22), (23, 24), (25, default);
+insert into D1644 (c2, c1) values (default, 26);
+insert into D1644 (c2, c1) values (27, 28), (default, 29), (30, 31);
+insert into D1644 (c2) values default, default, default, default;
+insert into D1644 (c2, c1) values (default, 128),(default, 129),(default, 131);
+select * from D1644;
+
+create table D1644_A (c1 int, c2 int generated by default as identity, c3 int);
+insert into D1644_A (c3, c1, c2) values (1, 2, default);
+insert into D1644_A (c3, c1, c2) values (3,4,5), (6,7,default);
+insert into D1644_A (c3, c2) values (8, default), (9, 10);
+select * from D1644_A;
+create table D1644_B (c1 int generated by default as identity);
+insert into D1644_B (c1) values default, 10;
+insert into D1644_B values default, 10;
+select * from D1644_B;
+



Mime
View raw message