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 / ExpressionClassBuilder.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/ExpressionClassBuilder.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/ExpressionClassBuilder.java
new file mode 100644 (file)
index 0000000..5e07194
--- /dev/null
@@ -0,0 +1,932 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.compile.ExpressionClassBuilder\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
+\r
+import org.apache.derby.iapi.services.compiler.ClassBuilder;\r
+import org.apache.derby.iapi.services.compiler.MethodBuilder;\r
+import org.apache.derby.iapi.services.compiler.JavaFactory;\r
+import org.apache.derby.iapi.services.compiler.LocalField;\r
+import org.apache.derby.iapi.reference.ClassName;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.sql.compile.CompilerContext;\r
+import org.apache.derby.iapi.sql.compile.ExpressionClassBuilderInterface;\r
+\r
+import org.apache.derby.iapi.sql.execute.ResultSetFactory;\r
+import org.apache.derby.iapi.sql.execute.ExecutionFactory;\r
+import org.apache.derby.iapi.sql.execute.ExecIndexRow;\r
+\r
+import org.apache.derby.iapi.sql.Activation;\r
+import org.apache.derby.iapi.sql.ParameterValueSet;\r
+import org.apache.derby.iapi.sql.Row;\r
+\r
+import org.apache.derby.iapi.sql.execute.ExecRow;\r
+\r
+import org.apache.derby.impl.sql.compile.OrderedColumnList;\r
+import org.apache.derby.impl.sql.compile.ResultColumnList;\r
+import org.apache.derby.impl.sql.execute.IndexColumnOrder;\r
+import org.apache.derby.iapi.store.access.ColumnOrdering;\r
+\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+import org.apache.derby.iapi.types.DataValueFactory;\r
+import org.apache.derby.iapi.types.TypeId;\r
+\r
+import org.apache.derby.iapi.sql.compile.TypeCompiler;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.util.ByteArray;\r
+\r
+import org.apache.derby.iapi.services.loader.ClassFactory;\r
+import org.apache.derby.iapi.services.loader.GeneratedClass;\r
+import org.apache.derby.iapi.services.loader.GeneratedByteCode;\r
+import org.apache.derby.iapi.services.loader.GeneratedMethod;\r
+\r
+import java.lang.reflect.Modifier;\r
+import org.apache.derby.iapi.services.classfile.VMOpcode;\r
+\r
+import org.apache.derby.iapi.services.monitor.Monitor;\r
+\r
+import org.apache.derby.iapi.services.io.FormatableArrayHolder;\r
+\r
+import java.io.Serializable;\r
+\r
+/**\r
+ * ExpressionClassBuilder\r
+ * provides an interface to satisfy generation's\r
+ * common tasks in building classes that involve expressions.\r
+ * This is the common superclass of ActivationClassBuilder and\r
+ * FilterClassBuilder. See the documentation on ActivationClassBuilder.\r
+ *\r
+ */\r
+abstract       class ExpressionClassBuilder implements ExpressionClassBuilderInterface\r
+{\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // CONSTANTS\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+       static final protected String currentDatetimeFieldName = "cdt";\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // STATE\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+       protected ClassBuilder cb;\r
+       protected GeneratedClass gc;\r
+       protected int nextExprNum;\r
+       protected int nextNonFastExpr;\r
+       protected int nextFieldNum;\r
+       protected MethodBuilder constructor;\r
+       CompilerContext myCompCtx;\r
+       MethodBuilder executeMethod; // to find it fast\r
+\r
+       protected LocalField cdtField;\r
+\r
+       //protected final JavaFactory javaFac;\r
+\r
+       private String currentRowScanResultSetName;\r
+\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // CONSTRUCTORS\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * By the time this is done, it has constructed the following class:\r
+        * <pre>\r
+        *    public class #className extends #superClass {\r
+        *              public #className() { super(); }\r
+        *    }\r
+        * </pre>\r
+        *\r
+        * @exception StandardException thrown on failure\r
+        */\r
+       ExpressionClassBuilder (String superClass, String className, CompilerContext cc ) \r
+               throws StandardException\r
+       {\r
+               int modifiers = Modifier.PUBLIC | Modifier.FINAL;\r
+\r
+               myCompCtx = cc;\r
+               JavaFactory javaFac = myCompCtx.getJavaFactory();\r
+\r
+               if ( className == null ) { className = myCompCtx.getUniqueClassName(); }\r
+\r
+               // start the class\r
+               cb = javaFac.newClassBuilder(myCompCtx.getClassFactory(),\r
+                       getPackageName(), modifiers,\r
+                       className, superClass);\r
+\r
+               beginConstructor();\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // ABSTRACT METHODS TO BE IMPLEMENTED BY CHILDREN\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Get the name of the package that the generated class will live in.\r
+        *\r
+        *      @return name of package that the generated class will live in.\r
+        */\r
+       abstract        String  getPackageName();\r
+\r
+       /**\r
+        * Get the number of ExecRows that must be allocated\r
+        *\r
+        *      @return number of ExecRows that must be allocated\r
+        *\r
+        *      @exception StandardException thrown on failure\r
+        */\r
+       abstract        int             getRowCount()\r
+                throws StandardException;\r
+\r
+       /**\r
+        * Sets the number of subqueries under this expression\r
+        *\r
+        *\r
+        *      @exception StandardException thrown on failure\r
+        */\r
+       abstract        void    setNumSubqueries()\r
+                throws StandardException;\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // ACCESSORS\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+               Return the base class of the activation's hierarchy\r
+               (the subclass of Object).\r
+\r
+               This class is expected to hold methods used by all\r
+               compilation code, such as datatype compilation code,\r
+               e.g. getDataValueFactory.\r
+        */\r
+       abstract String getBaseClassName();\r
+\r
+       MethodBuilder getConstructor() {\r
+               return constructor;\r
+       }\r
+\r
+       ClassBuilder getClassBuilder() {\r
+               return cb;\r
+       }\r
+\r
+       /**\r
+     * Get the execute method in order to add code to it.\r
+     * Added code will be executed for each execution\r
+     * of the activation. StatementNode completes the\r
+     * execute method so that code added by other nodes\r
+     * will be executed before the ResultSet is created\r
+     * using fillResultSet. \r
+        */\r
+       MethodBuilder getExecuteMethod() {\r
+               return executeMethod;\r
+       }\r
+\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // CONSTRUCTOR MANAGEMENT\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+       private final void      beginConstructor()\r
+       {\r
+               // create a constructor that just calls super.  \r
+               MethodBuilder realConstructor =\r
+                       cb.newConstructorBuilder(Modifier.PUBLIC);\r
+               realConstructor.callSuper();\r
+               realConstructor.methodReturn();\r
+               realConstructor.complete();\r
+\r
+               constructor = cb.newMethodBuilder(Modifier.PUBLIC, "void", "postConstructor");\r
+               constructor.addThrownException(ClassName.StandardException);\r
+       }\r
+\r
+       /**\r
+        * Finish the constructor by newing the array of Rows and putting a return \r
+        * at the end of it.\r
+        *\r
+        * @exception StandardException thrown on failure\r
+        */\r
+\r
+       void finishConstructor()\r
+                throws StandardException\r
+       {\r
+               int                             numResultSets;\r
+\r
+               /* Set the number of subqueries */\r
+               setNumSubqueries();\r
+\r
+               numResultSets = getRowCount();\r
+\r
+               /* Generate the new of ExecRow[numResultSets] when there are ResultSets\r
+                * which return Rows.\r
+                */\r
+               if (numResultSets >= 1)\r
+               {\r
+                       addNewArrayOfRows(numResultSets);\r
+               }\r
+\r
+               /* Generated code is:\r
+                *              return;\r
+                */\r
+               constructor.methodReturn();\r
+               constructor.complete();\r
+       }\r
+\r
+       /**\r
+        * Generate the assignment for row = new ExecRow[numResultSets]\r
+        *\r
+        * @param numResultSets The size of the array.\r
+        */\r
+       private void addNewArrayOfRows(int numResultSets)\r
+       {\r
+               /* Generated code is:\r
+                *              row = new ExecRow[numResultSets];\r
+                */\r
+\r
+               constructor.pushThis();\r
+               constructor.pushNewArray(ClassName.ExecRow, numResultSets);\r
+               constructor.putField(ClassName.BaseActivation, "row", ClassName.ExecRow + "[]");\r
+               constructor.endStatement();\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // ADD FIELDS TO GENERATED CLASS\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Add a field declaration to the generated class\r
+        * \r
+        * @param modifiers     The | of the modifier values such as public, static, etc.\r
+        * @param type          The type of the field in java language.\r
+        * @param name          The name of the field.\r
+        *\r
+        * @return None.\r
+        */\r
+       LocalField newFieldDeclaration(int modifiers, String type, String name)\r
+       {\r
+               return cb.addField(type, name, modifiers);\r
+       }\r
+\r
+       /**\r
+        * Add an arbitrarily named field to the generated class.\r
+        *\r
+        * This is used to generate fields where the caller doesn't care what\r
+        * the field is named.  It is especially useful for generating arbitrary\r
+        * numbers of fields, where the caller doesn't know in advance how many\r
+        * fields will be used.  For example, it is used for generating fields\r
+        * to hold intermediate values from expressions.\r
+        *\r
+        * @param modifiers     The | of the modifier values such as public, static, etc.\r
+        * @param type          The type of the field in java language.\r
+        *\r
+        * @return      The name of the new field\r
+        */\r
+\r
+       LocalField newFieldDeclaration(int modifiers, String type)\r
+       {\r
+               return cb.addField(type, newFieldName(), modifiers);\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // ADD FUNCTIONS TO GENERATED CLASS\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Activations might have need of internal functions\r
+        * that are not used by the result sets, but by other\r
+        * activation functions. Thus, we make it possible\r
+        * for functions to be generated directly as well\r
+        * as through the newExprFun interface.  newExprFun\r
+        * should be used when a static field pointing to the\r
+        * expression function is needed.\r
+        * <p>\r
+        * The generated function will generally have a generated name\r
+        * that can be viewed through the MethodBuilder interface.\r
+        * This name is generated to ensure uniqueness from other\r
+        * function names in the activation class. If you pass in a function\r
+        * name, think carefully about whether it will collide with other names.\r
+        *\r
+        * @param returnType the return type of the function\r
+        * @param modifiers the modifiers on the function\r
+        *\r
+        * @see #newExprFun\r
+        */\r
+       MethodBuilder newGeneratedFun(String returnType, int modifiers) {\r
+\r
+               return newGeneratedFun(returnType, modifiers,\r
+                                                          (String[]) null);\r
+       }\r
+\r
+       MethodBuilder newGeneratedFun(String returnType, \r
+                                                                                int modifiers,\r
+                                                                                String[] params) {\r
+\r
+               String exprName = "g".concat(Integer.toString(nextNonFastExpr++));\r
+               return newGeneratedFun(exprName, returnType, modifiers,\r
+                                                          params);\r
+\r
+       }\r
+\r
+       private MethodBuilder newGeneratedFun(String exprName, String returnType, \r
+                                                                                int modifiers,\r
+                                                                                String[] params) {\r
+\r
+\r
+\r
+               //\r
+               // create a new method supplying the given modifiers and return Type\r
+               // Java: #modifiers #returnType #exprName { }\r
+               //\r
+               MethodBuilder exprMethod;\r
+               if (params == null)\r
+               {\r
+                       exprMethod = cb.newMethodBuilder(modifiers, returnType, exprName);\r
+               }\r
+               else\r
+               {\r
+                       exprMethod = cb.newMethodBuilder(modifiers, returnType, \r
+                                                                                    exprName, params);\r
+               }\r
+\r
+               //\r
+               // declare it to throw StandardException\r
+               // Java: #modifiers #returnType #exprName throws StandardException { }\r
+               //\r
+               exprMethod.addThrownException(ClassName.StandardException);\r
+\r
+               return exprMethod;\r
+       }\r
+\r
+       /**\r
+        * "ExprFun"s are the "expression functions" that\r
+        * are specific to a given JSQL statement. For example,\r
+        * an ExprFun is generated to evaluate the where clause\r
+        * of a select statement and return a boolean result.\r
+        * <p>\r
+        *\r
+        * All methods return by this are expected to be called\r
+        * via the GeneratedMethod interface. Thus the methods\r
+        * are public and return java.lang.Object.\r
+        * <p>\r
+        * Once the exprfun has been created, the\r
+        * caller will need to add statements to it,\r
+        * minimally a return statement.\r
+        * <p>\r
+        * ExprFuns  return Object types, since they\r
+        * are invoked through reflection and thus their\r
+        * return type would get wrapped in an object anyway.\r
+        * For example: return java.lang.Boolean, not boolean.\r
+        */\r
+       MethodBuilder newExprFun()\r
+       {\r
+               // get next generated function \r
+               String exprName = "e".concat(Integer.toString(nextExprNum++));\r
+\r
+               return newGeneratedFun(exprName, "java.lang.Object", Modifier.PUBLIC, (String[]) null);\r
+       }\r
+\r
+       /**\r
+               Push an expression that is a GeneratedMethod reference to the\r
+               passed in method. aka. a "function pointer".\r
+       */\r
+       void pushMethodReference(MethodBuilder mb, MethodBuilder exprMethod) {\r
+\r
+               mb.pushThis(); // instance\r
+               mb.push(exprMethod.getName()); // arg\r
+               mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.GeneratedByteCode,\r
+                               "getMethod",\r
+                               ClassName.GeneratedMethod,\r
+                               1\r
+                               );\r
+       }\r
+\r
+       /**\r
+        * Start a user expression.  The difference between a normal expression\r
+        * (returned by newExprFun)\r
+        * and a user expression is that a user expression catches all exceptions\r
+        * (because we don't want random exceptions thrown from user methods to\r
+        * propagate to the rest of the system.\r
+        *\r
+        * @return      A new MethodBuilder\r
+        */\r
+       MethodBuilder newUserExprFun() {\r
+\r
+               MethodBuilder mb = newExprFun();\r
+               mb.addThrownException("java.lang.Exception");\r
+               return mb;\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // CURRENT DATE/TIME SUPPORT\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+               This utility method returns an expression for CURRENT_DATE.\r
+               Get the expression this way, because the activation needs to \r
+               generate support information for CURRENT_DATE,\r
+               that would otherwise be painful to create manually.\r
+        */\r
+       void getCurrentDateExpression(MethodBuilder mb) {\r
+               // do any needed setup\r
+               LocalField lf = getCurrentSetup();\r
+\r
+               // generated Java:\r
+               //        this.cdt.getCurrentDate();\r
+               mb.getField(lf);\r
+               mb.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, "getCurrentDate", "java.sql.Date", 0);\r
+       }\r
+\r
+       /**\r
+               This utility method returns an expression for CURRENT_TIME.\r
+               Get the expression this way, because the activation needs to \r
+               generate support information for CURRENT_TIME,\r
+               that would otherwise be painful to create manually.\r
+        */\r
+       void getCurrentTimeExpression(MethodBuilder mb) {\r
+               // do any needed setup\r
+               LocalField lf = getCurrentSetup();\r
+\r
+               // generated Java:\r
+               //        this.cdt.getCurrentTime();\r
+               mb.getField(lf);\r
+               mb.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, "getCurrentTime", "java.sql.Time", 0);\r
+       }\r
+\r
+       /**\r
+               This utility method generates an expression for CURRENT_TIMESTAMP.\r
+               Get the expression this way, because the activation needs to \r
+               generate support information for CURRENT_TIMESTAMP,\r
+               that would otherwise be painful to create manually.\r
+        */\r
+       void getCurrentTimestampExpression(MethodBuilder mb) {\r
+               // do any needed setup\r
+               LocalField lf = getCurrentSetup();\r
+\r
+               // generated Java:\r
+               //        this.cdt.getCurrentTimestamp();\r
+               mb.getField(lf);\r
+               mb.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null,\r
+                       "getCurrentTimestamp", "java.sql.Timestamp", 0);\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // COLUMN ORDERING\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+    /**\r
+               These utility methods buffers compilation from the IndexColumnOrder\r
+               class.\r
+\r
+               They create an ordering based on their parameter, stuff that into\r
+               the prepared statement, and then return the entry # for\r
+               use in the generated code.\r
+\r
+               We could write another utility method to generate code to\r
+               turn an entry # back into an object, but so far no-one needs it.\r
+       \r
+               WARNING: this is a crafty method that ASSUMES that \r
+               you want every column in the list ordered, and that every\r
+               column in the list is the entire actual result colunm.\r
+               It is only useful for DISTINCT in select.       \r
+        */\r
+       FormatableArrayHolder getColumnOrdering(ResultColumnList rclist)\r
+       {\r
+               IndexColumnOrder[] ordering;\r
+               int numCols = (rclist == null) ? 0 : rclist.size();\r
+               //skip the columns which are not exclusively part of the insert list\r
+    //ie columns with default and autoincrement. These columns will not\r
+    //be part of ordering.\r
+               int numRealCols = 0;\r
+               for (int i=0; i<numCols; i++)\r
+               {\r
+                       if (!(rclist.getResultColumn(i+1).isGeneratedForUnmatchedColumnInInsert()))\r
+                               numRealCols++;\r
+               }\r
+\r
+               ordering = new IndexColumnOrder[numRealCols];\r
+               for (int i=0, j=0; i<numCols; i++)\r
+               {\r
+                       if (!(rclist.getResultColumn(i+1).isGeneratedForUnmatchedColumnInInsert()))\r
+                       {\r
+                               ordering[j] = new IndexColumnOrder(i);\r
+                               j++;\r
+                       }\r
+               }\r
+               return new FormatableArrayHolder(ordering);\r
+       }\r
+\r
+       /**\r
+        * Add a column to the existing Ordering list.  Takes\r
+        * a column id and only adds it if it isn't in the list.\r
+        *\r
+        *\r
+        * @return the ColumnOrdering array\r
+        */\r
+       FormatableArrayHolder addColumnToOrdering(\r
+                                               FormatableArrayHolder orderingHolder,\r
+                                               int columnNum)\r
+       {\r
+               /*\r
+               ** We don't expect a lot of order by columns, so\r
+               ** linear search.\r
+               */\r
+               ColumnOrdering[] ordering = (ColumnOrdering[])orderingHolder.\r
+                                                                               getArray(ColumnOrdering.class);\r
+               int length = ordering.length;\r
+               for (int i = 0; i < length; i++)\r
+               {\r
+                       if (ordering[i].getColumnId() == columnNum)\r
+                               return orderingHolder;\r
+               }\r
+\r
+               /*\r
+               ** Didn't find it.  Allocate a bigger array\r
+               ** and add it to the end\r
+               */\r
+               IndexColumnOrder[] newOrdering = new IndexColumnOrder[length+1];\r
+               System.arraycopy(ordering, 0, newOrdering, 0, length);\r
+               newOrdering[length] = new IndexColumnOrder(columnNum);\r
+               \r
+               return new FormatableArrayHolder(newOrdering);\r
+       }       \r
+\r
+\r
+       FormatableArrayHolder getColumnOrdering(OrderedColumnList  oclist) {\r
+               int numCols = (oclist == null) ? 0 : oclist.size();\r
+\r
+               if (numCols == 0)\r
+               {\r
+                       return new FormatableArrayHolder(new IndexColumnOrder[0]);\r
+               }\r
+\r
+               return new FormatableArrayHolder(oclist.getColumnOrdering());\r
+       }\r
+\r
+       int addItem(Object o) \r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if ((o != null) && !(o instanceof Serializable))\r
+                       {\r
+                               SanityManager.THROWASSERT(\r
+                                       "o (" + o.getClass().getName() +\r
+                                       ") expected to be instanceof java.io.Serializable");\r
+                       }\r
+               }\r
+               return myCompCtx.addSavedObject(o);\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // Caching resuable Expressions\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Get/reuse the Expression for getting the DataValueFactory\r
+        */\r
+       private Object getDVF;\r
+       void pushDataValueFactory(MethodBuilder mb)\r
+       {\r
+               // generates:\r
+               //         getDataValueFactory()\r
+               //\r
+\r
+               if (getDVF == null) {\r
+                       getDVF = mb.describeMethod(VMOpcode.INVOKEVIRTUAL,\r
+                                                                               getBaseClassName(),\r
+                                                                               "getDataValueFactory",\r
+                                                                               ClassName.DataValueFactory);\r
+               }\r
+\r
+               mb.pushThis();\r
+               mb.callMethod(getDVF);\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // RESULT SET SUPPORT\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+               This is a utility method to get a common expression --\r
+               "BaseActivation.getResultSetFactory()".\r
+               <p>\r
+               BaseActivation gets the factory from the context and\r
+               caches it for faster retrieval.\r
+        */\r
+       private Object getRSF;\r
+       void pushGetResultSetFactoryExpression(MethodBuilder mb) {\r
+               // generated Java:\r
+               //      this.getResultSetFactory()\r
+               //\r
+               if (getRSF == null) {\r
+                       getRSF = mb.describeMethod(VMOpcode.INVOKEVIRTUAL, getBaseClassName(),\r
+                                       "getResultSetFactory",\r
+                                       ClassName.ResultSetFactory);\r
+               }\r
+               mb.pushThis();\r
+               mb.callMethod(getRSF);\r
+       }\r
+\r
+       /**\r
+               This is a utility method to get a common expression --\r
+               "BaseActivation.getExecutionFactory()".\r
+               REVISIT: could the same expression objects be reused within\r
+               the tree and have the correct java generated each time?\r
+               <p>\r
+               BaseActivation gets the factory from the context and\r
+               caches it for faster retrieval. \r
+        */\r
+       private Object getEF;\r
+       void pushGetExecutionFactoryExpression(MethodBuilder mb) {\r
+               if (getEF == null) {\r
+                       getEF = mb.describeMethod(VMOpcode.INVOKEVIRTUAL, getBaseClassName(),\r
+                                       "getExecutionFactory",\r
+                                       ClassName.ExecutionFactory);\r
+               }\r
+\r
+               // generated Java:\r
+               //      this.getExecutionFactory()\r
+               //\r
+               mb.pushThis();\r
+               mb.callMethod(getEF);\r
+       }\r
+\r
+       /**\r
+        * Generate a reference to the row array that\r
+        * all activations use.\r
+        * \r
+        * @param eb the expression block\r
+        *\r
+        * @return expression\r
+        */\r
+       //private void pushRowArrayReference(MethodBuilder mb)\r
+       //{             \r
+               // PUSHCOMPILE - cache\r
+       //      mb.pushThis();\r
+       //      mb.getField(ClassName.BaseActivation, "row", ClassName.ExecRow + "[]");\r
+       //}\r
+\r
+       /**\r
+        * Generate a reference to a colunm in a result set.\r
+        * \r
+        * @param rsNumber the result set number\r
+        * @param colId the column number\r
+        */\r
+       void pushColumnReference(MethodBuilder mb, int rsNumber, int colId)\r
+       {\r
+               mb.pushThis();\r
+               mb.push(rsNumber);\r
+               mb.push(colId);\r
+               mb.callMethod(VMOpcode.INVOKEVIRTUAL, ClassName.BaseActivation, "getColumnFromRow",\r
+                                               ClassName.DataValueDescriptor, 2);\r
+\r
+               //System.out.println("pushColumnReference ");\r
+               //pushRowArrayReference(mb);\r
+               //mb.getArrayElement(rsNumber); // instance for getColumn\r
+               //mb.push(colId); // first arg\r
+               //mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Row, "getColumn", ClassName.DataValueDescriptor, 1);\r
+       }\r
+\r
+       /**\r
+        * Generate a reference to the parameter value\r
+        * set that all activations use.\r
+        * \r
+        */\r
+       void pushPVSReference(MethodBuilder mb)\r
+       {\r
+               // PUSHCOMPILER-WASCACHED\r
+               mb.pushThis();\r
+               mb.getField(ClassName.BaseActivation, "pvs", ClassName.ParameterValueSet);\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // CLASS IMPLEMENTATION\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+       /*\r
+               The first time a current datetime is needed, create the class\r
+               level support for it.\r
+        */\r
+       protected LocalField getCurrentSetup() {\r
+               if (cdtField != null)\r
+                       return cdtField;\r
+\r
+               // generated Java:\r
+               // 1) the field "cdt" is created:\r
+               //    private CurrentDatetime cdt;\r
+               cdtField = newFieldDeclaration(\r
+                       Modifier.PRIVATE,\r
+                       ClassName.CurrentDatetime,\r
+                       currentDatetimeFieldName);\r
+\r
+               // 2) the constructor gets a statement to init CurrentDatetime:\r
+               //        cdt = new CurrentDatetime();\r
+\r
+               constructor.pushNewStart(ClassName.CurrentDatetime);\r
+               constructor.pushNewComplete(0);\r
+               constructor.setField(cdtField);\r
+\r
+               return cdtField;\r
+       }\r
+\r
+       /**\r
+        * generated the next field name available.\r
+        * these are of the form 'e#', where # is\r
+        * incremented each time.\r
+        * This shares the name space with the expression methods\r
+        * as Java allows names and fields to have the same name.\r
+        * This reduces the number of constant pool entries created\r
+        * for a generated class file.\r
+        */\r
+       private String newFieldName()\r
+       {\r
+               return "e".concat(Integer.toString(nextFieldNum++));\r
+       }\r
+\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // DEBUG\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // DATATYPES\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+       /**\r
+        * Get the TypeCompiler associated with the given TypeId\r
+        *\r
+        * @param typeId        The TypeId to get a TypeCompiler for\r
+        *\r
+        * @return      The corresponding TypeCompiler\r
+        *\r
+        */\r
+       protected TypeCompiler getTypeCompiler(TypeId typeId)\r
+       {\r
+               return myCompCtx.getTypeCompilerFactory().getTypeCompiler(typeId);\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       //\r
+       // GENERATE BYTE CODE\r
+       //\r
+       ///////////////////////////////////////////////////////////////////////\r
+\r
+       /**\r
+        * Take the generated class, and turn it into an\r
+        * actual class.\r
+        * <p> This method assumes, does not check, that\r
+        * the class and its parts are all complete.\r
+        *\r
+        * @param savedBytes place to save generated bytes.\r
+        *      if null, it is ignored\r
+        * @exception StandardException thrown when exception occurs\r
+        */\r
+       GeneratedClass getGeneratedClass(ByteArray savedBytes) throws StandardException {\r
+               if (gc != null) return gc;\r
+\r
+               if (savedBytes != null)\r
+               {\r
+                       ByteArray classBytecode = cb.getClassBytecode();\r
+\r
+                       // note: be sure to set the length since\r
+                       // the class builder allocates the byte array\r
+                       // in big chunks\r
+                       savedBytes.setBytes(classBytecode.getArray());\r
+                       savedBytes.setLength(classBytecode.getLength());\r
+               }\r
+\r
+           gc =  cb.getGeneratedClass();\r
+\r
+               return gc; // !! yippee !! here it is...\r
+       }\r
+\r
+       /**\r
+        * Get a "this" expression declared as an Activation.\r
+        * This is the commonly used type of the this expression.\r
+        *\r
+        */\r
+       void pushThisAsActivation(MethodBuilder mb) {\r
+               // PUSHCOMPILER - WASCACHED\r
+               mb.pushThis();\r
+               mb.upCast(ClassName.Activation);\r
+       }\r
+\r
+       /**\r
+               Generate a Null data value.\r
+               Nothing is required on the stack, a SQL null data value\r
+               is pushed.\r
+       */\r
+       void generateNull(MethodBuilder mb, TypeCompiler tc, int collationType) {\r
+               pushDataValueFactory(mb);\r
+               mb.pushNull(tc.interfaceName());\r
+               tc.generateNull(mb, collationType);\r
+       }\r
+\r
+       /**\r
+               Generate a Null data value.\r
+               The express value is required on the stack and will be popped, a SQL null data value\r
+               is pushed.\r
+       */\r
+       void generateNullWithExpress(MethodBuilder mb, TypeCompiler tc, \r
+                       int collationType) {\r
+               pushDataValueFactory(mb);\r
+               mb.swap(); // need the dvf as the instance\r
+               mb.cast(tc.interfaceName());\r
+               tc.generateNull(mb, collationType);\r
+       }\r
+\r
+       /**\r
+               Generate a data value.\r
+               The value is to be set in the SQL data value is required\r
+               on the stack and will be popped, a SQL data value\r
+               is pushed.\r
+       */\r
+       void generateDataValue(MethodBuilder mb, TypeCompiler tc, \r
+                       int collationType, LocalField field) {\r
+               pushDataValueFactory(mb);\r
+               mb.swap(); // need the dvf as the instance\r
+               tc.generateDataValue(mb, collationType, field);\r
+       }\r
+\r
+       \r
+       /**\r
+        *generates a variable name for the rowscanresultset.\r
+        *This can not be a fixed name because in cases like\r
+        *cascade delete same activation class will be dealing \r
+        * more than one RowScanResultSets for dependent tables.\r
+       */\r
+\r
+       String newRowLocationScanResultSetName()\r
+       {\r
+               currentRowScanResultSetName = newFieldName();\r
+               return currentRowScanResultSetName;\r
+       }\r
+\r
+       // return the Name of ResultSet with the RowLocations to be modified (deleted or updated).\r
+       String getRowLocationScanResultSetName()\r
+       {\r
+               return currentRowScanResultSetName;\r
+       }\r
+\r
+       \r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r