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 / BetweenOperatorNode.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/BetweenOperatorNode.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/BetweenOperatorNode.java
new file mode 100644 (file)
index 0000000..40bf4bb
--- /dev/null
@@ -0,0 +1,322 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.compile.BetweenOperatorNode\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.error.StandardException;\r
+\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;\r
+\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+\r
+import org.apache.derby.iapi.sql.compile.C_NodeTypes;\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.impl.sql.compile.ExpressionClassBuilder;\r
+import org.apache.derby.impl.sql.compile.ActivationClassBuilder;\r
+import org.apache.derby.iapi.sql.compile.NodeFactory;\r
+import org.apache.derby.iapi.services.context.ContextManager;\r
+\r
+/**\r
+ * A BetweenOperatorNode represents a BETWEEN clause. The between values are\r
+ * represented as a 2 element list in order to take advantage of code reuse.\r
+ *\r
+ */\r
+\r
+public class BetweenOperatorNode extends BinaryListOperatorNode\r
+{\r
+       /**\r
+        * Initializer for a BetweenOperatorNode\r
+        *\r
+        * @param leftOperand           The left operand of the node\r
+        * @param betweenValues         The between values in list form\r
+        */\r
+\r
+       public void init(Object leftOperand, Object betweenValues)\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       ValueNodeList betweenVals = (ValueNodeList) betweenValues;\r
+\r
+                       SanityManager.ASSERT(betweenVals.size() == 2,\r
+                               "betweenValues.size() (" +\r
+                               betweenVals.size()      +\r
+                               ") is expected to be 2");\r
+               }\r
+\r
+               super.init(leftOperand, betweenValues, "BETWEEN", null);\r
+       }\r
+\r
+       /**\r
+        * Eliminate NotNodes in the current query block.  We traverse the tree, \r
+        * inverting ANDs and ORs and eliminating NOTs as we go.  We stop at \r
+        * ComparisonOperators and boolean expressions.  We invert \r
+        * ComparisonOperators and replace boolean expressions with \r
+        * boolean expression = false.\r
+        * NOTE: Since we do not recurse under ComparisonOperators, there\r
+        * still could be NotNodes left in the tree.\r
+        *\r
+        * @param       underNotNode            Whether or not we are under a NotNode.\r
+        *                                                      \r
+        *\r
+        * @return              The modified expression\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       ValueNode eliminateNots(boolean underNotNode) \r
+                                       throws StandardException\r
+       {\r
+               BinaryComparisonOperatorNode leftBCO;\r
+               BinaryComparisonOperatorNode rightBCO;\r
+               OrNode                                           newOr;\r
+\r
+               if (SanityManager.DEBUG)\r
+               SanityManager.ASSERT(rightOperandList.size() == 2,\r
+                       "rightOperandList.size() (" +\r
+                       rightOperandList.size() +\r
+                       ") is expected to be 2");\r
+\r
+               if (! underNotNode)\r
+               {\r
+                       return this;\r
+               }\r
+\r
+               /* we want to convert the BETWEEN  * into < OR > \r
+                  as described below.\r
+               */              \r
+\r
+               /* Convert:\r
+                *              leftO between rightOList.elementAt(0) and rightOList.elementAt(1)\r
+                * to:\r
+                *              leftO < rightOList.elementAt(0) or leftO > rightOList.elementAt(1)\r
+                * NOTE - We do the conversion here since ORs will eventually be\r
+                * optimizable and there's no benefit for the optimizer to see NOT BETWEEN\r
+                */\r
+\r
+               NodeFactory nodeFactory = getNodeFactory();\r
+               ContextManager cm = getContextManager();\r
+\r
+               /* leftO < rightOList.elementAt(0) */\r
+               leftBCO = (BinaryComparisonOperatorNode) \r
+                                       nodeFactory.getNode(\r
+                                                                       C_NodeTypes.BINARY_LESS_THAN_OPERATOR_NODE,\r
+                                                                       leftOperand, \r
+                                                                       rightOperandList.elementAt(0),\r
+                                                                       cm);\r
+               /* Set type info for the operator node */\r
+               leftBCO.bindComparisonOperator();\r
+\r
+               /* leftO > rightOList.elementAt(1) */\r
+               rightBCO = (BinaryComparisonOperatorNode) \r
+                                       nodeFactory.getNode(\r
+                                                               C_NodeTypes.BINARY_GREATER_THAN_OPERATOR_NODE,\r
+                                                               leftOperand, \r
+                                                               rightOperandList.elementAt(1),\r
+                                                               cm);\r
+               /* Set type info for the operator node */\r
+               rightBCO.bindComparisonOperator();\r
+\r
+               /* Create and return the OR */\r
+               newOr = (OrNode) nodeFactory.getNode(\r
+                                                                                               C_NodeTypes.OR_NODE,\r
+                                                                                               leftBCO,\r
+                                                                                               rightBCO,\r
+                                                                                               cm);\r
+               newOr.postBindFixup();\r
+\r
+               /* Tell optimizer to use the between selectivity instead of >= * <= selectivities */\r
+               leftBCO.setBetweenSelectivity();\r
+               rightBCO.setBetweenSelectivity();\r
+\r
+               return newOr;\r
+       }\r
+\r
+       /**\r
+        * Preprocess an expression tree.  We do a number of transformations\r
+        * here (including subqueries, IN lists, LIKE and BETWEEN) plus\r
+        * subquery flattening.\r
+        * NOTE: This is done before the outer ResultSetNode is preprocessed.\r
+        *\r
+        * @param       numTables                       Number of tables in the DML Statement\r
+        * @param       outerFromList           FromList from outer query block\r
+        * @param       outerSubqueryList       SubqueryList from outer query block\r
+        * @param       outerPredicateList      PredicateList from outer query block\r
+        *\r
+        * @return              The modified expression\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public ValueNode preprocess(int numTables,\r
+                                                               FromList outerFromList,\r
+                                                               SubqueryList outerSubqueryList,\r
+                                                               PredicateList outerPredicateList) \r
+                                       throws StandardException\r
+       {\r
+               ValueNode       leftClone1;\r
+               ValueNode       rightOperand;\r
+\r
+               /* We must 1st preprocess the component parts */\r
+               super.preprocess(numTables,\r
+                                                outerFromList, outerSubqueryList,\r
+                                                outerPredicateList);\r
+\r
+               /* This is where we do the transformation for BETWEEN to make it optimizable.\r
+                * c1 BETWEEN value1 AND value2 -> c1 >= value1 AND c1 <= value2\r
+                * This transformation is only done if the leftOperand is a ColumnReference.\r
+                */\r
+               if (!(leftOperand instanceof ColumnReference))\r
+               {\r
+                       return this;\r
+               }\r
+\r
+               /* For some unknown reason we need to clone the leftOperand if it is\r
+                * a ColumnReference because reusing them in Qualifiers for a scan\r
+                * does not work.  \r
+                */\r
+               leftClone1 = leftOperand.getClone();\r
+\r
+               /* The transformed tree has to be normalized:\r
+                *                              AND\r
+                *                         /   \\r
+                *                        >=    AND\r
+                *                                 /   \\r
+                *                                <=    TRUE\r
+                */\r
+\r
+               NodeFactory nodeFactory = getNodeFactory();\r
+               ContextManager cm = getContextManager();\r
+\r
+        QueryTreeNode trueNode = nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.BOOLEAN_CONSTANT_NODE,\r
+                                                                                       Boolean.TRUE,\r
+                                                                                       cm);\r
+\r
+               /* Create the AND <= */\r
+               BinaryComparisonOperatorNode lessEqual = \r
+                       (BinaryComparisonOperatorNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.BINARY_LESS_EQUALS_OPERATOR_NODE,\r
+                                               leftClone1, \r
+                                               rightOperandList.elementAt(1),\r
+                                               cm);\r
+\r
+               /* Set type info for the operator node */\r
+               lessEqual.bindComparisonOperator();\r
+\r
+               /* Create the AND */\r
+               AndNode newAnd = (AndNode) nodeFactory.getNode(\r
+                                                                                               C_NodeTypes.AND_NODE,\r
+                                                                                               lessEqual,\r
+                                                                                               trueNode,\r
+                                                                                               cm);\r
+               newAnd.postBindFixup();\r
+\r
+               /* Create the AND >= */\r
+               BinaryComparisonOperatorNode greaterEqual = \r
+                       (BinaryComparisonOperatorNode) nodeFactory.getNode(\r
+                                       C_NodeTypes.BINARY_GREATER_EQUALS_OPERATOR_NODE,\r
+                                       leftOperand, \r
+                                       rightOperandList.elementAt(0),\r
+                                       cm);\r
+\r
+               /* Set type info for the operator node */\r
+               greaterEqual.bindComparisonOperator();\r
+\r
+               /* Create the AND */\r
+               newAnd = (AndNode) nodeFactory.getNode(\r
+                                                                                               C_NodeTypes.AND_NODE,\r
+                                                                                               greaterEqual,\r
+                                                                                               newAnd,\r
+                                                                                               cm);\r
+               newAnd.postBindFixup();\r
+\r
+               /* Tell optimizer to use the between selectivity instead of >= * <= selectivities */\r
+               lessEqual.setBetweenSelectivity();\r
+               greaterEqual.setBetweenSelectivity();\r
+\r
+               return newAnd;\r
+       }\r
\r
+       /**\r
+        * Do code generation for this BETWEEN operator.\r
+        *\r
+        * @param acb   The ExpressionClassBuilder for the class we're generating\r
+        * @param mb    The method the code to place the code\r
+        *\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+\r
+       public void generateExpression(ExpressionClassBuilder acb,\r
+                                                                                       MethodBuilder mb)\r
+               throws StandardException\r
+       {\r
+               AndNode                                          newAnd;\r
+               BinaryComparisonOperatorNode leftBCO;\r
+               BinaryComparisonOperatorNode rightBCO;\r
+\r
+               if (SanityManager.DEBUG)\r
+               SanityManager.ASSERT(rightOperandList.size() == 2,\r
+                       "rightOperandList.size() (" +\r
+                       rightOperandList.size() +\r
+                       ") is expected to be 2");\r
+\r
+               /* Convert:\r
+                *              leftO between rightOList.elementAt(0) and rightOList.elementAt(1)\r
+                * to:\r
+                *              leftO >= rightOList.elementAt(0) and leftO <= rightOList.elementAt(1) \r
+                */\r
+\r
+               NodeFactory nodeFactory = getNodeFactory();\r
+               ContextManager cm = getContextManager();\r
+\r
+               /* leftO >= rightOList.elementAt(0) */\r
+               leftBCO = (BinaryComparisonOperatorNode) \r
+                                       nodeFactory.getNode(\r
+                                                       C_NodeTypes.BINARY_GREATER_EQUALS_OPERATOR_NODE,\r
+                                                       leftOperand, \r
+                                                       rightOperandList.elementAt(0),\r
+                                                       cm);\r
+               /* Set type info for the operator node */\r
+               leftBCO.bindComparisonOperator();\r
+\r
+               /* leftO <= rightOList.elementAt(1) */\r
+               rightBCO = (BinaryComparisonOperatorNode) \r
+                                       nodeFactory.getNode(\r
+                                               C_NodeTypes.BINARY_LESS_EQUALS_OPERATOR_NODE,\r
+                                               leftOperand, \r
+                                               rightOperandList.elementAt(1),\r
+                                               cm);\r
+               /* Set type info for the operator node */\r
+               rightBCO.bindComparisonOperator();\r
+\r
+               /* Create and return the AND */\r
+               newAnd = (AndNode) nodeFactory.getNode(\r
+                                                                                               C_NodeTypes.AND_NODE,\r
+                                                                                               leftBCO,\r
+                                                                                               rightBCO,\r
+                                                                                               cm);\r
+               newAnd.postBindFixup();\r
+               newAnd.generateExpression(acb, mb);\r
+       }\r
+}\r