db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From abr...@apache.org
Subject svn commit: r634057 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/sql/compile/ testing/org/apache/derbyTesting/functionTests/tests/lang/
Date Wed, 05 Mar 2008 22:16:59 GMT
Author: abrown
Date: Wed Mar  5 14:16:52 2008
New Revision: 634057

URL: http://svn.apache.org/viewvc?rev=634057&view=rev
Log:
DERBY-2998 (partial): Remove unused method from ColumnReference.java and
fix ROW_NUMBER() functionality so that row numbers are assigned *before*
DISTINCT is applied, instead of after.

Contributed by Thomas Nielsen (thomas dot nielsen at sun dot com)

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ProjectRestrictNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OLAPTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java?rev=634057&r1=634056&r2=634057&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ColumnReference.java
Wed Mar  5 14:16:52 2008
@@ -1003,22 +1003,6 @@
 	{ 
 		return (source.getExpression() instanceof ColumnReference);
 	}
-
-	/**
-	 * Return whether or not the source of this ColumnReference is a window 
-	 * function.
-	 * 
-	 * Note that we only care about the immediate source here.
-	 * This enables a push into a subquery that again has a windowfunction 
-	 * column in its subquery RCL.
-	 *
-	 * @return Whether or not the source of this ColumnReference 
-	 *         is a window function.
-	 */
-	boolean pointsToWindowFunction()
-	{ 
-		return (source.isWindowFunction());
-	}
 	
 	/**
 	 * The type of a ColumnReference is the type of its

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ProjectRestrictNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ProjectRestrictNode.java?rev=634057&r1=634056&r2=634057&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ProjectRestrictNode.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ProjectRestrictNode.java
Wed Mar  5 14:16:52 2008
@@ -638,19 +638,26 @@
 			 * modify the lower selects RCL, and put a (noop) PRN on top in the 
 			 * above call. This results in:
 			 *    SELECT -> PRN -> PRN(noop) -> WN -> ...			 
+			 * A DISTINCT query will place an additional DistinctNode on top of 
+			 * the window node:
+			 *    SELECT -> PRN -> PRN(noop) -> DN -> WN -> ...
 			 * Note that the RCL for the initial PRN and its child SELECT used 
 			 * to be the same object. After the above call, the initial PRNs RCL 
 			 * is incorrect, and we need to regenerate the VCNs. 
+			 * The above two combinations are the only two possible from 
+			 * modifyAccessPaths() that require regeneration of the VCNs.
 			 */
 			if (childResult instanceof ProjectRestrictNode){
 				ProjectRestrictNode prn = (ProjectRestrictNode) childResult;
-				if (prn.childResult instanceof WindowNode){
+				if (prn.childResult.getResultColumns()
+					.containsWindowFunctionResultColumn())
+				{
 					/* 
 					 * We have a window function column in the RCL of our child 
 					 * PRN, and need to regenerate the VCNs.
 					 */					
-					resultColumns.genVirtualColumnNodes( prn.childResult, 
-														 prn.childResult.getResultColumns() );
+					resultColumns.genVirtualColumnNodes(
+						prn.childResult, prn.childResult.getResultColumns());
 				}
 			}
 			

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java?rev=634057&r1=634056&r2=634057&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java Wed
Mar  5 14:16:52 2008
@@ -1310,8 +1310,12 @@
 			eliminateSort = eliminateSort || gbn.getIsInSortedOrder();
 		}
 
-		// if it is distinct, that must also be taken care of.
-		if (isDistinct)
+		/* 
+		 * If it is distinct, that must also be taken care of. But, if there is 
+		 * a window function in the RCL we must delay duplicate elimination
+		 * until after the window function has been evaluated.
+		 */
+		if (isDistinct && !hasWindowFunction)
 		{
 			// We first verify that a distinct is valid on the
 			// RCL.
@@ -1504,13 +1508,39 @@
 				}
 			}
 
+			/* 
+			 * After evaluation of the window function, we can do duplicate 
+			 * elimination for distinct queries.
+			 */
+			if (isDistinct)
+			{
+				/* Verify that a distinct is valid on the RCL. */
+				prnRSN.getResultColumns().verifyAllOrderable();
+
+				/*
+				 * We cannot push duplicate elimination into store via a hash 
+				 * scan when there is a window function in the RCL, but it may 
+				 * be possible to filter out duplicates without a sorter.
+				 */
+				boolean inSortedOrder = isOrderedResult(prnRSN.getResultColumns(), 
+														prnRSN, 
+														!(orderByAndDistinctMerged));
+				prnRSN = (ResultSetNode) getNodeFactory().getNode(
+											C_NodeTypes.DISTINCT_NODE,
+											prnRSN,
+											new Boolean(inSortedOrder),
+											null,
+											getContextManager());
+				prnRSN.costEstimate = costEstimate.cloneMe();
+			}
+			
 			/*
 			 * Top off with a PRN as this is the intent of this method. Even 
 			 * though this PRN is a noop and will never be generated, we should 
 			 * leave it here as other parts of the code expects to find 
-			 * PRN -> WN.
+			 * PRN -> WN, or PRN -> DN -> WN.
 			 */
-			ResultColumnList newRCL = windowFunctionRCL.copyListAndObjects(); 
+			ResultColumnList newRCL = prnRSN.getResultColumns().copyListAndObjects(); 
 			newRCL.genVirtualColumnNodes(prnRSN, prnRSN.getResultColumns());
 						
 			prnRSN = (ResultSetNode) getNodeFactory().getNode(

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OLAPTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OLAPTest.java?rev=634057&r1=634056&r2=634057&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OLAPTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/OLAPTest.java
Wed Mar  5 14:16:52 2008
@@ -291,6 +291,23 @@
 										{"50", "5", "500"}};
 		JDBC.assertFullResultSet(rs, expectedRows);
 		
+		/* A couple of distinct queries */
+		rs = s.executeQuery("select distinct row_number() over (), 'ABC' from t1");
+		expectedRows = new String[][]{{"1", "ABC"},
+										{"2", "ABC"},
+										{"3", "ABC"},
+										{"4", "ABC"},
+										{"5", "ABC"}};
+		JDBC.assertFullResultSet(rs, expectedRows);
+		
+		rs = s.executeQuery("select * from (select distinct row_number() over (), 'ABC' from t1)
tmp");
+		expectedRows = new String[][]{{"1", "ABC"},
+										{"2", "ABC"},
+										{"3", "ABC"},
+										{"4", "ABC"},
+										{"5", "ABC"}};
+		JDBC.assertFullResultSet(rs, expectedRows);
+		
 		/*
 		 * Negative testing of Statements
 		 */



Mime
View raw message