Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / impl / sql / compile / BaseTableNumbersVisitor.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/compile/BaseTableNumbersVisitor.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/compile/BaseTableNumbersVisitor.java
new file mode 100644 (file)
index 0000000..15244c1
--- /dev/null
@@ -0,0 +1,226 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.compile.BaseTableNumbersVisitor\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.Visitable; \r
+import org.apache.derby.iapi.sql.compile.Visitor;\r
+import org.apache.derby.iapi.util.JBitSet;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+/**\r
+ * Walk through a subtree and build a list of the assigned numbers for\r
+ * all tables that exist in that subtree.  We do this by looking for any\r
+ * column references in the subtree and, for each column reference, we\r
+ * walk down the ColumnReference-ResultColumn chain until we find the\r
+ * the bottom-most table number, which should correspond to a base\r
+ * table.\r
+ */\r
+public class BaseTableNumbersVisitor implements Visitor\r
+{\r
+       // JBitSet to hold the table numbers that we find.\r
+       private JBitSet tableMap;\r
+\r
+       /* Column number of the ColumnReference or ResultColumn\r
+        * for which we most recently found a base table number. \r
+        * In cases where this visitor is only expected to find\r
+        * a single base table number, this field is useful for\r
+        * determining what the column position w.r.t. the found\r
+        * base table was.\r
+        */\r
+       private int columnNumber;\r
+\r
+       /**\r
+        * Constructor: takes a JBitSet to use as the holder for any base table\r
+        * numbers found while walking the subtree.\r
+        *\r
+        * @param tableMap JBitSet into which we put the table numbers we find.\r
+        */\r
+       public BaseTableNumbersVisitor(JBitSet tableMap)\r
+       {\r
+               this.tableMap = tableMap;\r
+               columnNumber = -1;\r
+       }\r
+\r
+       /**\r
+        * Set a new JBitSet to serve as the holder for base table numbers\r
+        * we find while walking.\r
+        *\r
+        * @param tableMap JBitSet into which we put the table numbers we find.\r
+        */\r
+       protected void setTableMap(JBitSet tableMap)\r
+       {\r
+               this.tableMap = tableMap;\r
+       }\r
+\r
+       /**\r
+        * Reset the state of this visitor.\r
+        */\r
+       protected void reset()\r
+       {\r
+               tableMap.clearAll();\r
+               columnNumber = -1;\r
+       }\r
+\r
+       /**\r
+        * Retrieve the the position of the ColumnReference or\r
+        * ResultColumn for which we most recently found a base\r
+        * table number.\r
+        */\r
+       protected int getColumnNumber()\r
+       {\r
+               return columnNumber;\r
+       }\r
+\r
+       ////////////////////////////////////////////////\r
+       //\r
+       // VISITOR INTERFACE\r
+       //\r
+       ////////////////////////////////////////////////\r
+\r
+       /**\r
+        * @see org.apache.derby.iapi.sql.compile.Visitor#visit\r
+        */\r
+       public Visitable visit(Visitable node)\r
+               throws StandardException\r
+       {\r
+               ResultColumn rc = null;\r
+               if (node instanceof ColumnReference)\r
+               {\r
+                       // Start by seeing if this column reference is the\r
+                       // bottom-most one, meaning that there are no column\r
+                       // references beneath this one.\r
+                       rc = ((ColumnReference)node).getSource();\r
+\r
+                       if (rc == null) {\r
+                       // this can happen if column reference is pointing to a column\r
+                       // that is not from a base table.  For example, if we have a\r
+                       // VALUES clause like\r
+                       //\r
+                       //    (values (1, 2), (3, 4)) V1 (i, j)\r
+                       //\r
+                       // and then a column reference to VI.i, the column reference\r
+                       // won't have a source.\r
+                               return node;\r
+                       }\r
+               }\r
+               else if (node instanceof ResultColumn)\r
+                       rc = (ResultColumn)node;\r
+               else if (node instanceof SelectNode)\r
+               {\r
+                       // If the node is a SelectNode we just need to look at its\r
+                       // FROM list.\r
+                       ((SelectNode)node).getFromList().accept(this);\r
+               }\r
+               else if (node instanceof FromBaseTable) {\r
+               // just grab the FBT's table number.\r
+                       tableMap.set(((FromBaseTable)node).getTableNumber());\r
+               }\r
+\r
+               if (rc != null)\r
+               {\r
+                       // This next call will walk through the ResultColumn tree\r
+                       // until it finds another ColumnReference, and then will\r
+                       // return the table number for that column reference.  We\r
+                       // can't stop there, though, because the column reference\r
+                       // that we found might in turn have column references beneath\r
+                       // it, and we only want the table number of the bottom-most\r
+                       // column reference.  So once we find the column reference,\r
+                       // we have to recurse.\r
+\r
+                       int baseTableNumber = rc.getTableNumber();\r
+                       if (baseTableNumber >= 0) {\r
+                       // Move down to the column reference that has the table\r
+                       // number that we just found.  There may be one or more\r
+                       // VirtualColumnNode-to-ResultColumnNode links between\r
+                       // the current ResultColumn and the column reference we're\r
+                       // looking for, so we have to walk past those until we find\r
+                       // the desired column reference.\r
+\r
+                               ValueNode rcExpr = rc.getExpression();\r
+                               while (rcExpr instanceof VirtualColumnNode) {\r
+                                       rc = ((VirtualColumnNode)rcExpr).getSourceColumn();\r
+                                       rcExpr = rc.getExpression();\r
+                               }\r
+\r
+                               if (rcExpr instanceof ColumnReference)\r
+                               // we found our column reference; recurse using that.\r
+                                       rcExpr.accept(this);\r
+                               else {\r
+                               // Else we must have found the table number someplace\r
+                               // other than within a ColumnReference (ex. we may\r
+                               // have pulled it from a VirtualColumnNode's source\r
+                               // table); so just set the number.\r
+                                       tableMap.set(baseTableNumber);\r
+                                       columnNumber = rc.getColumnPosition();\r
+                               }\r
+                       }\r
+                       else if (node instanceof ColumnReference) {\r
+                       // we couldn't find any other table numbers beneath the\r
+                       // ColumnReference, so just use the table number for\r
+                       // that reference.\r
+                               ColumnReference cr = (ColumnReference)node;\r
+                               cr.getTablesReferenced(tableMap);\r
+                               columnNumber = cr.getColumnNumber();\r
+                       }\r
+               }\r
+\r
+               return node;\r
+       }\r
+\r
+       /**\r
+        * @see org.apache.derby.iapi.sql.compile.Visitor#skipChildren\r
+        */\r
+       public boolean skipChildren(Visitable node)\r
+       {\r
+               /* A SelectNode's children can include a where clause in the\r
+                * form of either a PredicateList or an AndNode.  In either\r
+                * case we don't want to descend into the where clause because\r
+                * it's possible that it references a base table that is not\r
+                * in the subtree we're walking.  So we skip the children of\r
+                * a SelectNode.  Similarly, any other PredicateList may contain\r
+                * references to base tables that we don't want to include, so\r
+                * we skip a PredicateList's children as well.  Note, though,\r
+                * that if this visitor is specifically targeted for a particular\r
+                * Predicate or AndNode (i.e. a call is directly made to\r
+                * Predicate.accept() or AndNode.accept()) then we _will_ descend\r
+                * into that predicate's operands and retrieve referenced base\r
+                * table numbers.\r
+                *\r
+                * And finally, if we visit a FromBaseTable we can just grab\r
+                * it's number and that's it--there's no need to go any further.\r
+                */\r
+               return (node instanceof FromBaseTable) ||\r
+                       (node instanceof SelectNode) ||\r
+                       (node instanceof PredicateList);\r
+       }\r
+\r
+       /**\r
+        * @see org.apache.derby.iapi.sql.compile.Visitor#stopTraversal\r
+        */\r
+       public boolean stopTraversal()\r
+       {\r
+               return false;\r
+       }\r
+\r
+}      \r