db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bpendle...@apache.org
Subject svn commit: r1772428 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/sql/compile/ testing/org/apache/derbyTesting/functionTests/tests/lang/
Date Sat, 03 Dec 2016 03:54:46 GMT
Author: bpendleton
Date: Sat Dec  3 03:54:46 2016
New Revision: 1772428

URL: http://svn.apache.org/viewvc?rev=1772428&view=rev
Log:
DERBY-6918: Problem with schema name containing a period

When processing DELETE statements in a database schema including
referential integrity constraints that specify ON DELETE CASCADE,
it is easiest to keep the schema name and table name separate,
rather than pasting them together into a compound name joined with
a period, because pasting them together results in ambiguity about
which period separates the schema name from the table name, and
which period was simply part of the schema name proper.

Adjusted the logic in DeleteNode and DMLModStatementNode accordingly.


Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ForeignKeysDeferrableTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java?rev=1772428&r1=1772427&r2=1772428&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java
Sat Dec  3 03:54:46 2016
@@ -95,6 +95,7 @@ abstract class DMLModStatementNode exten
 	private ValueNode		checkConstraints;
 
 	/* Info required to perform referential actions */
+	protected String[] fkSchemaNames; // referencing schema names.
 	protected String[] fkTableNames; // referencing table names.
 	protected int[] fkRefActions;    //type of referential actions 
 	protected ColumnDescriptorList[]  fkColDescriptors;
@@ -908,6 +909,7 @@ abstract class DMLModStatementNode exten
         int[]                               raRules;
         boolean[]                           deferrable;
         UUID[]                              fkIds;
+		ArrayList<String>              refSchemaNames = new ArrayList<String>(1);
 		ArrayList<String>              refTableNames = new ArrayList<String>(1);
 		ArrayList<Long>               refIndexConglomNum = new ArrayList<Long>(1);
 		ArrayList<Integer>            refActions = new ArrayList<Integer>(1);
@@ -988,7 +990,8 @@ abstract class DMLModStatementNode exten
 					{
 						//find  the referencing  table Name
 						fktd = fkcd.getTableDescriptor();
-						refTableNames.add(fktd.getSchemaName() + "." + fktd.getName());
+						refSchemaNames.add(fktd.getSchemaName());
+						refTableNames.add(fktd.getName());
                         refActions.add(Integer.valueOf(raRules[inner]));
 						//find the referencing column name required for update null.
 						refColumns = fkcd.getReferencedColumns();
@@ -1056,6 +1059,7 @@ abstract class DMLModStatementNode exten
 		if (size > 0)
 		{
 			fkTableNames = new String[size];
+			fkSchemaNames = new String[size];
 			fkRefActions  = new int[size];
 			fkColDescriptors = new ColumnDescriptorList[size];
 			fkIndexConglomNumbers = new long[size];
@@ -1063,6 +1067,7 @@ abstract class DMLModStatementNode exten
 			for (int i = 0; i < size; i++)
 			{
 				fkTableNames[i] = refTableNames.get(i);
+				fkSchemaNames[i] = refSchemaNames.get(i);
 				fkRefActions[i]  = (refActions.get(i)).intValue();
 				fkColDescriptors[i] =
 					refColDescriptors.get(i);

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java?rev=1772428&r1=1772427&r2=1772428&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java Sat
Dec  3 03:54:46 2016
@@ -368,7 +368,9 @@ class DeleteNode extends DMLModStatement
 					dependentNodes = new StatementNode[noDependents];
 					for(int i =0 ; i < noDependents ; i ++)
 					{
-						dependentNodes[i] = getDependentTableNode(fkTableNames[i],
+						dependentNodes[i] = getDependentTableNode(
+															  fkSchemaNames[i],
+															  fkTableNames[i],
 															  fkRefActions[i],
 															  fkColDescriptors[i]);
 						dependentNodes[i].bindStatement();
@@ -735,22 +737,19 @@ class DeleteNode extends DMLModStatement
 	 * DML (UPDATE or DELETE) on the dependent tables. 
 	 * Following function returns the DML Node for the dependent table.
 	 */
-	private StatementNode getDependentTableNode(String tableName, int refAction,
+	private StatementNode getDependentTableNode(String schemaName, String tableName, int refAction,
 												ColumnDescriptorList cdl) throws StandardException
 	{
         DMLModStatementNode node = null;
 
-		int index = tableName.indexOf('.');
-		String schemaName = tableName.substring(0 , index);
-		String tName = tableName.substring(index+1);
 		if(refAction == StatementType.RA_CASCADE)
 		{
-			node = getEmptyDeleteNode(schemaName , tName);
+			node = getEmptyDeleteNode(schemaName , tableName);
 		}
 
 		if(refAction == StatementType.RA_SETNULL)
 		{
-			node = getEmptyUpdateNode(schemaName , tName, cdl);
+			node = getEmptyUpdateNode(schemaName , tableName, cdl);
 		}
 
         // The dependent node should be marked as such, and it should inherit

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ForeignKeysDeferrableTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ForeignKeysDeferrableTest.java?rev=1772428&r1=1772427&r2=1772428&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ForeignKeysDeferrableTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ForeignKeysDeferrableTest.java
Sat Dec  3 03:54:46 2016
@@ -1350,4 +1350,56 @@ public class ForeignKeysDeferrableTest e
             assertTrue( dsicve.getConstraintName().startsWith( "SQL" ) );
         }
     }
+
+    /* Regression test for DERBY-6918, which is not directly related
+     * to deferrable foreign key constraints. But this was a convenient
+     * and simple place to add the regression test.
+     */
+    public void testDerby6918()
+                throws SQLException
+    {
+        Statement s = createStatement();
+        s.execute("create schema \"1.a\"");
+        s.execute("create table \"1.a\".\"role\" " +
+                   "( \"id\" integer generated always as identity," +
+                   "  \"name\" varchar(255) not null)" );
+
+        s.execute("alter table \"1.a\".\"role\" " +
+                  "  add constraint \"role_pk\" primary key (\"id\")");
+
+        s.execute("create table \"1.a\".\"user\"" +
+                  " ( \"id\" integer generated always as identity," +
+                  "   \"name\" varchar(255) not null)");
+
+        s.execute("alter table \"1.a\".\"user\" " +
+                  "  add constraint \"user_pk\" primary key (\"id\")");
+
+        s.execute("create table \"1.a\".\"user_role\" " +
+                  " ( \"role\" integer not null," +
+                  "   \"user\" integer not null)");
+
+        s.execute("alter table \"1.a\".\"user_role\"" +
+                  " add constraint \"user_role_fk1\" " +
+                  "     foreign key (\"role\") " +
+                  "     references \"1.a\".\"role\" (\"id\")" +
+                  "     on delete cascade");
+
+        s.execute("alter table \"1.a\".\"user_role\"" +
+                  " add constraint \"user_role_fk2\"" +
+                  "     foreign key (\"user\")" +
+                  "     references \"1.a\".\"user\" (\"id\")" +
+                  "     on delete cascade");
+
+        s.execute("alter table \"1.a\".\"user_role\"" +
+                  "  add constraint \"user_role_u1\"" +
+                  "      unique (\"user\", \"role\")");
+
+        s.execute("insert into \"1.a\".\"role\" (\"name\") values ('r1')");
+        s.execute("insert into \"1.a\".\"user\" (\"name\") values ('u1')");
+        s.execute("insert into \"1.a\".\"user_role\" (\"role\",\"user\") values (1,1)");
+
+        s.execute("select * from \"1.a\".\"user\"");
+
+        s.execute("delete from \"1.a\".\"user\"");
+    }
 }



Mime
View raw message