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

Dag H. Wanvik edited comment on DERBY-4413 at 10/19/09 5:37 AM:
----------------------------------------------------------------

If I use a default value rather than a GENERATED ALWAYS AS, it works
as expected.

It seems the generated values are computed deferredly,
i.e. when row is to be inserted (InsertResultSet), whereas default
values are generated along with the rest of the columns. This causes a
problem for the sorter in the former case.

Default values are handled via this logic:

Cf. InsertNode#bindStatement -> InsertNode#enhanceAndCheckForAutoincrement ->
    ResultSetNode#enhanceRCLForInsert -> genNewRCForInsert (ca line 1149)

whereas generated columns are explicitly deferred in that code
and handled here:
    InsertNode#bindStatement -> parseAndBindGenerationClauses

Since generated columns are not bound down through the "enhanced"
result set's RCL, code is not generated for the "null" constants left
by enhanceRCLForInsert, and the sorter crashes.

Note that the RC has an expression containing an untyped NULL,
so it seems the column is not well-formed when the sorter sees it.

                        org.apache.derby.impl.sql.compile.resultcol...@9dca26
                        exposedName: null
                        name: J
                        tableName: null
                        isDefaultColumn: false
                        wasDefaultColumn: false
                        isNameGenerated: false
                        sourceTableName: null
                        type: INTEGER NOT NULL
                        columnDescriptor: columnName: J
                        columnPosition: 2
                        columnType: INTEGER NOT NULL
                        columnDefault: null
                        uuid: eb0f4097-0124-6cc9-1ba1-000003db0968
                        defaultUUID: c3350098-0124-6cc9-1ba1-000003db0968
                        
                        isGenerated: false
                        isGeneratedForUnmatchedColumnInInsert: true
                        isGroupingColumn: false
                        isReferenced: true
                        isRedundant: false
                        virtualColumnId: 2
                        resultSetNumber: -1
                        dataTypeServices: INTEGER NOT NULL
                        expression:                             
                                
org.apache.derby.impl.sql.compile.untypednullconstantn...@1429cb2
                                value: null
                                dataTypeServices: null


      was (Author: dagw):
    If I use a default value rather than a GENERATED ALWAYS AS, it works
as expected.

It seems the generated values are computed deferredly,
i.e. when row is to be inserted (InsertResultSet), whereas default
values are generated along with the rest of the columns. This causes a
problem for the sorter in the former case (stack trace, see end of mail).

Default values are handled via this logic:

Cf. InsertNode#bindStatement -> InsertNode#enhanceAndCheckForAutoincrement ->
    ResultSetNode#enhanceRCLForInsert -> genNewRCForInsert (ca line 1149)

whereas generated columns are explicitly deferred in that code
and handled here:
    InsertNode#bindStatement -> parseAndBindGenerationClauses

Since generated columns are not bound down through the "enhanced"
result set's RCL, code is not generated for the "null" constants left
by enhanceRCLForInsert, and the sorter crashes.

Note that the RC has an expression containing an untyped NULL,
so it seems the column is not well-formed when the sorter sees it.

                        org.apache.derby.impl.sql.compile.resultcol...@9dca26
                        exposedName: null
                        name: J
                        tableName: null
                        isDefaultColumn: false
                        wasDefaultColumn: false
                        isNameGenerated: false
                        sourceTableName: null
                        type: INTEGER NOT NULL
                        columnDescriptor: columnName: J
                        columnPosition: 2
                        columnType: INTEGER NOT NULL
                        columnDefault: null
                        uuid: eb0f4097-0124-6cc9-1ba1-000003db0968
                        defaultUUID: c3350098-0124-6cc9-1ba1-000003db0968
                        
                        isGenerated: false
                        isGeneratedForUnmatchedColumnInInsert: true
                        isGroupingColumn: false
                        isReferenced: true
                        isRedundant: false
                        virtualColumnId: 2
                        resultSetNumber: -1
                        dataTypeServices: INTEGER NOT NULL
                        expression:                             
                                
org.apache.derby.impl.sql.compile.untypednullconstantn...@1429cb2
                                value: null
                                dataTypeServices: null

  
