Skip to content

Commit

Permalink
DERBY-6918: Problem with schema name containing a period
Browse files Browse the repository at this point in the history
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.



git-svn-id: https://svn.apache.org/repos/asf/db/derby/code/trunk@1772428 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
Bryan Pendleton committed Dec 3, 2016
1 parent 3ef48bb commit 43d83c6
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 8 deletions.
Expand Up @@ -95,6 +95,7 @@ abstract class DMLModStatementNode extends DMLStatementNode
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;
Expand Down Expand Up @@ -908,6 +909,7 @@ protected boolean hasGenerationClauses(TableDescriptor td)
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);
Expand Down Expand Up @@ -988,7 +990,8 @@ else if (cd instanceof ReferencedKeyConstraintDescriptor)
{
//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();
Expand Down Expand Up @@ -1056,13 +1059,15 @@ else if (cd instanceof ReferencedKeyConstraintDescriptor)
if (size > 0)
{
fkTableNames = new String[size];
fkSchemaNames = new String[size];
fkRefActions = new int[size];
fkColDescriptors = new ColumnDescriptorList[size];
fkIndexConglomNumbers = new long[size];
fkColArrays = new int[size][];
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);
Expand Down
13 changes: 6 additions & 7 deletions java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java
Expand Up @@ -368,7 +368,9 @@ else if (cursorTargetTableName != null)
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();
Expand Down Expand Up @@ -735,22 +737,19 @@ protected final int getStatementType()
* 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
Expand Down
Expand Up @@ -1350,4 +1350,56 @@ public void testSharedConglomerates() throws SQLException {
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\"");
}
}

0 comments on commit 43d83c6

Please sign in to comment.