You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2009/12/14 16:35:07 UTC

svn commit: r890370 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/sql/compile/PredicateList.java testing/org/apache/derbyTesting/functionTests/tests/lang/PredicateTest.java

Author: kahatlen
Date: Mon Dec 14 15:35:06 2009
New Revision: 890370

URL: http://svn.apache.org/viewvc?rev=890370&view=rev
Log:
DERBY-2282: Incorrect "transitive closure" logic leads to inconsistent behavior for binary comparison predicates

Extended the fix to work on parameters in addition to constants.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/PredicateList.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/PredicateTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/PredicateList.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/PredicateList.java?rev=890370&r1=890369&r2=890370&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/PredicateList.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/PredicateList.java Mon Dec 14 15:35:06 2009
@@ -1440,6 +1440,17 @@
 		}
 	}
 
+    /**
+     * Check if a node is representing a constant or a parameter.
+     *
+     * @param node the node to check
+     * @return {@code true} if the node is a constant or a parameter, {@code
+     * false} otherwise
+     */
+    private static boolean isConstantOrParameterNode(ValueNode node) {
+        return node instanceof ConstantNode || node instanceof ParameterNode;
+    }
+
 	/**
 	 * Push all predicates, which can be pushed, into the underlying select.
 	 * A predicate can be pushed into an underlying select if the source of 
@@ -1510,8 +1521,7 @@
 					opNode = (BinaryRelationalOperatorNode) andNode.getLeftOperand();
 					// Investigate using invariant interface to check rightOperand
 					if (! (opNode.getLeftOperand() instanceof ColumnReference) ||
-					    ! (opNode.getRightOperand() instanceof ConstantNode ||
-							 opNode.getRightOperand() instanceof ParameterNode))
+						! isConstantOrParameterNode(opNode.getRightOperand()))
 						continue;
 
 					crNode = (ColumnReference) opNode.getLeftOperand();
@@ -2273,12 +2283,13 @@
 
 				// RESOLVE: Consider using variant type of the expression, instead of
 				// ConstantNode or ParameterNode in the future.
-				if (left instanceof ColumnReference && 
-					  (right instanceof ConstantNode || right instanceof ParameterNode))
+				if (left instanceof ColumnReference &&
+						isConstantOrParameterNode(right))
 				{
 					searchClauses.addElement(predicate);
 				}
-				else if (left instanceof ConstantNode && right instanceof ColumnReference)
+				else if (isConstantOrParameterNode(left) &&
+						right instanceof ColumnReference)
 				{
 					// put the ColumnReference on the left to simplify things
 					andNode.setLeftOperand(bcon.getSwappedEquivalent());

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/PredicateTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/PredicateTest.java?rev=890370&r1=890369&r2=890370&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/PredicateTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/PredicateTest.java Mon Dec 14 15:35:06 2009
@@ -24,6 +24,7 @@
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.StringReader;
+import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
@@ -98,6 +99,29 @@
 
         // Verify that we now have all the expected qualifiers.
         assertEquals(expectedOperators, extractOperators(getStatistics()));
+
+        // Now check that we get the same plan with parameters instead of
+        // constants on the right-hand side.
+
+        PreparedStatement paramRight = prepareStatement(
+                "select i from t1, t2 where " +
+                "t1.i = t2.j and t1.i >= ? and t2.j <= ?");
+        paramRight.setInt(1, 23);
+        paramRight.setInt(2, 30);
+
+        JDBC.assertSingleValueResultSet(paramRight.executeQuery(), "23");
+        assertEquals(expectedOperators, extractOperators(getStatistics()));
+
+        // Same plan expected with parameters on the left-hand side.
+
+        PreparedStatement paramLeft = prepareStatement(
+                "select i from t1, t2 where " +
+                "t1.i = t2.j and ? <= t1.i and ? >= t2.j");
+        paramLeft.setInt(1, 23);
+        paramLeft.setInt(2, 30);
+
+        JDBC.assertSingleValueResultSet(paramLeft.executeQuery(), "23");
+        assertEquals(expectedOperators, extractOperators(getStatistics()));
     }
 
     /**