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 / ExtractOperatorNode.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/ExtractOperatorNode.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/ExtractOperatorNode.java
new file mode 100644 (file)
index 0000000..7f1d694
--- /dev/null
@@ -0,0 +1,186 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.compile.ExtractOperatorNode\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.C_NodeTypes;\r
+\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+\r
+import org.apache.derby.iapi.types.TypeId;\r
+import org.apache.derby.iapi.types.DateTimeDataValue;\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+\r
+import org.apache.derby.iapi.sql.compile.TypeCompiler;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import java.sql.Types;\r
+\r
+import java.util.Vector;\r
+\r
+/**\r
+ * This node represents a unary extract operator, used to extract\r
+ * a field from a date/time. The field value is returned as an integer.\r
+ *\r
+ */\r
+public class ExtractOperatorNode extends UnaryOperatorNode {\r
+\r
+       static private final String fieldName[] = {\r
+               "YEAR", "MONTH", "DAY", "HOUR", "MINUTE", "SECOND"\r
+       };\r
+       static private final String fieldMethod[] = {\r
+               "getYear","getMonth","getDate","getHours","getMinutes","getSeconds"\r
+       };\r
+\r
+       private int extractField;\r
+\r
+       /**\r
+        * Initializer for a ExtractOperatorNode\r
+        *\r
+        * @param field         The field to extract\r
+        * @param operand       The operand\r
+        */\r
+       public void init(Object field, Object operand) {\r
+               extractField = ((Integer) field).intValue();\r
+               super.init( operand,\r
+                                       "EXTRACT "+fieldName[extractField],\r
+                                       fieldMethod[extractField] );\r
+       }\r
+\r
+       /**\r
+        * Bind this operator\r
+        *\r
+        * @param fromList                      The query's FROM list\r
+        * @param subqueryList          The subquery list being built as we find SubqueryNodes\r
+        * @param aggregateVector       The aggregate vector being built as we find AggregateNodes\r
+        *\r
+        * @return      The new top of the expression tree.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+\r
+       public ValueNode bindExpression(\r
+               FromList                fromList, \r
+               SubqueryList    subqueryList,\r
+               Vector  aggregateVector)\r
+                       throws StandardException \r
+       {\r
+               int     operandType;\r
+               TypeId opTypeId;\r
+\r
+               bindOperand(fromList, subqueryList,\r
+                               aggregateVector);\r
+\r
+               opTypeId = operand.getTypeId();\r
+               operandType = opTypeId.getJDBCTypeId();\r
+               TypeCompiler tc = operand.getTypeCompiler();\r
+\r
+               /*\r
+               ** Cast the operand, if necessary, - this function is allowed only on\r
+               ** date/time types.  By default, we cast to DATE if extracting\r
+               ** YEAR, MONTH or DAY and to TIME if extracting HOUR, MINUTE or\r
+               ** SECOND.\r
+               */\r
+               if (opTypeId.isStringTypeId())\r
+               {\r
+                       int castType = (extractField < 3) ? Types.DATE : Types.TIME;\r
+                       operand =  (ValueNode)\r
+                               getNodeFactory().getNode(\r
+                                       C_NodeTypes.CAST_NODE,\r
+                                       operand, \r
+                                       DataTypeDescriptor.getBuiltInDataTypeDescriptor(castType, true, \r
+                                                                               tc.getCastToCharWidth(\r
+                                                                                               operand.getTypeServices())),\r
+                                       getContextManager());\r
+                       ((CastNode) operand).bindCastNodeOnly();\r
+\r
+                       opTypeId = operand.getTypeId();\r
+                       operandType = opTypeId.getJDBCTypeId();\r
+               }\r
+\r
+               if ( ! ( ( operandType == Types.DATE )\r
+                          || ( operandType == Types.TIME ) \r
+                          || ( operandType == Types.TIMESTAMP ) \r
+                       )       ) {\r
+                       throw StandardException.newException(SQLState.LANG_UNARY_FUNCTION_BAD_TYPE, \r
+                                               "EXTRACT "+fieldName[extractField],\r
+                                               opTypeId.getSQLTypeName());\r
+               }\r
+\r
+               /*\r
+                       If the type is DATE, ensure the field is okay.\r
+                */\r
+               if ( (operandType == Types.DATE) \r
+                        && (extractField > DateTimeDataValue.DAY_FIELD) ) {\r
+                       throw StandardException.newException(SQLState.LANG_UNARY_FUNCTION_BAD_TYPE, \r
+                                               "EXTRACT "+fieldName[extractField],\r
+                                               opTypeId.getSQLTypeName());\r
+               }\r
+\r
+               /*\r
+                       If the type is TIME, ensure the field is okay.\r
+                */\r
+               if ( (operandType == Types.TIME) \r
+                        && (extractField < DateTimeDataValue.HOUR_FIELD) ) {\r
+                       throw StandardException.newException(SQLState.LANG_UNARY_FUNCTION_BAD_TYPE, \r
+                                               "EXTRACT "+fieldName[extractField],\r
+                                               opTypeId.getSQLTypeName());\r
+               }\r
+\r
+               /*\r
+               ** The result type of extract is int,\r
+               ** unless it is TIMESTAMP and SECOND, in which case\r
+               ** for now it is DOUBLE but eventually it will need to\r
+               ** be DECIMAL(11,9).\r
+               */\r
+               if ( (operandType == Types.TIMESTAMP)\r
+                        && (extractField == DateTimeDataValue.SECOND_FIELD) ) {\r
+                       setType(new DataTypeDescriptor(\r
+                                                       TypeId.getBuiltInTypeId(Types.DOUBLE),\r
+                                                       operand.getTypeServices().isNullable()\r
+                                               )\r
+                               );\r
+               } else {\r
+                       setType(new DataTypeDescriptor(\r
+                                                       TypeId.INTEGER_ID,\r
+                                                       operand.getTypeServices().isNullable()\r
+                                               )\r
+                               );\r
+               }\r
+\r
+               return this;\r
+       }\r
+\r
+       public String toString() {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       return super.toString() + "field is "+fieldName[extractField]+"\n";\r
+               }\r
+               else\r
+               {\r
+                       return "";\r
+               }\r
+       }\r
+}\r