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 / SingleChildResultSetNode.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/SingleChildResultSetNode.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/SingleChildResultSetNode.java
new file mode 100644 (file)
index 0000000..46f5657
--- /dev/null
@@ -0,0 +1,636 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.compile.SingleChildResultSetNode\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.services.context.ContextManager;\r
+\r
+import org.apache.derby.iapi.sql.compile.AccessPath;\r
+import org.apache.derby.iapi.sql.compile.CostEstimate;\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.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.C_NodeTypes;\r
+\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+\r
+import org.apache.derby.iapi.sql.Activation;\r
+import org.apache.derby.iapi.sql.ResultSet;\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.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.util.JBitSet;\r
+\r
+import java.util.Properties;\r
+import java.util.Vector;\r
+\r
+/**\r
+ * A SingleChildResultSetNode represents a result set with a single child.\r
+ *\r
+ */\r
+\r
+abstract class SingleChildResultSetNode extends FromTable\r
+{\r
+       /**\r
+        * ResultSetNode under the SingleChildResultSetNode\r
+        */\r
+       ResultSetNode   childResult;\r
+\r
+       // Does this node have the truly... for the underlying tree\r
+       protected boolean hasTrulyTheBestAccessPath;\r
+\r
+\r
+       /**\r
+        * Initialilzer for a SingleChildResultSetNode.\r
+        *\r
+        * @param childResult   The child ResultSetNode\r
+        * @param tableProperties       Properties list associated with the table\r
+        */\r
+\r
+       public void init(Object childResult, Object tableProperties)\r
+       {\r
+               /* correlationName is always null */\r
+               super.init(null, tableProperties);\r
+               this.childResult = (ResultSetNode) childResult;\r
+\r
+               /* Propagate the child's referenced table map, if one exists */\r
+               if (this.childResult.getReferencedTableMap() != null)\r
+               {\r
+                       referencedTableMap =\r
+                               (JBitSet) this.childResult.getReferencedTableMap().clone();\r
+               }\r
+       }\r
+\r
+       /** @see Optimizable#getTrulyTheBestAccessPath */\r
+       public AccessPath getTrulyTheBestAccessPath()\r
+       {\r
+               if (hasTrulyTheBestAccessPath)\r
+               {\r
+                       return super.getTrulyTheBestAccessPath();\r
+               }\r
+\r
+               if (childResult instanceof Optimizable)\r
+                       return ((Optimizable) childResult).getTrulyTheBestAccessPath();\r
+\r
+               return super.getTrulyTheBestAccessPath();\r
+       }\r
+\r
+       /**\r
+        * Return the childResult from this node.\r
+        *\r
+        * @return ResultSetNode        The childResult from this node.\r
+        */\r
+       public ResultSetNode getChildResult()\r
+       {\r
+               return childResult;\r
+       }\r
+\r
+       /**\r
+        * Set the childResult for this node.\r
+        *\r
+        * @param childResult   The new childResult for this node.\r
+        */\r
+       void setChildResult(ResultSetNode childResult)\r
+       {\r
+               this.childResult = childResult;\r
+       }\r
+\r
+       /**\r
+        * @see Optimizable#pullOptPredicates\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void pullOptPredicates(\r
+                                                               OptimizablePredicateList optimizablePredicates)\r
+                       throws StandardException\r
+       {\r
+               if (childResult instanceof Optimizable)\r
+               {\r
+                       ((Optimizable) childResult).pullOptPredicates(optimizablePredicates);\r
+               }\r
+       }\r
+\r
+       /** @see Optimizable#forUpdate */\r
+       public boolean forUpdate()\r
+       {\r
+               if (childResult instanceof Optimizable)\r
+               {\r
+                       return ((Optimizable) childResult).forUpdate();\r
+               }\r
+               else\r
+               {\r
+                       return super.forUpdate();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see Optimizable#initAccessPaths\r
+        */\r
+       public void initAccessPaths(Optimizer optimizer)\r
+       {\r
+               super.initAccessPaths(optimizer);\r
+               if (childResult instanceof Optimizable)\r
+               {\r
+                       ((Optimizable) childResult).initAccessPaths(optimizer);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see Optimizable#updateBestPlanMap\r
+        *\r
+        * Makes a call to add/load/remove a plan mapping for this node,\r
+        * and then makes the necessary call to recurse on this node's\r
+        * child, in order to ensure that we've handled the full plan\r
+        * all the way down this node's subtree.\r
+        */\r
+       public void updateBestPlanMap(short action,\r
+               Object planKey) throws StandardException\r
+       {\r
+               super.updateBestPlanMap(action, planKey);\r
+\r
+               // Now walk the child.  Note that if the child is not an\r
+               // Optimizable and the call to child.getOptimizerImpl()\r
+               // returns null, then that means we haven't tried to optimize\r
+               // the child yet.  So in that case there's nothing to\r
+               // add/load.\r
+\r
+               if (childResult instanceof Optimizable)\r
+               {\r
+                       ((Optimizable)childResult).\r
+                               updateBestPlanMap(action, planKey);\r
+               }\r
+               else if (childResult.getOptimizerImpl() != null)\r
+               {\r
+                       childResult.getOptimizerImpl().\r
+                               updateBestPlanMaps(action, planKey);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Prints the sub-nodes of this object.  See QueryTreeNode.java for\r
+        * how tree printing is supposed to work.\r
+        *\r
+        * @param depth         The depth of this node in the tree\r
+        */\r
+\r
+       public void printSubNodes(int depth)\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       super.printSubNodes(depth);\r
+\r
+                       if (childResult != null)\r
+                       {\r
+                               printLabel(depth, "childResult: ");\r
+                               childResult.treePrint(depth + 1);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Search to see if a query references the specifed table name.\r
+        *\r
+        * @param name          Table name (String) to search for.\r
+        * @param baseTable     Whether or not name is for a base table\r
+        *\r
+        * @return      true if found, else false\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public boolean referencesTarget(String name, boolean baseTable)\r
+               throws StandardException\r
+       {\r
+               return childResult.referencesTarget(name, baseTable);\r
+       }\r
+\r
+       /**\r
+        * Return true if the node references SESSION schema tables (temporary or permanent)\r
+        *\r
+        * @return      true if references SESSION schema tables, else false\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public boolean referencesSessionSchema()\r
+               throws StandardException\r
+       {\r
+               return childResult.referencesSessionSchema();\r
+       }\r
+\r
+       /**\r
+        * Set the (query block) level (0-based) for this FromTable.\r
+        *\r
+        * @param level         The query block level for this FromTable.\r
+        */\r
+       public void setLevel(int level)\r
+       {\r
+               super.setLevel(level);\r
+               if (childResult instanceof FromTable)\r
+               {\r
+                       ((FromTable) childResult).setLevel(level);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Return whether or not this ResultSetNode contains a subquery with a\r
+        * reference to the specified target.\r
+        * \r
+        * @param name  The table name.\r
+        * @param baseTable     Whether or not the name is for a base table.\r
+        *\r
+        * @return boolean      Whether or not a reference to the table was found.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       boolean subqueryReferencesTarget(String name, boolean baseTable)\r
+               throws StandardException\r
+       {\r
+               return childResult.subqueryReferencesTarget(name, baseTable);\r
+       }\r
+\r
+       /** \r
+        * Put a ProjectRestrictNode on top of each FromTable in the FromList.\r
+        * ColumnReferences must continue to point to the same ResultColumn, so\r
+        * that ResultColumn must percolate up to the new PRN.  However,\r
+        * that ResultColumn will point to a new expression, a VirtualColumnNode, \r
+        * which points to the FromTable and the ResultColumn that is the source for\r
+        * the ColumnReference.  \r
+        * (The new PRN will have the original of the ResultColumnList and\r
+        * the ResultColumns from that list.  The FromTable will get shallow copies\r
+        * of the ResultColumnList and its ResultColumns.  ResultColumn.expression\r
+        * will remain at the FromTable, with the PRN getting a new \r
+        * VirtualColumnNode for each ResultColumn.expression.)\r
+        * We then project out the non-referenced columns.  If there are no referenced\r
+        * columns, then the PRN's ResultColumnList will consist of a single ResultColumn\r
+        * whose expression is 1.\r
+        *\r
+        * @param numTables                     Number of tables in the DML Statement\r
+        * @param gbl                           The group by list, if any\r
+        * @param fromList                      The from list, if any\r
+        *\r
+        * @return The generated ProjectRestrictNode atop the original FromTable.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+\r
+       public ResultSetNode preprocess(int numTables,\r
+                                                                       GroupByList gbl,\r
+                                                                       FromList fromList) \r
+                                                               throws StandardException\r
+       {\r
+               childResult = childResult.preprocess(numTables, gbl, fromList);\r
+\r
+               /* Build the referenced table map */\r
+               referencedTableMap = (JBitSet) childResult.getReferencedTableMap().clone();\r
+\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * Add a new predicate to the list.  This is useful when doing subquery\r
+        * transformations, when we build a new predicate with the left side of\r
+        * the subquery operator and the subquery's result column.\r
+        *\r
+        * @param predicate             The predicate to add\r
+        *\r
+        * @return ResultSetNode        The new top of the tree.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public ResultSetNode addNewPredicate(Predicate predicate)\r
+                       throws StandardException\r
+       {\r
+               childResult = childResult.addNewPredicate(predicate);\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * Push expressions down to the first ResultSetNode which can do expression\r
+        * evaluation and has the same referenced table map.\r
+        * RESOLVE - This means only pushing down single table expressions to\r
+        * DistinctNodes today.  Once we have a better understanding of how\r
+        * the optimizer will work, we can push down join clauses.\r
+        *\r
+        * @param predicateList The PredicateList.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void pushExpressions(PredicateList predicateList)\r
+                                       throws StandardException\r
+       {\r
+               if (childResult instanceof FromTable)\r
+               {\r
+                       ((FromTable) childResult).pushExpressions(predicateList);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Evaluate whether or not the subquery in a FromSubquery is flattenable.  \r
+        * Currently, a FSqry is flattenable if all of the following are true:\r
+        *              o  Subquery is a SelectNode. \r
+        *              o  It contains no top level subqueries.  (RESOLVE - we can relax this)\r
+        *              o  It does not contain a group by or having clause\r
+        *              o  It does not contain aggregates.\r
+        *\r
+        * @param fromList      The outer from list\r
+        *\r
+        * @return boolean      Whether or not the FromSubquery is flattenable.\r
+        */\r
+       public boolean flattenableInFromSubquery(FromList fromList)\r
+       {\r
+               /* Flattening currently involves merging predicates and FromLists.\r
+                * We don't have a FromList, so we can't flatten for now.\r
+                */\r
+               /* RESOLVE - this will introduce yet another unnecessary PRN */\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Ensure that the top of the RSN tree has a PredicateList.\r
+        *\r
+        * @param numTables                     The number of tables in the query.\r
+        * @return ResultSetNode        A RSN tree with a node which has a PredicateList on top.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public ResultSetNode ensurePredicateList(int numTables) \r
+               throws StandardException\r
+       {\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * Optimize this SingleChildResultSetNode.  \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 NRSN can appear above a\r
+                * SelectNode in a query tree.\r
+                */\r
+               childResult = childResult.optimize(\r
+                                                                               dataDictionary,\r
+                                                                               predicates,\r
+                                                                               outerRows);\r
+\r
+               Optimizer optimizer =\r
+                                                       getOptimizer(\r
+                                                               (FromList) getNodeFactory().getNode(\r
+                                                                       C_NodeTypes.FROM_LIST,\r
+                                                                       getNodeFactory().doJoinOrderOptimization(),\r
+                                                                       getContextManager()),\r
+                                                       predicates,\r
+                                                       dataDictionary,\r
+                                                       (RequiredRowOrdering) null);\r
+               costEstimate = optimizer.newCostEstimate();\r
+               costEstimate.setCost(childResult.getCostEstimate().getEstimatedCost(),\r
+                                                       childResult.getCostEstimate().rowCount(),\r
+                                                       childResult.getCostEstimate().singleScanRowCount());\r
+\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @see ResultSetNode#modifyAccessPaths\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public ResultSetNode modifyAccessPaths() throws StandardException\r
+       {\r
+               childResult = childResult.modifyAccessPaths();\r
+\r
+               return this;\r
+       }\r
+\r
+       /**\r
+        * @see ResultSetNode#changeAccessPath\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public ResultSetNode changeAccessPath() throws StandardException\r
+       {\r
+               childResult = childResult.changeAccessPath();\r
+               return this;\r
+       }\r
+\r
+       /** \r
+        * Determine whether or not the specified name is an exposed name in\r
+        * the current query block.\r
+        *\r
+        * @param name  The specified name to search for as an exposed name.\r
+        * @param schemaName    Schema name, if non-null.\r
+        * @param exactMatch    Whether or not we need an exact match on specified schema and table\r
+        *                                              names or match on table id.\r
+        *\r
+        * @return The FromTable, if any, with the exposed name.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       protected FromTable getFromTableByName(String name, String schemaName, boolean exactMatch)\r
+               throws StandardException\r
+       {\r
+               return childResult.getFromTableByName(name, schemaName, exactMatch);\r
+       }\r
+\r
+       /**\r
+        * Decrement (query block) level (0-based) for this FromTable.\r
+        * This is useful when flattening a subquery.\r
+        *\r
+        * @param decrement     The amount to decrement by.\r
+        */\r
+       void decrementLevel(int decrement)\r
+       {\r
+               super.decrementLevel(decrement);\r
+               childResult.decrementLevel(decrement);\r
+       }\r
+\r
+       /**\r
+        * Get the lock mode for the target of an update statement\r
+        * (a delete or update).  The update mode will always be row for\r
+        * CurrentOfNodes.  It will be table if there is no where clause.\r
+        *\r
+        * @return      The lock mode\r
+        */\r
+       public int updateTargetLockMode()\r
+       {\r
+               return childResult.updateTargetLockMode();\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
+        * @exception StandardException         Thrown on error\r
+        */\r
+       boolean isOrderedOn(ColumnReference[] crs, boolean permuteOrdering, Vector fbtVector)\r
+                               throws StandardException\r
+       {\r
+               return childResult.isOrderedOn(crs, permuteOrdering, fbtVector);\r
+       }\r
+\r
+       /**\r
+        * Return whether or not the underlying ResultSet tree will return\r
+        * a single row, at most.\r
+        * This is important for join nodes where we can save the extra next\r
+        * on the right side if we know that it will return at most 1 row.\r
+        *\r
+        * @return Whether or not the underlying ResultSet tree will return a single row.\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public boolean isOneRowResultSet()      throws StandardException\r
+       {\r
+               // Default is false\r
+               return childResult.isOneRowResultSet();\r
+       }\r
+\r
+       /**\r
+        * Return whether or not the underlying ResultSet tree is for a NOT EXISTS join.\r
+        *\r
+        * @return Whether or not the underlying ResultSet tree is for a NOT EXISTS.\r
+        */\r
+       public boolean isNotExists()\r
+       {\r
+               return childResult.isNotExists();\r
+       }\r
+\r
+       /**\r
+        * Determine whether we need to do reflection in order to do the projection.  \r
+        * Reflection is only needed if there is at least 1 column which is not\r
+        * simply selecting the source column.\r
+        *\r
+        * @return      Whether or not we need to do reflection in order to do\r
+        *                      the projection.\r
+        */\r
+       protected boolean reflectionNeededForProjection()\r
+       {\r
+               return ! (resultColumns.allExpressionsAreColumns(childResult));\r
+       }\r
+\r
+       /**\r
+        * Replace any DEFAULTs with the associated tree for the default.\r
+        *\r
+        * @param ttd   The TableDescriptor for the target table.\r
+        * @param tcl   The RCL for the target table.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       void replaceDefaults(TableDescriptor ttd, ResultColumnList tcl) \r
+               throws StandardException\r
+       {\r
+               childResult.replaceDefaults(ttd, tcl);\r
+       }\r
+\r
+       /**\r
+        * @see ResultSetNode#adjustForSortElimination\r
+        */\r
+       void adjustForSortElimination()\r
+       {\r
+               childResult.adjustForSortElimination();\r
+       }\r
+\r
+       /**\r
+        * @see ResultSetNode#adjustForSortElimination\r
+        */\r
+       void adjustForSortElimination(RequiredRowOrdering rowOrdering)\r
+               throws StandardException\r
+       {\r
+               childResult.adjustForSortElimination(rowOrdering);\r
+       }\r
+\r
+       /**\r
+        * Get the final CostEstimate for this node.\r
+        *\r
+        * @return      The final CostEstimate for this node, which is\r
+        *                      the final cost estimate for the child node.\r
+        */\r
+       public CostEstimate getFinalCostEstimate()\r
+               throws StandardException\r
+       {\r
+               /*\r
+               ** The cost estimate will be set here if either optimize() or\r
+               ** optimizeIt() was called on this node.  It's also possible\r
+               ** that optimization was done directly on the child node,\r
+               ** in which case the cost estimate will be null here.\r
+               */\r
+               if (costEstimate == null)\r
+                       return childResult.getFinalCostEstimate();\r
+               else\r
+               {\r
+                       return costEstimate;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Accept a visitor, and call v.visit()\r
+        * on child nodes as necessary.  \r
+        * \r
+        * @param v the visitor\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public Visitable accept(Visitor v) \r
+               throws StandardException\r
+       {\r
+               if (v.skipChildren(this))\r
+               {\r
+                       return v.visit(this);\r
+               }\r
+\r
+               Visitable returnNode = super.accept(v);\r
+\r
+               if (childResult != null && !v.stopTraversal())\r
+               {\r
+                       childResult = (ResultSetNode)childResult.accept(v);\r
+               }\r
+\r
+               return returnNode;\r
+       }\r
+}\r