db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r1564730 - in /db/derby/code/branches/10.10: ./ java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java java/testing/org/apache/derbyTesting/functionTests/tests/lang/InsertTest.java
Date Wed, 05 Feb 2014 12:14:46 GMT
Author: kahatlen
Date: Wed Feb  5 12:14:45 2014
New Revision: 1564730

URL: http://svn.apache.org/r1564730
Log:
DERBY-6443: ArrayIndexOutOfBoundsException when calling function from trigger

Merged revision 1556809 from trunk.

Modified:
    db/derby/code/branches/10.10/   (props changed)
    db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java
    db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/InsertTest.java

Propchange: db/derby/code/branches/10.10/
------------------------------------------------------------------------------
  Merged /db/derby/code/trunk:r1556809

Modified: db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java?rev=1564730&r1=1564729&r2=1564730&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java
(original)
+++ db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java
Wed Feb  5 12:14:45 2014
@@ -113,7 +113,12 @@ public class StaticMethodCallNode extend
 	private int[]		 applicationParameterNumbers; 
 
 	private boolean		isSystemCode;
-	private boolean		alreadyBound;
+
+    /**
+     * This flag is true while bindExpression() is executing. It is used to
+     * avoid infinite recursion when bindExpression() is reentered.
+     */
+    private boolean isInsideBind;
 
     /**
      * Generated boolean field to hold the indicator
@@ -182,10 +187,24 @@ public class StaticMethodCallNode extend
 			throws StandardException
 	{
 		// for a function we can get called recursively
-		if (alreadyBound)
-			return this;
+        if (isInsideBind) {
+            return this;
+        }
 
+        isInsideBind = true;
+        try {
+            return bindExpressionMinion(fromList, subqueryList, aggregateVector);
+        } finally {
+            isInsideBind = false;
+        }
+    }
 
+    private JavaValueNode bindExpressionMinion(
+            FromList fromList,
+            SubqueryList subqueryList,
+            List aggregateVector)
+        throws StandardException
+    {
 		bindParameters(fromList, subqueryList, aggregateVector);
 
 		
@@ -345,7 +364,6 @@ public class StaticMethodCallNode extend
 		resolveMethodCall( javaClassName, true );
 
 
-		alreadyBound = true;
 		if (isPrivilegeCollectionRequired())
 			getCompilerContext().addRequiredRoutinePriv(ad);
 

Modified: db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/InsertTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/InsertTest.java?rev=1564730&r1=1564729&r2=1564730&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/InsertTest.java
(original)
+++ db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/InsertTest.java
Wed Feb  5 12:14:45 2014
@@ -207,4 +207,75 @@ public class InsertTest extends BaseJDBC
                 TOO_MANY_RESULT_COLUMNS,
                 "insert into derby4449 (x) values (default, default)");
     }
+
+    /**
+     * Regression test case for DERBY-6443. INSERT statements bind the
+     * source SELECT statement twice, and the second time it would miss
+     * aggregates and subqueries if they were wrapped in a function call.
+     * This led to inconsistencies in the query tree that caused errors
+     * during execution (or assertion failures during compilation in sane
+     * builds).
+     */
+    public void testDerby6443() throws SQLException {
+        Statement s = createStatement();
+
+        // Disable auto-commit for easy cleanup of test tables (automatically
+        // rolled back in tearDown()), and create a separate schema to avoid
+        // name conflicts with other test cases.
+        setAutoCommit(false);
+        s.execute("CREATE SCHEMA d6443");
+        s.execute("SET SCHEMA d6443");
+
+        // This is the original test case provided in the bug report. It
+        // used to fail with an assert failure when compiling the trigger
+        // (in sane builds), or with an ArrayIndexOutOfBoundsException when
+        // the trigger fired (in insane builds).
+        s.execute("CREATE TABLE foo (name VARCHAR(20), val DOUBLE)");
+        s.execute("CREATE TABLE summary "
+                + "(name VARCHAR(20), aver DOUBLE, size INT)");
+        s.execute("CREATE TRIGGER trg_foo AFTER INSERT ON foo "
+                + "REFERENCING NEW TABLE AS changed FOR EACH STATEMENT "
+                + "INSERT INTO summary (name, aver, size) "
+                + "SELECT name, FLOOR(AVG(LOG10(val))), COUNT(*) "
+                + "FROM changed "
+                + "GROUP BY name");
+        s.execute("INSERT INTO foo (name, val) "
+                + "VALUES ('A', 10), ('A', 20), ('B', 30), ('C', 40)");
+        JDBC.assertFullResultSet(
+                s.executeQuery("select * from foo order by val"),
+                new String[][] {
+                    { "A", "10.0" },
+                    { "A", "20.0" },
+                    { "B", "30.0" },
+                    { "C", "40.0" },
+                });
+        JDBC.assertFullResultSet(
+                s.executeQuery("select * from summary order by name"),
+                new String[][] {
+                    { "A", "1.0", "2" },
+                    { "B", "1.0", "1" },
+                    { "C", "1.0", "1" },
+                });
+
+        // Some other problematic queries...
+
+        s.execute("create table t1(x int)");
+        s.execute("insert into t1 values 1");
+        s.execute("create table t2(x int)");
+
+        // Used to fail with assert or ArrayIndexOutOfBoundsException.
+        s.execute("insert into t2 select floor(avg(x)) from t1");
+
+        // Same here...
+        s.execute("create function f(x int) returns int language java "
+                + "parameter style java external name 'java.lang.Math.abs'");
+        s.execute("insert into t2 select f(avg(x)) from t1");
+
+        // This query used to fail with a NullPointerException.
+        s.execute("insert into t2 select f((select x from t1)) from t1");
+
+        JDBC.assertFullResultSet(
+                s.executeQuery("select * from t2"),
+                new String[][] {{"1"}, {"1"}, {"1"}});
+    }
 }



Mime
View raw message