> INSERT from SELECT DISTINCT gives assertFailure (sane), or  NPE (insane) in 
> presence of generated columns
> ---------------------------------------------------------------------------------------------------------
>
>                 Key: DERBY-4413
>                 URL: https://issues.apache.org/jira/browse/DERBY-4413
>             Project: Derby
>          Issue Type: Bug
>          Components: SQL
>    Affects Versions: 10.5.3.0
>            Reporter: Dag H. Wanvik
>
> When a generated column is present in a table, an INSERT DISTINCT fail:
> Repro:
> create table t(i integer, 
>                j integer not null generated always as (i*66));
> insert into t(i) values 1,2;
> insert into t(i) select distinct i from t;
> In an insane build we see this assertFailure:
> ij version 10.5
> ij> connect 'jdbc:derby:wombat2;create=true';
> ij> create table t(i integer, 
>                j integer not null generated always as (i*66));
> 0 rows inserted/updated/deleted
> ij> insert into t(i) values 1,2;
> 2 rows inserted/updated/deleted
> ij> insert into t(i) select distinct i from t;
> ERROR XJ001: Java exception: 'ASSERT FAILED col[1]  is null: 
> org.apache.derby.shared.common.sanity.AssertFailure'.
> java.sql.SQLException: Java exception: 'ASSERT FAILED col[1]  is null: 
> org.apache.derby.shared.common.sanity.AssertFailure'.
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(SQLExceptionFactory40.java:95)
>       at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Util.java:87)
>       at org.apache.derby.impl.jdbc.Util.javaException(Util.java:244)
>       at 
> org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java:403)
>       at 
> org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(TransactionResourceImpl.java:346)
>       at 
> org.apache.derby.impl.jdbc.EmbedConnection.handleException(EmbedConnection.java:2201)
>       at 
> org.apache.derby.impl.jdbc.ConnectionChild.handleException(ConnectionChild.java:81)
>       at 
> org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1323)
>       at 
> org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:625)
>       at 
> org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:555)
>       at org.apache.derby.impl.tools.ij.ij.executeImmediate(ij.java:329)
>       at org.apache.derby.impl.tools.ij.utilMain.doCatch(utilMain.java:505)
>       at 
> org.apache.derby.impl.tools.ij.utilMain.runScriptGuts(utilMain.java:347)
>       at org.apache.derby.impl.tools.ij.utilMain.go(utilMain.java:245)
>       at org.apache.derby.impl.tools.ij.Main.go(Main.java:217)
>       at org.apache.derby.impl.tools.ij.Main.mainCore(Main.java:184)
>       at org.apache.derby.impl.tools.ij.Main.main(Main.java:75)
>       at org.apache.derby.tools.ij.main(ij.java:59)
>       at org.apache.derby.iapi.tools.run.main(run.java:53)
> Caused by: java.sql.SQLException: Java exception: 'ASSERT FAILED col[1]  is 
> null: org.apache.derby.shared.common.sanity.AssertFailure'.
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:45)
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(SQLExceptionFactory40.java:119)
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(SQLExceptionFactory40.java:70)
>       ... 18 more
> Caused by: org.apache.derby.shared.common.sanity.AssertFailure: ASSERT FAILED 
> col[1]  is null
>       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.sort.MergeSort.checkColumnTypes(MergeSort.java:458)
>       at 
> org.apache.derby.impl.store.access.sort.MergeInserter.insert(MergeInserter.java:98)
>       at 
> org.apache.derby.impl.sql.execute.SortResultSet.loadSorter(SortResultSet.java:317)
>       at 
> org.apache.derby.impl.sql.execute.SortResultSet.openCore(SortResultSet.java:268)
>       at 
> org.apache.derby.impl.sql.execute.NormalizeResultSet.openCore(NormalizeResultSet.java:139)
>       at 
> org.apache.derby.impl.sql.execute.InsertResultSet.open(InsertResultSet.java:415)
>       at 
> org.apache.derby.impl.sql.GenericPreparedStatement.executeStmt(GenericPreparedStatement.java:416)
>       at 
> org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:297)
>       at 
> org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1235)
>       ... 11 more

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

Reply via email to