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 / JavaValueNode.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/JavaValueNode.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/JavaValueNode.java
new file mode 100644 (file)
index 0000000..b1edb67
--- /dev/null
@@ -0,0 +1,471 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.compile.JavaValueNode\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.CompilerContext;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.services.context.ContextManager;\r
+\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;\r
+\r
+import org.apache.derby.iapi.types.TypeId;\r
+\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.services.i18n.MessageService;\r
+import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;\r
+import org.apache.derby.impl.sql.compile.ActivationClassBuilder;\r
+\r
+import org.apache.derby.iapi.types.JSQLType;\r
+\r
+import org.apache.derby.iapi.services.compiler.LocalField;\r
+import org.apache.derby.iapi.services.compiler.MethodBuilder;\r
+\r
+\r
+import org.apache.derby.iapi.services.loader.ClassInspector;\r
+\r
+import org.apache.derby.iapi.store.access.Qualifier;\r
+\r
+import org.apache.derby.iapi.util.JBitSet;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import java.lang.reflect.Modifier;\r
+\r
+import java.util.Vector;\r
+\r
+/**\r
+ * This abstract node class represents a data value in the Java domain.\r
+ */\r
+\r
+abstract class JavaValueNode extends QueryTreeNode\r
+{\r
+       private boolean mustCastToPrimitive;\r
+\r
+       protected boolean forCallStatement;\r
+       private boolean valueReturnedToSQLDomain;\r
+       private boolean returnValueDiscarded;\r
+\r
+       protected       JSQLType        jsqlType;\r
+\r
+       /* Name of field holding receiver value, if any */\r
+       private LocalField receiverField;\r
+\r
+        // * Collation type of schema where method is defined. \r
+       private int collationType;\r
+\r
+       public boolean isPrimitiveType() throws StandardException\r
+       {\r
+               JSQLType        myType = getJSQLType();\r
+               \r
+               if ( myType == null ) { return false; }\r
+               else { return ( myType.getCategory() == JSQLType.JAVA_PRIMITIVE ); }\r
+       }\r
+\r
+       public String getJavaTypeName() throws StandardException\r
+       {\r
+               JSQLType        myType = getJSQLType();\r
+\r
+               if ( myType == null ) { return ""; }\r
+\r
+               switch( myType.getCategory() )\r
+               {\r
+                   case JSQLType.JAVA_CLASS: return myType.getJavaClassName();\r
+\r
+                   case JSQLType.JAVA_PRIMITIVE: return JSQLType.primitiveNames[ myType.getPrimitiveKind() ];\r
+\r
+                   default:\r
+\r
+                               if (SanityManager.DEBUG)\r
+                               { SanityManager.THROWASSERT( "Inappropriate JSQLType: " + myType ); }\r
+               }\r
+\r
+               return "";\r
+       }\r
+\r
+       public void setJavaTypeName(String javaTypeName)\r
+       {\r
+               jsqlType = new JSQLType( javaTypeName );\r
+       }\r
+\r
+       public String getPrimitiveTypeName()\r
+               throws StandardException\r
+       {\r
+               JSQLType        myType = getJSQLType();\r
+\r
+               if ( myType == null ) { return ""; }\r
+\r
+               switch( myType.getCategory() )\r
+               {\r
+                   case JSQLType.JAVA_PRIMITIVE: return JSQLType.primitiveNames[ myType.getPrimitiveKind() ];\r
+\r
+                   default:\r
+\r
+                               if (SanityManager.DEBUG)\r
+                               { SanityManager.THROWASSERT( "Inappropriate JSQLType: " + myType ); }\r
+               }\r
+\r
+               return "";\r
+       }\r
+\r
+       /**\r
+         *     Toggles whether the code generator should add a cast to extract a primitive\r
+         *     value from an object.\r
+         *\r
+         *     @param  booleanValue    true if we want the code generator to add a cast\r
+         *                                                     false otherwise\r
+         */\r
+       public void castToPrimitive(boolean booleanValue)\r
+       {\r
+               mustCastToPrimitive = booleanValue;\r
+       }\r
+\r
+       /**\r
+         *     Reports whether the code generator should add a cast to extract a primitive\r
+         *     value from an object.\r
+         *\r
+         *     @return true if we want the code generator to add a cast\r
+         *                             false otherwise\r
+         */\r
+       public  boolean mustCastToPrimitive() { return mustCastToPrimitive; }\r
+\r
+       /**\r
+         *     Get the JSQLType that corresponds to this node. Could be a SQLTYPE,\r
+         *     a Java primitive, or a Java class.\r
+         *\r
+         *     @return the corresponding JSQLType\r
+         *\r
+         */\r
+       public  JSQLType        getJSQLType() throws StandardException\r
+       { return jsqlType; }\r
+\r
+\r
+       /**\r
+         *     Map a JSQLType to a compilation type id.\r
+         *\r
+         *     @param  jsqlType        the universal type to map\r
+         *\r
+         *     @return the corresponding compilation type id\r
+         *\r
+         */\r
+       public  TypeId  mapToTypeID( JSQLType jsqlType )\r
+       {\r
+               DataTypeDescriptor      dts = jsqlType.getSQLType();\r
+\r
+               if ( dts == null ) { return null; }\r
+\r
+               return dts.getTypeId();\r
+       }\r
+\r
+       /**\r
+        * Mark this node as being for a CALL Statement.\r
+        * (void methods are only okay for CALL Statements)\r
+        */\r
+       public void markForCallStatement()\r
+       {\r
+               forCallStatement = true;\r
+       }\r
+\r
+       /**\r
+        * @see ValueNode#remapColumnReferencesToExpressions\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       abstract public JavaValueNode remapColumnReferencesToExpressions()\r
+               throws StandardException;\r
+\r
+       /**\r
+        * @see ValueNode#categorize\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       abstract public boolean categorize(JBitSet referencedTabs, boolean simplePredsOnly)\r
+               throws StandardException;\r
+\r
+       /**\r
+        * @see ValueNode#bindExpression\r
+        *\r
+        * @return the new node, usually this\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       abstract JavaValueNode bindExpression(FromList fromList, SubqueryList subqueryList,\r
+                                                       Vector aggregateVector) \r
+                                                       throws StandardException;\r
+       /**\r
+        * @see ValueNode#preprocess\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       abstract public void preprocess(int numTables,\r
+                                                                       FromList outerFromList,\r
+                                                                       SubqueryList outerSubqueryList,\r
+                                                                       PredicateList outerPredicateList)\r
+                                                       throws StandardException;\r
+\r
+       /** @see ValueNode#getConstantValueAsObject \r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       Object getConstantValueAsObject()\r
+               throws StandardException\r
+       {\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Do the code generation for this node.  Call the more general\r
+        * routine that generates expressions.\r
+        *\r
+        * @param acb   The ActivationClassBuilder for the class being built\r
+        * @param mb the method  the expression will go into\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+\r
+       protected final void generate(ActivationClassBuilder acb,\r
+                                                                               MethodBuilder mb)\r
+                                                                       throws StandardException\r
+       {\r
+               generateExpression( acb, mb );\r
+       }\r
+\r
+       /**\r
+        * Generate the expression that evaluates to the receiver. This is\r
+        * for the case where a java expression is being returned to the SQL\r
+        * domain, and we need to check whether the receiver is null (if so,\r
+        * the SQL value should be set to null, and this Java expression\r
+        * not evaluated). Instance method calls and field references have\r
+        * receivers, while class method calls and calls to constructors do\r
+        * not. If this Java expression does not have a receiver, this method\r
+        * returns null.\r
+        *\r
+        * The implementation of this method should only generate the receiver\r
+        * once and cache it in a field. This is because there will be two\r
+        * references to the receiver, and we want to evaluate it only once.\r
+        *\r
+        *\r
+        * @param acb   The ExpressionClassBuilder for the class being built\r
+        * @param mb the method  the expression will go into\r
+        *\r
+        * @return              True if has compiled receiver.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       protected boolean generateReceiver(ExpressionClassBuilder acb,\r
+                                                                                                       MethodBuilder mb)\r
+                                                                       throws StandardException\r
+       {\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Return the variant type for the underlying expression.\r
+        * The variant type can be:\r
+        *              VARIANT                         - variant within a scan\r
+        *                                                        (method calls and non-static field access)\r
+        *              SCAN_INVARIANT          - invariant within a scan\r
+        *                                                        (column references from outer tables)\r
+        *              QUERY_INVARIANT         - invariant within the life of a query\r
+        *                                                        (constant expressions)\r
+        *\r
+        * @return      The variant type for the underlying expression.\r
+        */\r
+       protected int getOrderableVariantType() throws StandardException\r
+       {\r
+               // The default is VARIANT\r
+               return Qualifier.VARIANT;\r
+               //return Qualifier.SCAN_INVARIANT;\r
+       }\r
+\r
+       /**\r
+        * General logic shared by Core compilation and by the Replication Filter\r
+        * compiler. Every child of ValueNode must implement one of these methods.\r
+        *\r
+        * @param acb   The ExpressionClassBuilder for the class being built\r
+        * @param mb the method the expression will go into\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+\r
+       protected abstract  void generateExpression(\r
+                                                                                       ExpressionClassBuilder acb,\r
+                                                                                       MethodBuilder mb)\r
+                                                                       throws StandardException;\r
+\r
+       /**\r
+        * Generate the expression that evaluates to the receiver. This is\r
+        * for the case where a java expression is being returned to the SQL\r
+        * domain, and we need to check whether the receiver is null (if so,\r
+        * the SQL value should be set to null, and this Java expression\r
+        * not evaluated). Instance method calls and field references have\r
+        * receivers, while class method calls and calls to constructors do\r
+        * not. If this Java expression does not have a receiver, this method\r
+        * returns null.\r
+        *\r
+        * This also covers the case where a java expression is being returned\r
+        * to the Java domain. In this case, we need to check whether the\r
+        * receiver is null only if the value returned by the Java expression\r
+        * is an object (not a primitive type). We don't want to generate the\r
+        * expression here if we are returning a primitive type to the Java\r
+        * domain, because there's no point in checking whether the receiver\r
+        * is null in this case (we can't make the expression return a null\r
+        * value).\r
+        *\r
+        * Only generate the receiver once and cache it in a field. This is\r
+        * because there will be two references to the receiver, and we want\r
+        * to evaluate it only once.\r
+        *\r
+        *\r
+        * @param acb   The ActivationClassBuilder for the class being built\r
+        * @param mb the method the expression will go into\r
+        * @param receiver      The query tree form of the receiver expression\r
+        *\r
+        * @return              The compiled receiver, if any.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       protected final boolean generateReceiver(ExpressionClassBuilder acb,\r
+                                                                                       MethodBuilder mb,\r
+                                                                                       JavaValueNode receiver)\r
+                                                                       throws StandardException\r
+       {\r
+               ClassInspector classInspector = getClassFactory().getClassInspector();\r
+\r
+               /*\r
+               ** Don't generate the expression now if it returns a primitive\r
+               ** type to the Java domain.\r
+               */\r
+               if ( (! valueReturnedToSQLDomain()) &&\r
+                               classInspector.primitiveType(getJavaTypeName()))\r
+               {\r
+                       return false;\r
+               }\r
+\r
+               /*\r
+               ** Generate the following:\r
+               **\r
+               ** <receiver class> <field name>;\r
+               ** <field name> = <receiver>;\r
+               **\r
+               ** for non-static calls.\r
+               */\r
+\r
+               String receiverClassName = receiver.getJavaTypeName();\r
+               receiverField =\r
+                               acb.newFieldDeclaration(Modifier.PRIVATE, receiverClassName);\r
+\r
+               receiver.generateExpression(acb, mb);\r
+               mb.putField(receiverField);\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Get an expression that has the value of the receiver. If a field\r
+        * holding the receiver value was already generated, use that.  If not,\r
+        * generate the receiver value.\r
+        *\r
+        * @param acb   The ExpressionClassBuilder for the class we're generating\r
+        * @param mb the method  the expression will go into\r
+        * @param receiver      The query tree form of the receiver expression\r
+        *\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       protected final void getReceiverExpression(ExpressionClassBuilder acb,\r
+                                                                       MethodBuilder mb,\r
+                                                                       JavaValueNode receiver)\r
+                                                                               throws StandardException\r
+       {\r
+               if (receiverField != null)\r
+               {\r
+                       mb.getField(receiverField);\r
+               }\r
+               else\r
+               {\r
+                       receiver.generateExpression(acb, mb);\r
+               }\r
+       }\r
+\r
+       /** Inform this node that it returns its value to the SQL domain */\r
+       protected void returnValueToSQLDomain()\r
+       {\r
+               valueReturnedToSQLDomain = true;\r
+       }\r
+\r
+       /** Tell whether this node returns its value to the SQL domain */\r
+       protected boolean valueReturnedToSQLDomain()\r
+       {\r
+               return valueReturnedToSQLDomain;\r
+       }\r
+\r
+       /** Tell this node that nothing is done with the returned value */\r
+       protected void markReturnValueDiscarded()\r
+       {\r
+               returnValueDiscarded = true;\r
+       }\r
+\r
+       /** Tell whether the return value from this node is discarded */\r
+       protected boolean returnValueDiscarded()\r
+       {\r
+               return returnValueDiscarded;\r
+       }\r
+\r
+       /**\r
+               Check the reliability type of this java value.\r
+\r
+           @exception StandardException                Thrown on error\r
+\r
+               @see org.apache.derby.iapi.sql.compile.CompilerContext\r
+       */\r
+       public void checkReliability(ValueNode sqlNode) throws StandardException {\r
+        sqlNode.checkReliability( \r
+                CompilerContext.FUNCTION_CALL_ILLEGAL,\r
+                SQLState.LANG_JAVA_METHOD_CALL_OR_FIELD_REF\r
+                );\r
+       }\r
+\r
+    /**\r
+     * @return collationType as set by setCollationType\r
+     */\r
+    public int getCollationType() {\r
+        return collationType;\r
+    }\r
+    \r
+    /**\r
+     * Set the collation type.\r
+     * This will be used to determine the collation type for \r
+     * the SQLToJavaValueNode.\r
+     * \r
+     * @param type one of <code>StringDataValue.COLLATION_TYPE_UCS_BASIC </code> or\r
+     *                    <code>StringDataValue.COLLATION_TYPE_TERRITORY_BASED </code>  \r
+     */\r
+    public void setCollationType(int type) {\r
+        collationType = type;\r
+    }\r
+    \r
+    \r
+}\r