Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 84504 invoked from network); 25 Nov 2007 21:07:09 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 25 Nov 2007 21:07:09 -0000 Received: (qmail 92485 invoked by uid 500); 25 Nov 2007 21:06:57 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 92451 invoked by uid 500); 25 Nov 2007 21:06:57 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 92438 invoked by uid 99); 25 Nov 2007 21:06:57 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 25 Nov 2007 13:06:57 -0800 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 25 Nov 2007 21:06:46 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 98A371A9832; Sun, 25 Nov 2007 13:06:48 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r598054 - in /db/derby/code/branches/10.3/java: engine/org/apache/derby/impl/sql/compile/CoalesceFunctionNode.java testing/org/apache/derbyTesting/functionTests/tests/lang/CoalesceTest.java Date: Sun, 25 Nov 2007 21:06:48 -0000 To: derby-commits@db.apache.org From: dag@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20071125210648.98A371A9832@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: dag Date: Sun Nov 25 13:06:47 2007 New Revision: 598054 URL: http://svn.apache.org/viewvc?rev=598054&view=rev Log: DERBY-2016 ArrayIndexOutOfBoundsException for COALESCE with aggregate functions Merged from trunk: svn merge -r 597277:597278 https://svn.apache.org/repos/asf/db/derby/code/trunk This is patch DERBY-2016d. Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/compile/CoalesceFunctionNode.java db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CoalesceTest.java Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/compile/CoalesceFunctionNode.java URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/compile/CoalesceFunctionNode.java?rev=598054&r1=598053&r2=598054&view=diff ============================================================================== --- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/compile/CoalesceFunctionNode.java (original) +++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/compile/CoalesceFunctionNode.java Sun Nov 25 13:06:47 2007 @@ -105,7 +105,12 @@ { String functionName; //Are we here because of COALESCE function or VALUE function ValueNodeList argumentsList; //this is the list of arguments to the function. We are interested in the first not-null argument - ValueNode firstNonParameterNode;//The generated method will generate code to call coalesce on this non-parameter argument + + /** + * The generated method will generate code to call coalesce on + * this non-parameter argument. + */ + private int firstNonParameterNodeIdx = -1; /** * Initializer for a CalesceFunctionNode @@ -152,7 +157,7 @@ { if (!(((ValueNode) argumentsList.elementAt(index)).requiresTypeFromContext())) { - firstNonParameterNode = (ValueNode) argumentsList.elementAt(index); + firstNonParameterNodeIdx = index; break; } } @@ -279,7 +284,10 @@ ** Next, if we are dealing with result type that is variable length, then generate a call to setWidth. */ - firstNonParameterNode.generateExpression(acb, mb); //coalesce will be called on this non-parameter argument + // coalesce will be called on this non-parameter argument + ((ValueNode) argumentsList.elementAt(firstNonParameterNodeIdx)). + generateExpression(acb, mb); + mb.upCast(ClassName.DataValueDescriptor); mb.getField(arrayField); // first arg to the coalesce function @@ -411,7 +419,8 @@ if (SanityManager.DEBUG) { super.printSubNodes(depth); - printLabel(depth, "argumentsList: "); + printLabel(depth, "argumentsList: [firstNonParameterNodeIdx=" + + firstNonParameterNodeIdx + "]" ); int argumentsListSize = argumentsList.size(); for (int i=0; i < argumentsListSize; i++) { ((ValueNode)argumentsList.elementAt(i)).treePrint(depth+1); Modified: db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CoalesceTest.java URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CoalesceTest.java?rev=598054&r1=598053&r2=598054&view=diff ============================================================================== --- db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CoalesceTest.java (original) +++ db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/CoalesceTest.java Sun Nov 25 13:06:47 2007 @@ -170,6 +170,7 @@ "create table tD (c1 int, c2 char(254))", "create table tB (c1 char(254), c2 char(40), vc1 varchar(253), vc2 varchar(2000), lvc1 long varchar, lvc2 long varchar, clob1 CLOB(200), clob2 CLOB(33K))", "create table tC (cbd1 char(254) for bit data, cbd2 char(40) for bit data, vcbd1 varchar(253) for bit data, vcbd2 varchar(2000) for bit data, lvcbd1 long varchar for bit data, lvcbd2 long varchar for bit data, blob1 BLOB(200), blob2 BLOB(33K))", + "create table tAggr (i int)" }; /* Public constructor required for running test as standalone JUnit. */ @@ -1131,7 +1132,43 @@ dumpRS(s.executeQuery("select coalesce(blob1,blob2) from tC"), expectedValues[index++]); dumpRS(s.executeQuery("select value(blob1,blob2) from tC"), expectedValues[index++]); - } + } + + + public void testAggregateDerby2016() throws SQLException + { + String[] expectedValues = { + "COL1(datatype : INTEGER, precision : 10, scale : 0) 2 ", + "COL1(datatype : INTEGER, precision : 10, scale : 0) 55 ", + "COL1(datatype : INTEGER, precision : 10, scale : 0) 1 ", + }; + + int index = 0; + + // let aggregate max return a non-null: should give 2 + ps = prepareStatement("insert into tAggr values ?"); + for (int i=0; i<3; i++) { + ps.setInt(1, i); + ps.executeUpdate(); + } + + dumpRS(s.executeQuery("select coalesce(max(i), 55) from tAggr"), + expectedValues[index++]); + + s.executeUpdate("delete from tAggr"); + + // let aggregate max return a null + ps.setNull(1, Types.INTEGER); + ps.executeUpdate(); + + dumpRS(s.executeQuery("select coalesce(max(i), 55) from tAggr"), + expectedValues[index++]); + + // two aggregates + dumpRS(s.executeQuery( + "select coalesce(max(i), count(*), 55) from tAggr"), + expectedValues[index++]); + } /**************supporting methods *******************/