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

Mamta A. Satoor commented on DERBY-6786:
----------------------------------------

You are correct Johannes. Just want to share some more information from my 
debugging which enforces your point.

First of all, for reference purposes, here are the tables we are dealing with 
following tables
create table k1 (k varchar(64), s decimal);
create table k2 (k varchar(64), s decimal);
create table t (s decimal);

And one of the queries that may result in npe (depending on what data is in the 
tables) is as follows
insert into t
 select erg.* from (
  select d2.s from (select k,s from k1) as d1
   left join (select k,s from k2) as d2 on d1.k=d2.k
  ) as erg
 where s > 10;

For the query above, we generate various internal Derby resultsets. The issue 
appears to be what resultset gets associated to column s in predicate where s > 
10. It would seem that for this predicate, column s should be associated with 
the internal resulset created for outermost select which is select erg.*. 
Instead, it looks like it is getting associated with the 2nd select in the join 
clause which is (select k,s from k2) as d2

Lets look at the contents of these two internal resultsets for different data 
in tables k1 and k2 to understand the NPE better.
case 1) 
Let's say the only data into the two tables is
delete from k1;
delete from k2;
insert into k1 values ('110007', 224);
insert into k2 values ('110007', 361);

For this data, the join above will result into a match because both k1 and k2 
have '110007' for column k. The contents of resultset for (select k,s from k2) 
as d2 is { 110007, 361 } and the merged row looks like { 110007, 224, 110007, 
361 }. Here, even though predicate column s is incorrectly associated with 
internal resultset for (select k,s from k2) as d2, we will not get a npe 
because that resultset for the given data is not null(because there was a 
matching row in table k2.)

Case 2)
Let's say the only data into the two tables is
delete from k1;
delete from k2;
insert into k1 values ('110007', 224);
insert into k2 values ('110007', null);

Again, for this data, the join above will result into a match because both k1 
and k2 have '110007' for column k. The contents of resultset for (select k,s 
from k2) as d2 is { 110007, NULL } and the merged row looks like { 110007, 224, 
110007, 361 }. For this case again, we will not get a npe because the resultset 
associated with (select k,s from k2) as d2 is not null (because there was a 
matching row in table k2.)

Case 3)
This is the case where we run into NPE.
Let's say the only data into the two tables is
delete from k1;
delete from k2;
insert into k1 values ('110007', 224);
insert into k2 values ('110019', 361);

For this data, the join above will not find a matching row in k2. Because of 
this, the resultset associated with (select k,s from k2) as d2 will be null but 
the merged row will look like { 110007, 224, NULL, NULL }. Predicate where s > 
10 association with resultset for (select k,s from k2) as d2 I believe is the 
cause of npe. It seems like we should be looking at the merged row resultset to 
find predicate s's value. Doing that will work for all the 3 cases covered 
here. 

It will appear that to fix the issue, we will need to fix the predicate's 
assoication with correct resulset and that will automatically generate the 
correct run time behavior.


