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 ab...@apache.org on 2008/03/05 23:16:59 UTC
svn commit: r634057 - in /db/derby/code/trunk/java:
engine/org/apache/derby/impl/sql/compile/
testing/org/apache/derbyTesting/functionTests/tests/lang/
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
*/