Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / impl / sql / compile / BaseTypeCompiler.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/compile/BaseTypeCompiler.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/compile/BaseTypeCompiler.java
new file mode 100644 (file)
index 0000000..686add3
--- /dev/null
@@ -0,0 +1,384 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.compile.BaseTypeCompiler\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.reference.SQLState;\r
+import org.apache.derby.iapi.services.loader.ClassFactory;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.sql.compile.TypeCompiler;\r
+\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+import org.apache.derby.iapi.types.DataValueFactory;\r
+import org.apache.derby.iapi.types.NumberDataValue;\r
+import org.apache.derby.iapi.types.SQLInteger;\r
+import org.apache.derby.iapi.types.TypeId;\r
+\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+\r
+import org.apache.derby.iapi.services.compiler.LocalField;\r
+import org.apache.derby.iapi.services.compiler.MethodBuilder;\r
+\r
+import org.apache.derby.iapi.services.classfile.VMOpcode;\r
+\r
+/**\r
+ * This is the base implementation of TypeCompiler\r
+ *\r
+ */\r
+\r
+abstract class BaseTypeCompiler implements TypeCompiler\r
+{\r
+       private TypeId correspondingTypeId;\r
+\r
+       /**\r
+        * Get the method name for getting out the corresponding primitive\r
+        * Java type.\r
+        *\r
+        * @return String               The method call name for getting the\r
+        *                                              corresponding primitive Java type.\r
+        */\r
+       public String getPrimitiveMethodName()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.THROWASSERT("getPrimitiveMethodName not applicable for " +\r
+                                                                         getClass().toString());\r
+               }\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * @see TypeCompiler#resolveArithmeticOperation\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public DataTypeDescriptor\r
+       resolveArithmeticOperation(DataTypeDescriptor leftType,\r
+                                                               DataTypeDescriptor rightType,\r
+                                                               String operator)\r
+                                                       throws StandardException\r
+       {\r
+               throw StandardException.newException(SQLState.LANG_BINARY_OPERATOR_NOT_SUPPORTED, \r
+                                                                               operator,\r
+                                                                               leftType.getTypeId().getSQLTypeName(),\r
+                                                                               rightType.getTypeId().getSQLTypeName()\r
+                                                                               );\r
+       }\r
+\r
+    /**\r
+     * The caller will have pushed a DataValueFactory and a null or a value\r
+     * of the correct type (interfaceName()). Thus upon entry the\r
+     * stack looks like on of:\r
+     * ...,dvf,ref\r
+     * ...,dvf,null\r
+     * \r
+     * This method then sets up to call the required method\r
+     * on DataValueFactory using the nullMethodName().\r
+     * The value left on the stack will be a DataValueDescriptor\r
+     * of the correct type:\r
+     * \r
+     * ...,dvd\r
+     * \r
+     * @see TypeCompiler#generateNull(MethodBuilder, int)\r
+     */\r
+       public void generateNull(MethodBuilder mb, int collationType)\r
+       {\r
+        int argCount;\r
+        if (pushCollationForDataValue(collationType))\r
+        {\r
+            mb.push(collationType);\r
+            argCount = 2;\r
+        }\r
+        else\r
+            argCount = 1;\r
+        \r
+               mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null,\r
+                                                                       nullMethodName(),\r
+                                                                       interfaceName(),\r
+                                    argCount);\r
+       }\r
+\r
+    \r
+    /**\r
+     * The caller will have pushed a DataValueFactory and  value\r
+     * of that can be converted to the correct type, e.g. int\r
+     * for a SQL INTEGER.\r
+     *  \r
+     * Thus upon entry the\r
+     * stack looks like:\r
+     * ...,dvf,value\r
+     * \r
+     * If field is not null then it is used as the holder\r
+     * of the generated DataValueDescriptor to avoid object\r
+     * creations on multiple passes through this code.\r
+     * The field may contain null or a valid value.\r
+     * \r
+     * This method then sets up to call the required method\r
+     * on DataValueFactory using the dataValueMethodName().\r
+     * The value left on the stack will be a DataValueDescriptor\r
+     * of the correct type:\r
+     * \r
+     * If the field contained a valid value then generated\r
+     * code will return that value rather than a newly created\r
+     * object. If field was not-null then the generated code\r
+     * will set the value of field to be the return from\r
+     * the DataValueFactory method call. Thus if the field\r
+     * was empty (set to null) when this code is executed it\r
+     * will contain the newly generated value, otherwise it\r
+     * will be reset to the same value.\r
+     * \r
+     * ...,dvd\r
+     * \r
+     * @see TypeCompiler#generateDataValue(MethodBuilder, int, LocalField)\r
+     */\r
+    public void generateDataValue(MethodBuilder mb, int collationType,\r
+                       LocalField field)\r
+       {\r
+\r
+            \r
+               String                          interfaceName = interfaceName();\r
+\r
+               // push the second argument\r
+\r
+               /* If fieldName is null, then there is no\r
+                * reusable wrapper (null), else we\r
+                * reuse the field.\r
+                */\r
+               if (field == null)\r
+               {\r
+                       mb.pushNull(interfaceName);\r
+               }\r
+               else\r
+               {\r
+                       mb.getField(field);\r
+               }\r
+        \r
+        int argCount;\r
+        if (pushCollationForDataValue(collationType))\r
+        {\r
+            mb.push(collationType);\r
+            argCount = 3;\r
+        }\r
+        else\r
+            argCount = 2;\r
+\r
+               mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null,\r
+                                                       dataValueMethodName(),\r
+                                                       interfaceName,\r
+                            argCount);\r
+\r
+               if (field != null)\r
+               {\r
+                       /* Store the result of the method call in the field,\r
+                        * so we can re-use the wrapper.\r
+                        */\r
+                       mb.putField(field);\r
+               }\r
+       }\r
+\r
+    /**\r
+        Return the method name to get a Derby DataValueDescriptor\r
+        object of the correct type set to SQL NULL. The method named will\r
+        be called with one argument: a holder object if pushCollationForDataValue()\r
+        returns false, otherwise two arguments, the second being the\r
+        collationType.\r
+    */\r
+    abstract String nullMethodName();\r
+\r
+       /**\r
+               Return the method name to get a Derby DataValueDescriptor\r
+               object of the correct type and set it to a specific value.\r
+        The method named will be called with two arguments, a value to set the\r
+        returned value to and a holder object if pushCollationForDataValue()\r
+        returns false. Otherwise three arguments, the third being the\r
+        collationType.\r
+        This implementation returns "getDataValue" to map\r
+        to the overloaded methods\r
+        DataValueFactory.getDataValue(type, dvd type)\r
+       */\r
+       String dataValueMethodName()\r
+       {\r
+               return "getDataValue";\r
+       }\r
+    \r
+    /**\r
+     * Return true if the collationType is to be passed\r
+     * to the methods generated by generateNull and\r
+     * generateDataValue.\r
+     * \r
+     * @param collationType Collation type of character values.\r
+     * @return true collationType will be pushed, false collationType will be ignored.\r
+     */\r
+    boolean pushCollationForDataValue(int collationType)\r
+    {\r
+        return false;\r
+    }\r
+\r
+       \r
+       /**\r
+        * Determine whether thisType is storable in otherType due to otherType\r
+        * being a user type.\r
+        *\r
+        * @param thisType      The TypeId of the value to be stored\r
+        * @param otherType     The TypeId of the value to be stored in\r
+        *\r
+        * @return      true if thisType is storable in otherType\r
+        */\r
+       protected boolean userTypeStorable(TypeId thisType,\r
+                                                       TypeId otherType,\r
+                                                       ClassFactory cf)\r
+       {\r
+               /*\r
+               ** If the other type is user-defined, use the java types to determine\r
+               ** assignability.\r
+               */\r
+               if (otherType.userType())\r
+               {\r
+                       return cf.getClassInspector().assignableTo(\r
+                                       thisType.getCorrespondingJavaTypeName(),\r
+                                       otherType.getCorrespondingJavaTypeName());\r
+               }\r
+\r
+               return false;\r
+       }\r
+       \r
+       /**\r
+        * Tell whether this numeric type can be converted to the given type.\r
+        *\r
+        * @param otherType     The TypeId of the other type.\r
+        * @param forDataTypeFunction  was this called from a scalarFunction like\r
+        *                             CHAR() or DOUBLE()\r
+        */\r
+       public boolean numberConvertible(TypeId otherType, \r
+                                                                        boolean forDataTypeFunction)\r
+       {\r
+\r
+               // Can't convert numbers to long types\r
+               if (otherType.isLongConcatableTypeId())\r
+                       return false;\r
+\r
+               // Numbers can only be converted to other numbers, \r
+               // and CHAR, (not VARCHARS or LONGVARCHAR). \r
+               // Only with the CHAR() or VARCHAR()function can they be converted.\r
+               boolean retval =((otherType.isNumericTypeId()) ||\r
+                                                (otherType.isBooleanTypeId()) ||\r
+                                                (otherType.userType()));\r
+\r
+               // For CHAR  Conversions, function can convert \r
+               // Floating types\r
+               if (forDataTypeFunction)\r
+                       retval = retval || \r
+                               (otherType.isFixedStringTypeId() &&\r
+                               (getTypeId().isFloatingPointTypeId()));\r
+          \r
+               retval = retval ||\r
+                       (otherType.isFixedStringTypeId() &&                                       \r
+                        (!getTypeId().isFloatingPointTypeId()));\r
+               \r
+               return retval;\r
+\r
+       }\r
+\r
+       /**\r
+        * Tell whether this numeric type can be stored into from the given type.\r
+        *\r
+        * @param thisType      The TypeId of this type\r
+        * @param otherType     The TypeId of the other type.\r
+        * @param cf            A ClassFactory\r
+        */\r
+\r
+       public boolean numberStorable(TypeId thisType,\r
+                                                                       TypeId otherType,\r
+                                                                       ClassFactory cf)\r
+       {\r
+               /*\r
+               ** Numbers can be stored into from other number types.\r
+               ** Also, user types with compatible classes can be stored into numbers.\r
+               */\r
+               if ((otherType.isNumericTypeId())       ||\r
+                       (otherType.isBooleanTypeId()))\r
+                       return true;\r
+\r
+               /*\r
+               ** If the other type is user-defined, use the java types to determine\r
+               ** assignability.\r
+               */\r
+               return userTypeStorable(thisType, otherType, cf);\r
+       }\r
+\r
+\r
+       /**\r
+        * Get the TypeId that corresponds to this TypeCompiler.\r
+        */\r
+       protected TypeId getTypeId()\r
+       {\r
+               return correspondingTypeId;\r
+       }\r
+\r
+       /**\r
+        * Get the TypeCompiler that corresponds to the given TypeId.\r
+        */\r
+       protected TypeCompiler getTypeCompiler(TypeId typeId)\r
+       {\r
+               return TypeCompilerFactoryImpl.staticGetTypeCompiler(typeId);\r
+       }\r
+\r
+       /**\r
+        * Set the TypeCompiler that corresponds to the given TypeId.\r
+        */\r
+       void setTypeId(TypeId typeId)\r
+       {\r
+               correspondingTypeId = typeId;\r
+       }\r
+\r
+       /**\r
+        * Get the StoredFormatId from the corresponding\r
+        * TypeId.\r
+        *\r
+        * @return The StoredFormatId from the corresponding\r
+        * TypeId.\r
+        */\r
+       protected int getStoredFormatIdFromTypeId()\r
+       {\r
+               return getTypeId().getTypeFormatId();\r
+       }\r
+\r
+    private static DataValueDescriptor gnn(DataValueFactory dvf)\r
+    {\r
+        return dvf.getNullInteger((NumberDataValue) null);\r
+    }\r
+    \r
+    private static DataValueDescriptor gnn2(DataValueFactory dvf)\r
+    {\r
+        return new SQLInteger();\r
+    }\r
+    \r
+\r
+}\r
+\r
+\r
+\r
+\r
+\r