db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "A B (JIRA)" <derby-...@db.apache.org>
Subject [jira] Updated: (DERBY-1329) ASSERT failure/IndexOutOfBoundsException with correlated subquery for UPDATE ... SET ... WHERE CURRENT OF ... statement.
Date Thu, 25 May 2006 15:26:30 GMT
     [ http://issues.apache.org/jira/browse/DERBY-1329?page=all ]

A B updated DERBY-1329:
-----------------------

    Attachment: d1329.patch

Attaching a patch to address this issue.  In a word, the problem is that the ColumnReference
in a CurrentOfNode can, in certain situations, end up with a tableNumber that is never set,
and hence it defaults to -1.  The fix I've made ensures that the ColumnReference's tableNumber
will always be set when necessary--i.e. when we've found the ResultColumn that matches the
received ColumnReference.  I think this is the correct fix for two reasons:

1) In FromList.bindColumnReferences(), there is the following comment:

  /* TableNumbers are set in the CR in the underlying
   * FromTable.  This ensures that they get the table
   * number from the underlying table, not the join node.
   * This is important for beging able to push predicates 
   * down through join nodes.
   */

The place where "TableNumbers are set" is in the getMatchingColumn() call, which means that
the underlying FromTable (which includes CurrentOfNode) is responsible for setting the table
number.

2) Inspection of all other FromTables that implement getMatchingColumn() shows that they all
set the ColumnReference's table number if the corresponding ResultColumn is found.  The one
exception is JoinNode, but the getMatchingColumn() method in JoinNode in turn calls the method
of the same name on the join's left and right nodes, so we know that, eventually, the ColumnReference's
tableNumber will get set by one of the other FromTable's getMatchingColumn() calls.  So the
only FromTable that does not set the tableNumber is CurrentOfNode, and that's the reason for
the failure described in this issue.

The change seems fairly minor but if anyone has a chance to double-check it, that'd be great.
 I also added a test case (using the repro posted in the above comments) to lang/update.sql.

I ran derbyall on Linux Red Hat (RHEL4) using ibm142 and saw no new failures.

Thanks,
Army

> ASSERT failure/IndexOutOfBoundsException with correlated subquery for UPDATE ... SET
... WHERE CURRENT OF ... statement.
> ------------------------------------------------------------------------------------------------------------------------
>
>          Key: DERBY-1329
>          URL: http://issues.apache.org/jira/browse/DERBY-1329
>      Project: Derby
>         Type: Bug

>   Components: SQL
>     Versions: 10.0.2.0, 10.0.2.1, 10.1.1.0, 10.2.0.0, 10.1.2.0, 10.1.1.1, 10.1.1.2, 10.1.2.1,
10.1.2.2, 10.1.2.3, 10.1.2.4
>     Reporter: A B
>     Assignee: A B
>     Priority: Minor
>      Fix For: 10.2.0.0, 10.1.3.0
>  Attachments: d1329.java, d1329.patch
>
> If in a statement of the form "UPDATE ... SET ... WHERE CURRENT OF ..." the SET clause
includes a correlated subquery that has a predicate referencing the table that is being updated,
Derby will fail with an ASSERT failure in sane mode and an IndexOutOfBounds exception in insane
mode.
> For example, if we have a cursor CUR1 for the results of a SELECT query on BASICTABLE1,
and then we try to execute the following update statement:
> update BASICTABLE1 set C3 = (SELECT CC3 FROM
>   BASICTABLE2 WHERE BASICTABLE1.ID=BASICTABLE2.IID) 
> where current of CUR1
> the result in SANE mode will be:
> org.apache.derby.shared.common.sanity.AssertFailure: ASSERT FAILED tableNumber is expected
to be non-negative.
> and in INSANE mode will be:
> java.lang.IndexOutOfBoundsException: bitIndex < 0: -1
> The failure occurs during preprocessing of the subquery node when Derby is trying to
"categorize" a predicate to see if it is pushable.  The exact code is in ColumnReference.categorize():
>   public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly)
>   {
>     if (SanityManager.DEBUG)
>       SanityManager.ASSERT(tableNumber >= 0,
>          "tableNumber is expected to be non-negative");
>     referencedTabs.set(tableNumber);
>     return ( ! replacesAggregate ) &&
>         ( (source.getExpression() instanceof ColumnReference) ||
>         (source.getExpression() instanceof VirtualColumnNode) ||
>         (source.getExpression() instanceof ConstantNode));
>   }
> We get to this code for a ColumnReference who's tableNumber is -1, which means that,
in sane mode, the assert will fire; in insane mode, we'll call "referencedTabs.set()" passing
in a -1, which leads to the IndexOutOfBoundsException.
> This failure occurs in embedded and with both clients, and occurs in 10.0, 10.1, and
the 10.2 trunk.

-- 
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


Mime
View raw message