[ 
http://issues.apache.org/jira/browse/DERBY-1644?page=comments#action_12451063 ] 
            
Bryan Pendleton commented on DERBY-1644:
----------------------------------------

Thanks Army! I think that your observation is crucial, and here's why:

The problem arises due to this code in InsertNode.bind():

                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());

When the VALUES clause encounters multiple rows, it generates a UNION node tree 
to 
combine the rows to be inserted. The code above 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.

I believe that the way to solve this is to merge the above 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.

That way, even if the RowResultSetNode instances are buried within UnionNode 
trees, they
will still be correctly set up for autoincrement processing during bind 
processing.

I'll attach a complete patch to this Jira issue once I finish writing a bunch 
of tests
and tidying up the code changes.


> NPE when inserting values to a table that has a column declared as generated 
> by default as identity
> ---------------------------------------------------------------------------------------------------
>
>                 Key: DERBY-1644
>                 URL: http://issues.apache.org/jira/browse/DERBY-1644
>             Project: Derby
>          Issue Type: Bug
>          Components: SQL
>    Affects Versions: 10.2.1.6
>         Environment: Sun JDK 1.4.2
>            Reporter: Yip Ng
>         Assigned To: Bryan Pendleton
>            Priority: Minor
>
> The following scenario triggers a NullPointerException in statement 
> compilation:
> ij> create table t1 (c1 int, c2 int generated by default as identity);
> 0 rows inserted/updated/deleted
> ij> insert into t1 (c2) values default, 10;
> ERROR XJ001: Java exception: ': java.lang.NullPointerException'.
> Stacktrace from derby.log:
> Database Class Loader started - derby.database.classpath=''
> 2006-08-04 06:31:17.235 GMT Thread[main,5,main] (XID = 235), (SESSIONID = 0), 
> (DATABASE = wombat), (DRDAID = null), Cleanup action starting
> 2006-08-04 06:31:17.235 GMT Thread[main,5,main] (XID = 235), (SESSIONID = 0), 
> (DATABASE = wombat), (DRDAID = null), Failed Statement is: insert into t1 
> (c2) values default, 10
> java.lang.NullPointerException
>       at 
> org.apache.derby.impl.sql.compile.ResultColumnList.generateCore(ResultColumnList.java:1033)
>       at 
> org.apache.derby.impl.sql.compile.ResultColumnList.generate(ResultColumnList.java:893)
>       at 
> org.apache.derby.impl.sql.compile.RowResultSetNode.generate(RowResultSetNode.java:690)
>       at 
> org.apache.derby.impl.sql.compile.UnionNode.generate(UnionNode.java:589)
>       at 
> org.apache.derby.impl.sql.compile.ProjectRestrictNode.generateMinion(ProjectRestrictNode.java:1424)
>       at 
> org.apache.derby.impl.sql.compile.ProjectRestrictNode.generate(ProjectRestrictNode.java:1286)
>       at 
> org.apache.derby.impl.sql.compile.NormalizeResultSetNode.generate(NormalizeResultSetNode.java:122)
>       at 
> org.apache.derby.impl.sql.compile.InsertNode.generate(InsertNode.java:764)
>       at 
> org.apache.derby.impl.sql.compile.StatementNode.generate(StatementNode.java:232)
>       at 
> org.apache.derby.impl.sql.GenericStatement.prepMinion(GenericStatement.java:477)
>       at 
> org.apache.derby.impl.sql.GenericStatement.prepare(GenericStatement.java:118)
>       at 
> org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(GenericLanguageConnectionContext.java:713)
>       at 
> org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:567)
>       at 
> org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:516)
>       at org.apache.derby.impl.tools.ij.ij.executeImmediate(ij.java:313)
>       at org.apache.derby.impl.tools.ij.utilMain.doCatch(utilMain.java:478)
>       at 
> org.apache.derby.impl.tools.ij.utilMain.runScriptGuts(utilMain.java:347)
>       at org.apache.derby.impl.tools.ij.utilMain.go(utilMain.java:248)
>       at org.apache.derby.impl.tools.ij.Main.go(Main.java:203)
>       at org.apache.derby.impl.tools.ij.Main.mainCore(Main.java:169)
>       at org.apache.derby.impl.tools.ij.Main14.main(Main14.java:55)
>       at org.apache.derby.tools.ij.main(ij.java:69)
> sysinfo:
> ------------------ Java Information ------------------
> Java Version:    1.4.2_12
> Java Vendor:     Sun Microsystems Inc.
> Java home:       C:\jdk142\jre
> Java classpath:  classes;.
> OS name:         Windows XP
> OS architecture: x86
> OS version:      5.1
> Java user name:  yip
> Java user home:  C:\Documents and Settings\Administrator
> Java user dir:   C:\derby\trunk
> java.specification.name: Java Platform API Specification
> java.specification.version: 1.4
> --------- Derby Information --------
> JRE - JDBC: J2SE 1.4.2 - JDBC 3.0
> [C:\derby\trunk\classes] 10.2.0.5 alpha - (1)
> ------------------------------------------------------
> ----------------- Locale Information -----------------
> Current Locale :  [English/United States [en_US]]
> Found support for locale: [de_DE]
>          version: 10.2.0.5 alpha - (1)
> Found support for locale: [es]
>          version: 10.2.0.5 alpha - (1)
> Found support for locale: [fr]
>          version: 10.2.0.5 alpha - (1)
> Found support for locale: [it]
>          version: 10.2.0.5 alpha - (1)
> Found support for locale: [ja_JP]
>          version: 10.2.0.5 alpha - (1)
> Found support for locale: [ko_KR]
>          version: 10.2.0.5 alpha - (1)
> Found support for locale: [pt_BR]
>          version: 10.2.0.5 alpha - (1)
> Found support for locale: [zh_CN]
>          version: 10.2.0.5 alpha - (1)
> Found support for locale: [zh_TW]
>          version: 10.2.0.5 alpha - (1)
> ------------------------------------------------------

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to