Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / engine / org / apache / derby / impl / sql / compile / DistinctNode.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/DistinctNode.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/DistinctNode.java
new file mode 100644 (file)
index 0000000..2faaef7
--- /dev/null
@@ -0,0 +1,343 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.compile.DistinctNode\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to you under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package        org.apache.derby.impl.sql.compile;\r
+\r
+import org.apache.derby.iapi.sql.compile.Optimizable;\r
+import org.apache.derby.iapi.sql.compile.OptimizableList;\r
+import org.apache.derby.iapi.sql.compile.OptimizablePredicate;\r
+import org.apache.derby.iapi.sql.compile.OptimizablePredicateList;\r
+import org.apache.derby.iapi.sql.compile.Optimizer;\r
+import org.apache.derby.iapi.sql.compile.CostEstimate;\r
+import org.apache.derby.iapi.sql.compile.Visitable;\r
+import org.apache.derby.iapi.sql.compile.Visitor;\r
+import org.apache.derby.iapi.sql.compile.RequiredRowOrdering;\r
+import org.apache.derby.iapi.sql.compile.RowOrdering;\r
+import org.apache.derby.iapi.sql.compile.C_NodeTypes;\r
+\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;\r
+\r
+import org.apache.derby.iapi.sql.Activation;\r
+import org.apache.derby.iapi.sql.ResultSet;\r
+import org.apache.derby.iapi.reference.ClassName;\r
+\r
+import org.apache.derby.iapi.services.classfile.VMOpcode;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.impl.sql.compile.ActivationClassBuilder;\r
+\r
+import org.apache.derby.iapi.services.compiler.MethodBuilder;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.util.JBitSet;\r
+\r
+\r
+import java.util.Properties;\r
+import java.util.Vector;\r
+\r
+/**\r
+ * A DistinctNode represents a result set for a disinct operation\r
+ * on a select.  It has the same description as its input result set.\r
+ *\r
+ * For the most part, it simply delegates operations to its childResultSet,\r
+ * which is currently expected to be a ProjectRestrictResultSet generated\r
+ * for a SelectNode.\r
+ *\r
+ * NOTE: A DistinctNode extends FromTable since it can exist in a FromList.\r
+ *\r
+ */\r
+public class DistinctNode extends SingleChildResultSetNode\r
+{\r
+       boolean inSortedOrder;\r
+\r
+       /**\r
+        * Initializer for a DistinctNode.\r
+        *\r
+        * @param childResult   The child ResultSetNode\r
+        * @param inSortedOrder Whether or not the child ResultSetNode returns its\r
+        *                                              output in sorted order.\r
+        * @param tableProperties       Properties list associated with the table\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void init(\r
+                                               Object childResult,\r
+                                               Object inSortedOrder,\r
+                                               Object tableProperties) throws StandardException\r
+       {\r
+               super.init(childResult, tableProperties);\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (!(childResult instanceof Optimizable))\r
+                       {\r
+                               SanityManager.THROWASSERT("childResult, " + childResult.getClass().getName() +\r
+                                       ", expected to be instanceof Optimizable");\r
+                       }\r
+                       if (!(childResult instanceof FromTable))\r
+                       {\r
+                               SanityManager.THROWASSERT("childResult, " + childResult.getClass().getName() +\r
+                                       ", expected to be instanceof FromTable");\r
+                       }\r
+               }\r
+\r
+               ResultColumnList prRCList;\r
+\r
+               /*\r
+                       We want our own resultColumns, which are virtual columns\r
+                       pointing to the child result's columns.\r
+\r
+                       We have to have the original object in the distinct node,\r
+                       and give the underlying project the copy.\r
+                */\r
+\r
+               /* We get a shallow copy of the ResultColumnList and its \r
+                * ResultColumns.  (Copy maintains ResultColumn.expression for now.)\r
+                */\r
+               prRCList = this.childResult.getResultColumns().copyListAndObjects();\r
+               resultColumns = this.childResult.getResultColumns();\r
+               this.childResult.setResultColumns(prRCList);\r
+\r
+               /* Replace ResultColumn.expression with new VirtualColumnNodes\r
+                * in the DistinctNode's RCL.  (VirtualColumnNodes include\r
+                * pointers to source ResultSetNode, this, and source ResultColumn.)\r
+                */\r
+               resultColumns.genVirtualColumnNodes(this, prRCList);\r
+\r
+               /* Verify that we can perform a DISTINCT on the\r
+                * underlying tree.\r
+                */\r
+               resultColumns.verifyAllOrderable();\r
+\r
+               this.inSortedOrder = ((Boolean) inSortedOrder).booleanValue();\r
+       }\r
+\r
+       /*\r
+        *  Optimizable interface\r
+        */\r
+\r
+       /**\r
+        * @see Optimizable#optimizeIt\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public CostEstimate optimizeIt(Optimizer optimizer,\r
+                                                                       OptimizablePredicateList predList,\r
+                                                                       CostEstimate outerCost,\r
+                                                                       RowOrdering rowOrdering)\r
+                       throws StandardException\r
+       {\r
+               CostEstimate childCost =\r
+                       ((Optimizable) childResult).optimizeIt(optimizer,\r
+                                                                       predList,\r
+                                                                       outerCost,\r
+                                                                       rowOrdering);\r
+\r
+               return super.optimizeIt(optimizer, predList, outerCost, rowOrdering);\r
+       }\r
+\r
+       /**\r
+        * @see Optimizable#estimateCost\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public CostEstimate estimateCost(OptimizablePredicateList predList,\r
+                                                                       ConglomerateDescriptor cd,\r
+                                                                       CostEstimate outerCost,\r
+                                                                       Optimizer optimizer,\r
+                                                                       RowOrdering rowOrdering)\r
+                       throws StandardException\r
+       {\r
+               // RESOLVE: WE NEED TO ADD IN THE COST OF SORTING HERE, AND FIGURE\r
+               // OUT HOW MANY ROWS WILL BE ELIMINATED.\r
+               CostEstimate childCost =\r
+                       ((Optimizable) childResult).estimateCost(predList,\r
+                                                                       cd,\r
+                                                                       outerCost,\r
+                                                                       optimizer,\r
+                                                                       rowOrdering);\r
+\r
+               costEstimate = getCostEstimate(optimizer);\r
+               costEstimate.setCost(childCost.getEstimatedCost(),\r
+                                                        childCost.rowCount(),\r
+                                                        childCost.singleScanRowCount());\r
+\r
+\r
+               /*\r
+               ** No need to use estimateCost on join strategy - that has already\r
+               ** been done on the child.\r
+               */\r
+               return costEstimate;\r
+       }\r
+\r
+       /**\r
+        * @see org.apache.derby.iapi.sql.compile.Optimizable#pushOptPredicate\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+\r
+       public boolean pushOptPredicate(OptimizablePredicate optimizablePredicate)\r
+                       throws StandardException\r
+       {\r
+               return false;\r
+               // return ((Optimizable) childResult).pushOptPredicate(optimizablePredicate);\r
+       }\r
+\r
+       /**\r
+        * Convert this object to a String.  See comments in QueryTreeNode.java\r
+        * for how this should be done for tree printing.\r
+        *\r
+        * @return      This object as a String\r
+        */\r
+\r
+       public String toString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       return childResult.toString() + "\n" + super.toString();\r
+               }\r
+               else\r
+               {\r
+                       return "";\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Optimize this DistinctNode.  \r
+        *\r
+        * @param dataDictionary        The DataDictionary to use for optimization\r
+        * @param predicates            The PredicateList to optimize.  This should\r
+        *                                                      be a join predicate.\r
+        * @param outerRows                     The number of outer joining rows\r
+        *\r
+        * @return      ResultSetNode   The top of the optimized subtree\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+\r
+       public ResultSetNode optimize(DataDictionary dataDictionary,\r
+                                                                 PredicateList predicates,\r
+                                                                 double outerRows) \r
+                                       throws StandardException\r
+       {\r
+               /* We need to implement this method since a PRN can appear above a\r
+                * SelectNode in a query tree.\r
+                */\r
+               childResult = (ProjectRestrictNode) childResult.optimize(\r
+                                                                                                                       dataDictionary,\r
+                                                                                                                       predicates,\r
+                                                                                                                       outerRows);\r
+               Optimizer optimizer = getOptimizer(\r
+                                               (FromList) getNodeFactory().getNode(\r
+                                                       C_NodeTypes.FROM_LIST,\r
+                                                       getNodeFactory().doJoinOrderOptimization(),\r
+                                                       this,\r
+                                                       getContextManager()),\r
+                                               predicates,\r
+                                               dataDictionary,\r
+                                               (RequiredRowOrdering) null);\r
+\r
+               // RESOLVE: NEED TO FACTOR IN COST OF SORTING AND FIGURE OUT HOW\r
+               // MANY ROWS HAVE BEEN ELIMINATED.\r
+               costEstimate = optimizer.newCostEstimate();\r
+\r
+               costEstimate.setCost(childResult.getCostEstimate().getEstimatedCost(),\r
+                                                        childResult.getCostEstimate().rowCount(),\r
+                                                        childResult.getCostEstimate().singleScanRowCount());\r
+\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * Return whether or not the underlying ResultSet tree\r
+        * is ordered on the specified columns.\r
+        * RESOLVE - This method currently only considers the outermost table \r
+        * of the query block.\r
+        *\r
+        * @param       crs                                     The specified ColumnReference[]\r
+        * @param       permuteOrdering         Whether or not the order of the CRs in the array can be permuted\r
+        * @param       fbtVector                       Vector that is to be filled with the FromBaseTable      \r
+        *\r
+        * @return      Whether the underlying ResultSet tree\r
+        * is ordered on the specified column.\r
+        */\r
+       boolean isOrderedOn(ColumnReference[] crs, boolean permuteOrdering, Vector fbtVector)\r
+       {\r
+               /* RESOLVE - DistinctNodes are ordered on their RCLs.\r
+                * Walk RCL to see if cr is 1st non-constant column in the\r
+                * ordered result.\r
+                */\r
+               return false;\r
+       }\r
+\r
+    /**\r
+     * generate the distinct result set operating over the source\r
+        * resultset.\r
+     *\r
+        * @exception StandardException         Thrown on error\r
+     */\r
+       public void generate(ActivationClassBuilder acb,\r
+                                                               MethodBuilder mb)\r
+                                                       throws StandardException\r
+       {\r
+               /* Get the next ResultSet#, so we can number this ResultSetNode, its\r
+                * ResultColumnList and ResultSet.\r
+                */\r
+               assignResultSetNumber();\r
+\r
+               // Get the final cost estimate based on the child's cost.\r
+               costEstimate = childResult.getFinalCostEstimate();\r
+\r
+               /*\r
+                       create the orderItem and stuff it in.\r
+                */\r
+               int orderItem = acb.addItem(acb.getColumnOrdering(resultColumns));\r
+\r
+               /* Generate the SortResultSet:\r
+                *      arg1: childExpress - Expression for childResultSet\r
+                *  arg2: distinct - true, of course\r
+                *  arg3: isInSortedOrder - is the source result set in sorted order\r
+                *  arg4: orderItem - entry in saved objects for the ordering\r
+                *  arg5: rowAllocator - method to construct rows for fetching\r
+                *                      from the sort\r
+                *  arg6: row size\r
+                *  arg7: resultSetNumber\r
+                */\r
+\r
+               acb.pushGetResultSetFactoryExpression(mb);\r
+\r
+               childResult.generate(acb, mb);\r
+               mb.push(true);\r
+               mb.push(inSortedOrder);\r
+               mb.push(orderItem);\r
+               resultColumns.generateHolder(acb, mb);\r
+               mb.push(resultColumns.getTotalColumnSize());\r
+               mb.push(resultSetNumber);\r
+               mb.push(costEstimate.rowCount());\r
+               mb.push(costEstimate.getEstimatedCost());\r
+\r
+               mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getSortResultSet",\r
+                ClassName.NoPutResultSet, 9);\r
+       }\r
+}\r