db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Bryan Pendleton (JIRA)" <j...@apache.org>
Subject [jira] Commented: (DERBY-4244) ALTER TABLE Sanity ASSERT in add column with autocommit off
Date Mon, 06 Jul 2009 20:19:15 GMT

    [ https://issues.apache.org/jira/browse/DERBY-4244?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12727758#action_12727758
] 

Bryan Pendleton commented on DERBY-4244:
----------------------------------------

I spent some time stepping through the code and thinking about it.

The X0Y58 message is generated at line 541 of AlterTableConstantAction.java:

                            if (cdl.getPrimaryKey() != null)
                            {
                                throw StandardException.newException(
                                    SQLState.LANG_ADD_PRIMARY_KEY_FAILED1,
                                    td.getQualifiedName());
                            }

However, this error is generated *after* the new column has already been added
to the table, which occurs at line 450 of AlterTableConstantAction.java:

                if (columnInfo[ix].action == ColumnInfo.CREATE)
                {
                    addNewColumnToTable(activation, lcc, dd, tc, ix);
                }

addnewColumnToTable adds the new column to the table, then updates the
data in the new column to the default value, using a nested sub-statement. This
occurs at line 3199 of AlterTableConstantAction.java:

        String updateStmt = "UPDATE \"" + td.getSchemaName() + "\".\"" +
                            td.getName() + "\" SET \"" +
                             columnName + "\" = " + defaultText;


        AlterTableConstantAction.executeUpdate(lcc, updateStmt);

    private static void executeUpdate(LanguageConnectionContext lcc, String updateStmt) throws
StandardException
    {
        PreparedStatement ps = lcc.prepareInternalStatement(updateStmt);

        // This is a substatement; for now, we do not set any timeout
        // for it. We might change this behaviour later, by linking
        // timeout to its parent statement's timeout settings.
        ResultSet rs = ps.executeSubStatement(lcc, true, 0L);
        rs.close();
    }

So the stack trace, when this is going on, looks something like:

GenericPreparedStatements.executeStmt:443
GenericPreparedStatement.executeSubStatement:272
AlterTableConstantAction.executeUpdate:3209
AlterTableConstantAction.updateNewColumnToDefault:3199
AlterTableConstantAction.addNewColumnToTable:1374
AlterTableConstantAction.executeConstantAction:450
MiscResultSet.open:64
GenericPreparedStatement.executeStmt:416
GenericPreparedStatement.execute:297
EmbedStatement.executeStatement:1235

This leads me to two ideas:

1) Although the X0Y58 error causes the outer statement to be rolled back to
its savepoint, there must be something that occurs in the nested inner
sub-statement which isn't undone by rolling back the outer statement to
its savepoint. Specifically, something involving the descriptor information
in the DataDictionary. So we could try to investigate that more.

2) It seems odd that we only catch this error at *execution* time, after
we have already added the new column to the table, and set all its
default values, and only then do we notice that there's an error in the constraint.
I think that the duplicate constraint error should be something that we are
able to catch at *compile* time. So we could investigate the compile time
processing of ALTER TABLE ADD COLUMN, and try to figure out why
this error isn't being caught during compilation.



> ALTER TABLE Sanity ASSERT in add column with autocommit off
> -----------------------------------------------------------
>
>                 Key: DERBY-4244
>                 URL: https://issues.apache.org/jira/browse/DERBY-4244
>             Project: Derby
>          Issue Type: Bug
>          Components: SQL
>    Affects Versions: 10.2.1.6, 10.2.2.0, 10.3.1.4, 10.3.2.1, 10.3.3.0, 10.4.1.3, 10.4.2.0,
10.5.1.1, 10.6.0.0
>            Reporter: Bryan Pendleton
>            Assignee: Eranda Sooriyabandara
>            Priority: Minor
>
> While working with Eranda on DERBY-4187, I stumbled across an apparent ALTER TABLE bug.
> Here's a script which reproduces the problem for me:
> autocommit off;
> create table t0(c1 int not null constraint p1 primary key);
> alter table t0 add column c1 int;
> alter table t0 add column c2 int not null default 0 primary key;
> alter table t0 add column c2 int not null default 0;
> The "autocommit off" is crucial; otherwise the problem does not reproduce.
> Here's the detailed assertion failure:
> 2009-05-23 15:01:17.436 GMT Thread[main,5,main] (XID = 146), (SESSIONID = 1), (DATABASE
= brydb), (DRDAID = null), Failed Statement is: alter table t0 add column c2 int not null
default 0
> org.apache.derby.shared.common.sanity.AssertFailure: ASSERT FAILED column_id = 1format_ids.length
= 2format_ids = [I@1321f5
>         at org.apache.derby.shared.common.sanity.SanityManager.THROWASSERT(SanityManager.java:162)
>         at org.apache.derby.shared.common.sanity.SanityManager.THROWASSERT(SanityManager.java:147)
>         at org.apache.derby.impl.store.access.heap.Heap.addColumn(Heap.java:418)
>         at org.apache.derby.impl.store.access.RAMTransaction.addColumnToConglomerate(RAMTransaction.java:618)
>         at org.apache.derby.impl.sql.execute.AlterTableConstantAction.addNewColumnToTable(AlterTableConstantAction.java:1325)
>         at org.apache.derby.impl.sql.execute.AlterTableConstantAction.executeConstantAction(AlterTableConstantAction.java:449)
> Here's the relevant section of Heap.java:
>             if (column_id != format_ids.length)
>             {
>                 if (SanityManager.DEBUG)
>                     SanityManager.THROWASSERT(
>                         "column_id = " + column_id +
>                         "format_ids.length = " + format_ids.length +
>                         "format_ids = " + format_ids);
>                 throw(StandardException.newException(
>                         SQLState.HEAP_TEMPLATE_MISMATCH,
>                         new Long(column_id),
>                         new Long(this.format_ids.length)));
>             }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message