> NullPointerException in INSERT INTO statement with multiple subselects
> ----------------------------------------------------------------------
>
>                 Key: DERBY-6786
>                 URL: https://issues.apache.org/jira/browse/DERBY-6786
>             Project: Derby
>          Issue Type: Bug
>          Components: SQL
>    Affects Versions: 10.2.2.0, 10.5.1.1, 10.8.2.2, 10.9.1.0, 10.10.1.1, 
> 10.11.1.1
>         Environment: not relevant, but tested under Windows 7 32bit, Windows 
> Server 2008 64bit, Java 6 and Java 7.
>            Reporter: Johannes Stadler
>              Labels: NullPointerException
>         Attachments: acaaeec04ex014axaa2ex076bx000000c72a081.java, repro.sql
>
>
> Hello,
> I'm getting this wrapped NullPointerException when I try to execute an INSERT 
> INTO SQL statement:
> java.sql.SQLException: The exception 'java.lang.NullPointerException' was 
> thrown while evaluating an expression.
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(SQLExceptionFactory40.java:101)
>       at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Util.java:148)
>       at org.apache.derby.impl.jdbc.Util.seeNextException(Util.java:349)
>       at 
> org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java:431)
>       at 
> org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(TransactionResourceImpl.java:353)
>       at 
> org.apache.derby.impl.jdbc.EmbedConnection.handleException(EmbedConnection.java:2400)
>       at 
> org.apache.derby.impl.jdbc.ConnectionChild.handleException(ConnectionChild.java:85)
>       at 
> org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1437)
>       at 
> org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:711)
>       at 
> org.apache.derby.impl.jdbc.EmbedStatement.executeLargeUpdate(EmbedStatement.java:190)
>       at 
> org.apache.derby.impl.jdbc.EmbedStatement.executeUpdate(EmbedStatement.java:179)
>       at 
> de.foconis.dakobp.unittests.div.TestMain.testNullpointer(TestMain.java:49)
>       at de.foconis.dakobp.unittests.div.TestMain.main(TestMain.java:28)
> Caused by: java.sql.SQLException: The exception 
> 'java.lang.NullPointerException' was thrown while evaluating an expression.
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:42)
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(SQLExceptionFactory40.java:125)
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(SQLExceptionFactory40.java:71)
>       ... 12 more
> Caused by: java.sql.SQLException: Java exception: ': 
> java.lang.NullPointerException'.
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:42)
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(SQLExceptionFactory40.java:125)
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(SQLExceptionFactory40.java:71)
>       at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Util.java:148)
>       at org.apache.derby.impl.jdbc.Util.javaException(Util.java:370)
>       at 
> org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java:436)
>       ... 10 more
> Caused by: java.lang.NullPointerException
>       at 
> org.apache.derby.exe.acf81e0010x014axa9c2x46e6x000000c6dc781.e2(Unknown 
> Source)
>       at 
> org.apache.derby.impl.services.reflect.DirectCall.invoke(ReflectGeneratedClass.java:105)
>       at 
> org.apache.derby.impl.sql.execute.ProjectRestrictResultSet.getNextRowCore(ProjectRestrictResultSet.java:275)
>       at 
> org.apache.derby.impl.sql.execute.ProjectRestrictResultSet.getNextRowCore(ProjectRestrictResultSet.java:263)
>       at 
> org.apache.derby.impl.sql.execute.DMLWriteResultSet.getNextRowCore(DMLWriteResultSet.java:127)
>       at 
> org.apache.derby.impl.sql.execute.InsertResultSet.open(InsertResultSet.java:519)
>       at 
> org.apache.derby.impl.sql.GenericPreparedStatement.executeStmt(GenericPreparedStatement.java:461)
>       at 
> org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:340)
>       at 
> org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1344)
>       ... 5 more
> Most likely this bug has already been reported as DERBY-5041, which has 
> already been closed (although I don't use a GROUP BY clause).
> The original statement is quite complex and partially generated, but the 
> error can be reproduced easily, using a statement as simple as this:
> insert into t
>  select erg.* from (
>   select d1.s from (select k,s from k1) as d1
>    right join (select k,s from k2) as d2 on d1.k = d2.k
>   ) as erg
>  where s > 10
> I will attach the file "repro.sql", containing all SQL statements required to 
> reproduce it (including the CREATE TABLEs).
> These are my investigation results:
> Conditions
> -------------
> 1. the outermost statement must NOT be a SELECT (e. g. INSERT)
> 2. there has to be a outer join in the subselect, where at least one dataset 
> has no join partner
> 3. an outer SELECT must have a restriction (WHERE clause) and access a column 
> from the table, that did not have a join partner
> Error state
> -------------
> The NullPointer occurs inside a generated class. So i enabled the Debug 
> Option "DumpClassFile", to get the generated class file (the decompiled java 
> class file will also be appended).
> The method "e2", stated in the StackTrace, performs the restrction "where s > 
> 10". Therefore it calls getColumnFromRow() with its resultSetNumber.
> This is where the error occurs: there is no "current row" available. 
> Precisely, the "row" property of the activation class at the specified index 
> (which is the resultSetNumber=3 in this example) is not set.
> It gets a bit complicated now, I will try to explain it, starting with the 
> generated resultset hierarchy.
> This tree of resultset implementations is generated to perform the query:
> Implementation                                resultSetNumber
> -------------------                           ---------------------
> InsertResultSet                       -> none
>  ProjectRestrictResultSet             -> 5
>   ProjectRestrictResultSet    -> 4
>    HashLeftOuterJoinResultSet -> 0
>     TableScanResultSet                -> 1
>     HashTableResultSet                -> 3
>      TableScanResultSet               -> 2
> The HashTableResultSet, which got the resultSetNumber 3 doesn't set a current 
> row, because there is no join partner (still everything correct). But the 
> ProjectRestrictResultSet on position 4 uses the restriction method ("e2"), 
> which accesses a column on resultSetNumber 3 -> error.
> As far as I can tell, a restriction must never relate to the source of an 
> outer join ResultSet. The numeration error does not occur, if the outermost 
> statement is a SELECT and the numeration is generated top-down.
> Unfortunately I couldn't find an easy solution for this problem. In my case, 
> this is a critical bug, because changing the query as workaround is 
> difficult, since parts of it are generated. Please note, that this error is 
> not dependent on any environment settings or platform and occured with all of 
> the abolve mentioned versions. I didn't test the versions from 10.6 to 10.7, 
> but probably those are also affected.
> If you require any further information, please let me know. I'm able to 
> perform a build, so I wouldn't need a full version, a patch would be 
> sufficient.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to