Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / impl / sql / compile / ResultColumnList.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java
new file mode 100644 (file)
index 0000000..4961541
--- /dev/null
@@ -0,0 +1,4120 @@
+/*\r
+   Derby - Class org.apache.derby.impl.sql.compile.ResultColumnList\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 java.lang.reflect.Modifier;\r
+import java.sql.ResultSetMetaData;\r
+import java.sql.Types;\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+\r
+import org.apache.derby.catalog.types.DefaultInfoImpl;\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.reference.ClassName;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.services.classfile.VMOpcode;\r
+import org.apache.derby.iapi.services.compiler.LocalField;\r
+import org.apache.derby.iapi.services.compiler.MethodBuilder;\r
+import org.apache.derby.iapi.services.context.ContextManager;\r
+import org.apache.derby.iapi.services.io.FormatableBitSet;\r
+import org.apache.derby.iapi.services.loader.ClassFactory;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.sql.ResultColumnDescriptor;\r
+import org.apache.derby.iapi.sql.compile.C_NodeTypes;\r
+import org.apache.derby.iapi.sql.compile.NodeFactory;\r
+import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList;\r
+import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.sql.dictionary.DefaultDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+import org.apache.derby.iapi.sql.execute.ExecRow;\r
+import org.apache.derby.iapi.store.access.ConglomerateController;\r
+import org.apache.derby.iapi.store.access.StoreCostController;\r
+import org.apache.derby.iapi.store.access.TransactionController;\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+import org.apache.derby.iapi.types.RowLocation;\r
+import org.apache.derby.iapi.types.TypeId;\r
+import org.apache.derby.iapi.util.JBitSet;\r
+import org.apache.derby.iapi.util.ReuseFactory;\r
+\r
+/**\r
+ * A ResultColumnList is the target list of a SELECT, INSERT, or UPDATE.\r
+ *\r
+ * @see ResultColumn\r
+ */\r
+\r
+public class ResultColumnList extends QueryTreeNodeVector\r
+{\r
+       /* Is this the ResultColumnList for an index row? */\r
+       protected boolean indexRow;\r
+       protected long  conglomerateId;\r
+\r
+       int                     orderBySelect = 0; // the number of result columns pulled up\r
+                                          // from ORDERBY list\r
+    /*\r
+     * A comment on 'orderBySelect'. When we encounter a SELECT .. ORDER BY\r
+     * statement, the columns (or expressions) in the ORDER BY clause may\r
+     * or may not have been explicitly mentioned in the SELECT column list.\r
+     * If the columns were NOT explicitly mentioned in the SELECT column\r
+     * list, then the parsing of the ORDER BY clause implicitly generates\r
+     * them into the result column list, because we'll need to have those\r
+     * columns present at execution time in order to sort by them. Those\r
+     * generated columns are added to the *end* of the ResultColumnList, and\r
+     * we keep track of the *number* of those columns in 'orderBySelect',\r
+     * so we can tell whether we are looking at a generated column by seeing\r
+     * whether its position in the ResultColumnList is in the last\r
+     * 'orderBySelect' number of columns. If the SELECT .. ORDER BY\r
+     * statement uses the "*" token to select all the columns from a table,\r
+     * then during ORDER BY parsing we redundantly generate the columns\r
+     * mentioned in the ORDER BY clause into the ResultColumnlist, but then\r
+     * later in getOrderByColumnToBind we determine that these are\r
+     * duplicates and we take them back out again.\r
+     */\r
+\r
+       /*\r
+       ** Is this ResultColumnList for a FromBaseTable for an index\r
+       ** that is to be updated?\r
+       */\r
+       protected boolean forUpdate;\r
+\r
+       // Is a count mismatch allowed - see set/get methods for details.\r
+       private boolean countMismatchAllowed;\r
+\r
+       // Number of RCs in this RCL at "init" time, before additional\r
+       // ones were added internally.\r
+       private int initialListSize = 0;\r
+\r
+       public ResultColumnList()\r
+       {\r
+       }\r
+\r
+       /**\r
+        * Add a ResultColumn (at this point, ResultColumn or\r
+        * AllResultColumn) to the list\r
+        *\r
+        * @param resultColumn  The ResultColumn to add to the list\r
+        */\r
+\r
+       public void addResultColumn(ResultColumn resultColumn)\r
+       {\r
+               /* Vectors are 0-based, ResultColumns are 1-based */\r
+               resultColumn.setVirtualColumnId(size() + 1);\r
+               addElement(resultColumn);\r
+       }\r
+\r
+       /**\r
+        * Append a given ResultColumnList to this one, resetting the virtual\r
+        * column ids in the appended portion.\r
+        *\r
+        * @param resultColumns         The ResultColumnList to be appended\r
+        * @param destructiveCopy       Whether or not this is a descructive copy\r
+        *                                                      from resultColumns\r
+        */\r
+       public void appendResultColumns(ResultColumnList resultColumns,\r
+                                                                       boolean destructiveCopy)\r
+       {\r
+               int     oldSize = size();\r
+               int     newID = oldSize + 1;\r
+\r
+               /*\r
+               ** Set the virtual column ids in the list being appended.\r
+               ** Vectors are zero-based, and virtual column ids are one-based,\r
+               ** so the new virtual column ids start at the original size\r
+               ** of this list, plus one.\r
+               */\r
+               int otherSize = resultColumns.size();\r
+               for (int index = 0; index < otherSize; index++)\r
+               {\r
+                       /* ResultColumns are 1-based */\r
+                       ((ResultColumn) resultColumns.elementAt(index)).setVirtualColumnId(newID);\r
+                       newID++;\r
+               }\r
+\r
+               if (destructiveCopy)\r
+               {\r
+                       destructiveAppend(resultColumns);\r
+               }\r
+               else\r
+               {\r
+                       nondestructiveAppend(resultColumns);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Get a ResultColumn from a column position (1-based) in the list\r
+        *\r
+        * @param position      The ResultColumn to get from the list (1-based)\r
+        *\r
+        * @return      the column at that position.\r
+        */\r
+\r
+       public ResultColumn getResultColumn(int position)\r
+       {\r
+               /*\r
+               ** First see if it falls in position x.  If not,\r
+               ** search the whole shebang\r
+               */\r
+               if (position <= size()) \r
+               {\r
+                       // this wraps the cast needed, \r
+                       // and the 0-based nature of the Vectors.\r
+                       ResultColumn rc = (ResultColumn)elementAt(position-1);\r
+                       if (rc.getColumnPosition() == position)\r
+                       {\r
+                               return rc;\r
+                       }\r
+               }\r
+               \r
+               /*\r
+               ** Check each column\r
+               */\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+                       if (rc.getColumnPosition() == position)\r
+                       {\r
+                               return rc;\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Take a column position and a ResultSetNode and find the ResultColumn\r
+        * in this RCL whose source result set is the same as the received\r
+        * RSN and whose column position is the same as the received column\r
+        * position.\r
+        *\r
+        * @param colNum The column position (w.r.t rsn) for which we're searching\r
+        * @param rsn The result set node for which we're searching.\r
+        * @return The ResultColumn in this RCL whose source is column colNum\r
+        *  in result set rsn.  That ResultColumn's position w.r.t to this RCL\r
+        *  is also returned via the whichRC parameter.  If no match is found,\r
+        *  return null and leave whichRC untouched.\r
+        */\r
+       public ResultColumn getResultColumn(int colNum, ResultSetNode rsn,\r
+               int [] whichRC) throws StandardException\r
+       {\r
+               if (colNum == -1)\r
+                       return null;\r
+\r
+               ResultColumn rc = null;\r
+               ColumnReference colRef = null;\r
+               int [] crColNum = new int[] { -1 };\r
+\r
+               for (int index = size() - 1; index >= 0; index--)\r
+               {\r
+                       rc = (ResultColumn) elementAt(index);\r
+                       if (!(rc.getExpression() instanceof ColumnReference))\r
+                       {\r
+                               // If the rc's expression isn't a column reference then\r
+                               // it can't be pointing to rsn, so just skip it.\r
+                               continue;\r
+                       }\r
+\r
+                       colRef = (ColumnReference)rc.getExpression();\r
+                       if ((rsn == colRef.getSourceResultSet(crColNum)) &&\r
+                               (crColNum[0] == colNum))\r
+                       {\r
+                               // Found a match.\r
+                               whichRC[0] = index+1;\r
+                               return rc;\r
+                       }\r
+               }\r
+\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Get a ResultColumn from a column position (1-based) in the list,\r
+        * null if out of range (for order by).\r
+        *\r
+        * @param position      The ResultColumn to get from the list (1-based)\r
+        *\r
+        * @return      the column at that position, null if out of range\r
+        */\r
+       public ResultColumn getOrderByColumn(int position)\r
+       {\r
+               // this wraps the cast needed, and the 0-based nature of the Vectors.\r
+               if (position == 0) \r
+                       return null;\r
+\r
+               return getResultColumn(position);\r
+       }\r
+\r
+       /**\r
+        * Get a ResultColumn that matches the specified columnName and\r
+        * mark the ResultColumn as being referenced.\r
+        *\r
+        * @param columnName    The ResultColumn to get from the list\r
+        *\r
+        * @return      the column that matches that name.\r
+        */\r
+\r
+       public ResultColumn getResultColumn(String columnName)\r
+       {\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+                       if (columnName.equals( resultColumn.getName()) )\r
+                       {\r
+                               /* Mark ResultColumn as referenced and return it */\r
+                               resultColumn.setReferenced();\r
+                               return resultColumn;\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Get a ResultColumn that matches the specified columnName and\r
+        * mark the ResultColumn as being referenced.\r
+        *\r
+        * @param columnsTableName      Qualifying name for the column\r
+        * @param columnName            The ResultColumn to get from the list\r
+        *\r
+        * @return      the column that matches that name.\r
+        */\r
+\r
+       public ResultColumn getResultColumn(String columnsTableName, String columnName)\r
+       {\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+\r
+                       /* If the column's table name is non-null, then we have found a match\r
+                        * only if the RC's table name is non-null and the same as the\r
+                        * the CR's table name.\r
+                        */\r
+                       if (columnsTableName != null)\r
+                       {\r
+                               if (resultColumn.getTableName() == null)\r
+                               {\r
+                                       continue;\r
+                               }\r
+                               \r
+                               if (! columnsTableName.equals(resultColumn.getTableName()))\r
+                               {\r
+                                       continue;\r
+                               }\r
+                       }\r
+                       if (columnName.equals( resultColumn.getName()) )\r
+                       {\r
+                               /* Mark ResultColumn as referenced and return it */\r
+                               resultColumn.setReferenced();\r
+                               return resultColumn;\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Get a ResultColumn that matches the specified columnName and\r
+        * mark the ResultColumn as being referenced.\r
+        * NOTE - this flavor enforces no ambiguity (at most 1 match)\r
+        *                Only FromSubquery needs to call this flavor since\r
+        *                it can have ambiguous references in its own list.\r
+        *\r
+        * @param cr                                       The ColumnReference to resolve\r
+        * @param exposedTableName                 Exposed table name for FromTable\r
+        * @param considerGeneratedColumns Also consider columns that are generated.\r
+        *   One example of this is group by where columns are added to the select list\r
+        *   if they are referenced in the group by but are not present in the select\r
+        *   list.\r
+        * @return      the column that matches that name.\r
+        *\r
+        * @exception StandardException Thrown on error\r
+        */\r
+\r
+       public ResultColumn getAtMostOneResultColumn(\r
+                                                               ColumnReference cr,\r
+                                                               String exposedTableName,\r
+                                                               boolean considerGeneratedColumns)\r
+               throws StandardException\r
+       {\r
+               int                             size = size();\r
+               ResultColumn    retRC = null;\r
+               String                  columnName = cr.getColumnName();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+\r
+                       if (columnName.equals( resultColumn.getName()))\r
+                       {\r
+                               if (resultColumn.isGenerated() && !considerGeneratedColumns) {\r
+                                       continue;\r
+                               }\r
+                               /* We should get at most 1 match */\r
+                               if (retRC != null)\r
+                               {\r
+                                       throw StandardException.newException(SQLState.LANG_AMBIGUOUS_COLUMN_NAME_IN_TABLE, \r
+                                                        columnName, exposedTableName);\r
+                               }\r
+                               /* Mark ResultColumn as referenced and return it */\r
+                               resultColumn.setReferenced();\r
+                               retRC = resultColumn;\r
+                       }\r
+               }\r
+               return retRC;\r
+       }\r
+\r
+       /**\r
+        * For order by column bind, get a ResultColumn that matches the specified \r
+        * columnName.\r
+        *\r
+        * This method is called during bind processing, in the special\r
+        * "bind the order by" call that is made by CursorNode.bindStatement().\r
+        * The OrderByList has a special set of bind processing routines\r
+        * that analyzes the columns in the ORDER BY list and verifies that\r
+        * each column is one of:\r
+        * - a direct reference to a column explicitly mentioned in\r
+        *   the SELECT list\r
+        * - a direct reference to a column implicitly mentioned as "SELECT *"\r
+        * - a direct reference to a column "pulled up" into the result\r
+        *   column list\r
+        * - or a valid and fully-bound expression ("c+2", "YEAR(hire_date)", etc.)\r
+        *\r
+        * At this point in the processing, it is possible that we'll find\r
+        * the column present in the RCL twice: once because it was pulled\r
+        * up during statement compilation, and once because it was added\r
+        * when "SELECT *" was expanded into the table's actual column list.\r
+        * If we find such a duplicated column, we can, and do, remove the\r
+        * pulled-up copy of the column and point the OrderByColumn\r
+        * to the actual ResultColumn from the *-expansion.\r
+        *\r
+        * Note that the association of the OrderByColumn with the\r
+        * corresponding ResultColumn in the RCL occurs in\r
+        * OrderByColumn.resolveAddedColumn.\r
+        *\r
+        * @param columnName    The ResultColumn to get from the list\r
+        * @param tableName     The table name on the OrderByColumn, if any\r
+        * @param tableNumber   The tableNumber corresponding to the FromTable with the\r
+        *                                              exposed name of tableName, if tableName != null.\r
+        * @param obc           The OrderByColumn we're binding.\r
+        *\r
+        * @return      the column that matches that name.\r
+        * @exception StandardException thrown on ambiguity\r
+        */\r
+       public ResultColumn getOrderByColumnToBind(\r
+            String columnName,\r
+            TableName tableName,\r
+            int tableNumber,\r
+            OrderByColumn obc)\r
+               throws StandardException\r
+       {\r
+               int                             size = size();\r
+               ResultColumn    retVal = null, resultColumn;\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       resultColumn = (ResultColumn) elementAt(index);\r
+\r
+                       /* The order by column is qualified, then it is okay to consider\r
+                        * this RC if:\r
+                        *      o  The RC is qualified and the qualifiers on the order by column\r
+                        *         and the RC are equal().\r
+                        *      o  The RC is not qualified, but its expression is a ColumnReference\r
+                        *         from the same table (as determined by the tableNumbers).\r
+                        */\r
+                        boolean columnNameMatches;\r
+                       if (tableName != null)\r
+                       {\r
+                ValueNode rcExpr = resultColumn.getExpression();\r
+                if (! (rcExpr instanceof ColumnReference))\r
+                                               continue;\r
+\r
+                ColumnReference cr = (ColumnReference) rcExpr;\r
+                if( (! tableName.equals( cr.getTableNameNode())) && tableNumber != cr.getTableNumber())\r
+                    continue;\r
+                               columnNameMatches =\r
+                                       columnName.equals( resultColumn.getSourceColumnName() );\r
+                       }\r
+                       else\r
+                               columnNameMatches =\r
+                                       resultColumn.columnNameMatches(columnName);\r
+\r
+\r
+                       /* We finally got past the qualifiers, now see if the column\r
+                        * names are equal. If they are, then we appear to have found\r
+                       * our order by column. If we find our order by column multiple\r
+                       * times, make sure that they are truly duplicates, otherwise\r
+                       * we have an ambiguous situation. For example, the query\r
+                       *   SELECT b+c AS a, d+e AS a FROM t ORDER BY a\r
+                       * is ambiguous because we don't know which "a" is meant. But\r
+                       *   SELECT t.a, t.* FROM t ORDER BY a\r
+                       * is not ambiguous, even though column "a" is selected twice.\r
+                       * If we find our ORDER BY column at the end of the\r
+                       * SELECT column list, in the last 'orderBySelect' number\r
+                       * of columns, then this column was not explicitly mentioned\r
+                       * by the user in their SELECT column list, but was implicitly \r
+                       * added by the parsing of the ORDER BY clause, and it\r
+                       * should be removed from the ResultColumnList and returned\r
+                       * to the caller.\r
+                        */\r
+                       if (columnNameMatches)\r
+                       {\r
+                               if (retVal == null)\r
+                               {\r
+                                       retVal = resultColumn;\r
+                               }\r
+                               else if (! retVal.isEquivalent(resultColumn))\r
+                               {\r
+                                       throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_FOR_ORDER_BY, columnName);\r
+                               }\r
+                               else if (index >= size - orderBySelect)\r
+                               {// remove the column due to pullup of orderby item\r
+                                       removeElement(resultColumn);\r
+                                       decOrderBySelect();\r
+                                       obc.clearAddedColumnOffset();\r
+                                       collapseVirtualColumnIdGap(\r
+                                                       resultColumn.getColumnPosition());\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+               return retVal;\r
+       }\r
+\r
+       /**\r
+        * Adjust virtualColumnId values due to result column removal\r
+        *\r
+        * This method is called when a duplicate column has been detected and\r
+        * removed from the list. We iterate through each of the other columns\r
+        * in the list and notify them of the column removal so they can adjust\r
+        * their virtual column id if necessary.\r
+        *\r
+        * @param gap   id of the column which was just removed.\r
+        */\r
+       private void collapseVirtualColumnIdGap(int gap)\r
+       {\r
+               for (int index = 0; index < size(); index++)\r
+                       ((ResultColumn) elementAt(index)).collapseVirtualColumnIdGap(gap);\r
+       }\r
+\r
+\r
+       /**\r
+        * For order by, get a ResultColumn that matches the specified \r
+        * columnName.\r
+        *\r
+        * This method is called during pull-up processing, at the very\r
+        * start of bind processing, as part of\r
+        * OrderByList.pullUpOrderByColumns. Its job is to figure out\r
+        * whether the provided column (from the ORDER BY list) already\r
+        * exists in the ResultColumnList or not. If the column does\r
+        * not exist in the RCL, we return NULL, which signifies that\r
+        * a new ResultColumn should be generated and added ("pulled up")\r
+        * to the RCL by our caller.\r
+        *\r
+        * Note that at this point in the processing, we should never\r
+        * find this column present in the RCL multiple times; if the\r
+        * column is already present in the RCL, then we don't need to,\r
+        * and won't, pull a new ResultColumn up into the RCL.\r
+        *\r
+        * If the caller specified "SELECT *", then the RCL at this\r
+        * point contains a special AllResultColumn object. This object\r
+        * will later be expanded and replaced by the actual set of\r
+        * columns in the table, but at this point we don't know what\r
+        * those columns are, so we may pull up an OrderByColumn\r
+        * which duplicates a column in the *-expansion; such\r
+        * duplicates will be removed at the end of bind processing\r
+        * by OrderByList.bindOrderByColumns.\r
+        *\r
+        * @param columnName    The ResultColumn to get from the list\r
+        * @param tableName     The table name on the OrderByColumn, if any\r
+        *\r
+        * @return      the column that matches that name, or NULL if pull-up needed\r
+        * @exception StandardException thrown on ambiguity\r
+        */\r
+       public ResultColumn findResultColumnForOrderBy(\r
+                            String columnName, TableName tableName)\r
+               throws StandardException\r
+       {\r
+               int                             size = size();\r
+               ResultColumn    retVal = null, resultColumn;\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       resultColumn = (ResultColumn) elementAt(index);\r
+\r
+                       // We may be checking on "ORDER BY T.A" against "SELECT *".\r
+                       // exposedName will not be null and "*" will not have an expression\r
+                       // or tablename.\r
+                       // We may be checking on "ORDER BY T.A" against "SELECT T.B, T.A".\r
+                        boolean columnNameMatches;\r
+                       if (tableName != null)\r
+                       {\r
+                               ValueNode rcExpr = resultColumn.getExpression();\r
+                               if (rcExpr == null || ! (rcExpr instanceof ColumnReference))\r
+                {\r
+                    continue;\r
+                }\r
+                               ColumnReference cr = (ColumnReference) rcExpr;\r
+                if( ! tableName.equals( cr.getTableNameNode()))\r
+                    continue;\r
+                               columnNameMatches =\r
+                                       columnName.equals( resultColumn.getSourceColumnName() );\r
+                       }\r
+                       else\r
+                               columnNameMatches =\r
+                                       resultColumn.columnNameMatches(columnName);\r
+\r
+                       /* We finally got past the qualifiers, now see if the column\r
+                        * names are equal.\r
+                        */\r
+                       if (columnNameMatches)\r
+                       {\r
+                               if (retVal == null)\r
+                               {\r
+                                       retVal = resultColumn;\r
+                               }\r
+                               else if (! retVal.isEquivalent(resultColumn))\r
+                               {\r
+                                       throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_FOR_ORDER_BY, columnName);\r
+                               }\r
+                               else if (index >= size - orderBySelect)\r
+                               {\r
+                                       if (SanityManager.DEBUG)\r
+                                               SanityManager.THROWASSERT(\r
+                                                       "Unexpectedly found ORDER BY column '" +\r
+                                                       columnName + "' pulled up at position " +index);\r
+                               }\r
+                       }\r
+               }\r
+               return retVal;\r
+       }\r
+\r
+\r
+       /**\r
+        * Copy the result column names from the given ResultColumnList\r
+        * to this ResultColumnList.  This is useful for insert-select,\r
+        * where the columns being inserted into may be different from\r
+        * the columns being selected from.  The result column list for\r
+        * an insert is supposed to have the column names being inserted\r
+        * into.\r
+        *\r
+        * @param nameList      The ResultColumnList from which to copy\r
+        *                      the column names\r
+        */\r
+\r
+       void copyResultColumnNames(ResultColumnList nameList)\r
+       {\r
+               /* List checking is done during bind().  Lists should be the\r
+                * same size when we are called.\r
+                */\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                        if ((! countMismatchAllowed) && size() != nameList.size())\r
+                        {\r
+                               SanityManager.THROWASSERT(\r
+                                       "The size of the 2 lists is expected to be the same. size() = " +\r
+                                       size() + ", nameList.size() = " + nameList.size());\r
+                        }\r
+                }\r
+\r
+               int size = (countMismatchAllowed) ? nameList.size() : size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn thisResultColumn = (ResultColumn) elementAt(index);\r
+                       ResultColumn nameListResultColumn =\r
+                               (ResultColumn) nameList.elementAt(index);\r
+                       thisResultColumn.setName(nameListResultColumn.getName());\r
+                       thisResultColumn.setNameGenerated(nameListResultColumn.isNameGenerated());\r
+               }\r
+       }\r
+\r
+       /**\r
+        * This class needs a treePrint method, even though it is not a\r
+        * descendant of QueryTreeNode, because its members contain tree\r
+        * nodes, and these have to be printed and indented properly.\r
+        *\r
+        * @param depth         The depth at which to indent the sub-nodes\r
+        */\r
+\r
+       public void treePrint(int depth)\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       for (int index = 0; index < size(); index++)\r
+                       {\r
+                               ((ResultColumn) elementAt(index) ).treePrint(depth);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Bind the expressions in this ResultColumnList.  This means binding\r
+        * the expression under each ResultColumn node.\r
+        *\r
+        * @param fromList              The FROM list for the query this\r
+        *                              expression is in, for binding columns.\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
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void bindExpressions(\r
+                                       FromList fromList, SubqueryList subqueryList,\r
+                                       Vector  aggregateVector)\r
+                               throws StandardException\r
+       {\r
+               /* First we expand the *'s in the result column list */\r
+               expandAllsAndNameColumns(fromList);\r
+\r
+               /* Now we bind each result column */\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ValueNode vn = (ValueNode) elementAt(index);\r
+                       vn = ((ResultColumn) vn ).bindExpression(\r
+                                                                                               fromList, subqueryList, \r
+                                                                                               aggregateVector);\r
+                       setElementAt(vn, index);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Bind the result columns to the expressions that live under them.\r
+        * All this does is copy the datatype information to from each expression\r
+        * to each result column.  This is useful for SELECT statements, where\r
+        * the result type of each column is the type of the column's expression.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void bindResultColumnsToExpressions()\r
+                                       throws StandardException\r
+       {\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ((ResultColumn) elementAt(index) ).bindResultColumnToExpression();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Bind the result columns by their names.  This is useful for GRANT and REVOKE statements\r
+     * like "GRANT SELECT ON t(c1,c1,c3) TO george", where the user specified a column list.\r
+        * This method does not check for duplicate column names.\r
+        *\r
+        * @param targetTableDescriptor The descriptor for the table\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void bindResultColumnsByName(TableDescriptor targetTableDescriptor)\r
+                                       throws StandardException\r
+       {\r
+               int                     size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+\r
+                       rc.bindResultColumnByName(\r
+                                               targetTableDescriptor,\r
+                                               index + 1\r
+                                       );\r
+               }\r
+       } // end of bindResultColumnsByName( TableDescriptor)\r
+\r
+       /**\r
+        * Bind the result columns by their names.  This is useful for update, grant, and revoke\r
+        * statements, and for INSERT statements like "insert into t (a, b, c)\r
+        * values (1, 2, 3)" where the user specified a column list.\r
+        * If the statment is an insert or update verify that the result column list does not contain any duplicates.\r
+        * NOTE: We pass the ResultColumns position in the ResultColumnList so\r
+        * that the VirtualColumnId gets set.\r
+        *\r
+        * @param targetTableDescriptor The descriptor for the table being\r
+        *                              updated or inserted into\r
+        * @param statement                     DMLStatementNode containing this list, null if no duplicate checking is to be done\r
+        *\r
+        * @return A FormatableBitSet representing the set of columns with respect to the table\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public FormatableBitSet bindResultColumnsByName(TableDescriptor targetTableDescriptor,\r
+                                                    DMLStatementNode statement)\r
+                                       throws StandardException\r
+       {\r
+               int                     size = size();\r
+               FormatableBitSet columnBitSet = new FormatableBitSet( targetTableDescriptor.getNumberOfColumns());\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+\r
+                       rc.bindResultColumnByName(\r
+                                               targetTableDescriptor,\r
+                                               index + 1\r
+                                       );\r
+            int colIdx = rc.getColumnPosition() - 1;\r
+            if( SanityManager.DEBUG)\r
+                SanityManager.ASSERT( colIdx >= 0 && colIdx < targetTableDescriptor.getNumberOfColumns(),\r
+                                      "Invalid column position found for " + rc.getName());\r
+                       /* Verify that this column's name is unique within the list if requested */\r
+            if( statement != null && columnBitSet.isSet( colIdx))\r
+            {\r
+                String colName = rc.getName();\r
+\r
+                               if (statement instanceof UpdateNode)\r
+                               {\r
+                                       throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_UPDATE, colName);\r
+                               }\r
+                               else\r
+                               {\r
+                                       throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_INSERT, colName);\r
+                               }\r
+                       }\r
+            columnBitSet.set( colIdx);\r
+               }\r
+               return columnBitSet;\r
+       }\r
+\r
+       /**\r
+        * Bind the result columns by their names.  This is useful for update\r
+        * VTI statements, and for INSERT statements like "insert into new t() (a, b, c)\r
+        * values (1, 2, 3)" where the user specified a column list.\r
+        * Also, verify that the result column list does not contain any duplicates.\r
+        * NOTE: We pass the ResultColumns position in the ResultColumnList so\r
+        * that the VirtualColumnId gets set.\r
+        *\r
+        * @param fullRCL       The full RCL for the target table\r
+        * @param statement                     DMLStatementNode containing this list\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void bindResultColumnsByName(ResultColumnList fullRCL,\r
+                                                                               FromVTI targetVTI,\r
+                                                                               DMLStatementNode statement)\r
+                                       throws StandardException\r
+       {\r
+               int                     size = size();\r
+               Hashtable       ht = new Hashtable(size + 2, (float) .999);\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn matchRC;\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+\r
+                       /* Verify that this column's name is unique within the list */\r
+                       String colName = rc.getName();\r
+\r
+                       Object object = ht.put(colName, colName);\r
+\r
+                       if (object != null &&\r
+                               ((String) object).equals(colName))\r
+                       {\r
+                               if (SanityManager.DEBUG)\r
+                               {\r
+                                       SanityManager.ASSERT((statement instanceof UpdateNode) ||\r
+                                                                                (statement instanceof InsertNode),\r
+                                               "statement is expected to be instanceof UpdateNode or InsertNode");\r
+                               }\r
+                               if (statement instanceof UpdateNode)\r
+                               {\r
+                                       throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_UPDATE, colName);\r
+                               }\r
+                               else\r
+                               {\r
+                                       throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_INSERT, colName);\r
+                               }\r
+                       }\r
+\r
+                       matchRC = fullRCL.getResultColumn(null, rc.getName());\r
+                       if (matchRC == null)\r
+                       {\r
+                               throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, \r
+                                                                                                        rc.getName(), \r
+                                                                                                        targetVTI.getNewInvocation().getJavaClassName());\r
+                       }\r
+\r
+                       /* We have a match.  We need to create a dummy ColumnDescriptor\r
+                        * since calling code expects one to get column info.\r
+                        */\r
+                       ColumnDescriptor cd = new ColumnDescriptor(\r
+                                                                                       rc.getName(),\r
+                                                                                       matchRC.getVirtualColumnId(),\r
+                                                                                       matchRC.getType(),\r
+                                                                                       null,\r
+                                                                                       null,\r
+                                                                                       (TableDescriptor) null,\r
+                                                                                       null,\r
+                                                                                       0, 0);\r
+                       rc.setColumnDescriptor(null, cd);\r
+                       rc.setVirtualColumnId(index + 1);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Bind the result columns by ordinal position.  This is useful for\r
+        * INSERT statements like "insert into t values (1, 2, 3)", where the\r
+        * user did not specify a column list.\r
+        *\r
+        * @param targetTableDescriptor The descriptor for the table being\r
+        *                              inserted into\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void bindResultColumnsByPosition(TableDescriptor targetTableDescriptor)\r
+                                       throws StandardException\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       /*\r
+                       ** Add one to the iterator index, because iterator indexes start at zero,\r
+                       ** and column numbers start at one.\r
+                       */\r
+                       ((ResultColumn) elementAt(index) ).bindResultColumnByPosition(\r
+                                               targetTableDescriptor,\r
+                                               index + 1);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Preprocess the expression trees under the RCL.\r
+        * 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
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void preprocess(int numTables,\r
+                                                       FromList outerFromList,\r
+                                                       SubqueryList outerSubqueryList,\r
+                                                       PredicateList outerPredicateList) \r
+                                       throws StandardException\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+                       setElementAt(resultColumn.preprocess(numTables,\r
+                                                                                                outerFromList,\r
+                                                                                                outerSubqueryList,\r
+                                                                                                outerPredicateList),\r
+                                                index);\r
+               }\r
+       }\r
+\r
+       /**\r
+               Verify that all the result columns have expressions that\r
+               are storable for them.  Check versus the given ResultColumnList.\r
+\r
+               @exception StandardException    Thrown on error\r
+        */\r
+       void checkStorableExpressions(ResultColumnList toStore)\r
+                       throws StandardException\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn    otherRC = (ResultColumn) toStore.elementAt(index);\r
+\r
+                       ((ResultColumn) elementAt(index) ).checkStorableExpression(otherRC);\r
+               }\r
+       }\r
+\r
+       /**\r
+         Return an array holding the 0 based heap offsets of \r
+         the StreamStorable columns in this ResultColumnList.\r
+         This returns null if this list does not contain any\r
+         StreamStorableColumns. The list this returns does not\r
+         contain duplicates. This should only be used for\r
+         a resultColumnList the refers to a single heap\r
+         such as the target for an Insert, Update or Delete.\r
+         @param heapColCount the number of heap columns\r
+         @exception StandardException  Thrown on error\r
+        */\r
+       public int[] getStreamStorableColIds(int heapColCount) throws StandardException\r
+       {\r
+               //@#$\r
+               //System.out.println("getStreamStorableColids");\r
+\r
+               int ssCount = 0;\r
+               boolean[] isSS = new boolean[heapColCount];//Should be table length.\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+\r
+                       if (rc.getTypeId().streamStorable())\r
+                       {\r
+                               //System.out.println("    streamStorable=true");\r
+                               ColumnDescriptor cd = rc.getTableColumnDescriptor();\r
+                               isSS[cd.getPosition()-1] = true;\r
+                       }\r
+               }\r
+\r
+               for (int ix=0;ix<isSS.length;ix++) if (isSS[ix]) ssCount++;\r
+\r
+               if (ssCount==0)return null;\r
+\r
+               int[] result = new int[ssCount];\r
+               int resultOffset=0;\r
+               for (int heapOffset=0;heapOffset<isSS.length;heapOffset++)\r
+               {\r
+                       if (isSS[heapOffset])\r
+                               result[resultOffset++]=heapOffset;\r
+               }\r
+\r
+               return result;\r
+       }\r
+       \r
+       /**\r
+               Verify that all the result columns have expressions that\r
+               are storable for them.  Check versus the expressions under the\r
+               ResultColumns.\r
+\r
+               @exception StandardException    Thrown on error\r
+        */\r
+       void checkStorableExpressions()\r
+                       throws StandardException\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ((ResultColumn) elementAt(index) ).checkStorableExpression();\r
+               }\r
+       }\r
+\r
+\r
+       /**\r
+        * Generate the code to place the columns' values into\r
+        * a row variable named "r". This wrapper is here\r
+        * rather than in ResultColumn, because that class does\r
+        * not know about the position of the columns in the list.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void generate(ActivationClassBuilder acb, MethodBuilder mb)\r
+                       throws StandardException\r
+       {\r
+               generateCore(acb, mb, false);\r
+       }\r
+\r
+       /**\r
+        * Generate the code to place the columns' values into\r
+        * a row variable named "r". This wrapper is here\r
+        * rather than in ResultColumn, because that class does\r
+        * not know about the position of the columns in the list.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       void generateNulls(ActivationClassBuilder acb,\r
+                                                       MethodBuilder mb) \r
+                       throws StandardException\r
+       {\r
+               generateCore(acb, mb, true);\r
+       }\r
+\r
+       /**\r
+        * Generate the code to place the columns' values into\r
+        * a row variable named "r". This wrapper is here\r
+        * rather than in ResultColumn, because that class does\r
+        * not know about the position of the columns in the list.\r
+        *\r
+        * This is the method that does the work.\r
+        */\r
+       void generateCore(ExpressionClassBuilder acb,\r
+                                                       MethodBuilder mb,\r
+                                                       boolean genNulls) \r
+                       throws StandardException\r
+       {\r
+               // generate the function and initializer:\r
+               // private ExecRow fieldX;\r
+               // In the constructor:\r
+               //       fieldX = getExecutionFactory().getValueRow(# cols);\r
+               // private ExecRow exprN()\r
+               // { \r
+               //   fieldX.setColumn(1, col(1).generateColumn(ps)));\r
+               //   ... and so on for each column ...\r
+               //   return fieldX;\r
+               // }\r
+               // static Method exprN = method pointer to exprN;\r
+\r
+               // this sets up the method and the static field.\r
+               MethodBuilder userExprFun = acb.newUserExprFun();\r
+\r
+               /* Declare the field */\r
+               LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE, ClassName.ExecRow);\r
+\r
+               // Generate the code to create the row in the constructor\r
+               genCreateRow(acb, field, "getValueRow", ClassName.ExecRow, size());\r
+\r
+               ResultColumn rc; \r
+               int size = size();\r
+\r
+               MethodBuilder cb = acb.getConstructor();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                   // generate statements of the form\r
+                       // fieldX.setColumn(columnNumber, (DataValueDescriptor) columnExpr);\r
+                       // and add them to exprFun.\r
+                       rc = (ResultColumn) elementAt(index);\r
+\r
+                       /* If we are not generating nulls, then we can skip this RC if\r
+                        * it is simply propagating a column from the source result set.\r
+                        */\r
+                       if (!genNulls)\r
+                       {\r
+                               ValueNode sourceExpr = rc.getExpression();\r
+\r
+                               if (sourceExpr instanceof VirtualColumnNode && ! ( ((VirtualColumnNode) sourceExpr).getCorrelated()))\r
+                               {\r
+                                       continue;\r
+                               }\r
+\r
+                               if (sourceExpr instanceof ColumnReference && ! ( ((ColumnReference) sourceExpr).getCorrelated()))\r
+                               {\r
+                                       continue;\r
+                               }\r
+                       }\r
+\r
+\r
+            // row add is 1-based, and iterator index is 0-based\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               if (index + 1 != rc.getVirtualColumnId())\r
+                               {\r
+                                       SanityManager.THROWASSERT(\r
+                                               "VirtualColumnId (" +\r
+                                               rc.getVirtualColumnId() +\r
+                                               ") does not agree with position within Vector (" +\r
+                                               (index + 1) +\r
+                                               ")");\r
+                               }\r
+                       }\r
+\r
+                       // we need the expressions to be Columns exactly.\r
+\r
+                       /* SPECIAL CASE:  Expression is a non-null constant.\r
+                        *      Generate the setColumn() call in the constructor\r
+                        *  so that it will only be executed once per instantiation.\r
+                        *\r
+                        * Increase the statement counter in constructor.  Code size in\r
+                        * constructor can become too big (more than 64K) for Java compiler\r
+                        * to handle (beetle 4293).  We set constant columns in other\r
+                        * methods if constructor has too many statements already.\r
+                        */\r
+                       if ( (! genNulls) &&\r
+                                (rc.getExpression() instanceof ConstantNode) &&\r
+                                ! ((ConstantNode) rc.getExpression()).isNull() &&\r
+                                ! cb.statementNumHitLimit(1))\r
+                       {\r
+\r
+\r
+                               cb.getField(field); // instance\r
+                               cb.push(index + 1); // first arg;\r
+\r
+                               rc.generateExpression(acb, cb);\r
+                               cb.cast(ClassName.DataValueDescriptor); // second arg\r
+                               cb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Row, "setColumn", "void", 2);\r
+                               continue;\r
+                       }\r
+\r
+                       userExprFun.getField(field); // instance\r
+                       userExprFun.push(index + 1); // arg1\r
+\r
+                       /* We want to reuse the null values instead of doing a new each time\r
+                        * if the caller said to generate nulls or the underlying expression\r
+                        * is a typed null value.\r
+                        */\r
+                       boolean needDVDCast = true;\r
+                       if (rc.isAutoincrementGenerated())\r
+                       {\r
+                               // (com.ibm.db2j.impl... DataValueDescriptor)\r
+                               // this.getSetAutoincValue(column_number)\r
+\r
+                               userExprFun.pushThis();\r
+\r
+                               userExprFun.push(rc.getColumnPosition());\r
+                               userExprFun.push(rc.getTableColumnDescriptor().getAutoincInc());\r
+\r
+                               userExprFun.callMethod(VMOpcode.INVOKEVIRTUAL, ClassName.BaseActivation,\r
+                                               "getSetAutoincrementValue", ClassName.DataValueDescriptor, 2);\r
+                               needDVDCast = false;\r
+                               \r
+                       }\r
+                       else if (genNulls ||\r
+                               ((rc.getExpression() instanceof ConstantNode) &&\r
+                                ((ConstantNode) rc.getExpression()).isNull()))\r
+                       {\r
+                               userExprFun.getField(field);\r
+                               userExprFun.push(index + 1);\r
+                               userExprFun.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Row, "getColumn",\r
+                                       ClassName.DataValueDescriptor, 1); // the express\r
+\r
+                               acb.generateNullWithExpress(userExprFun, rc.getTypeCompiler(),\r
+                                               rc.getTypeServices().getCollationType());\r
+                       }\r
+                       else\r
+                       {\r
+                               rc.generateExpression(acb, userExprFun);\r
+                       }\r
+                       if (needDVDCast)\r
+                               userExprFun.cast(ClassName.DataValueDescriptor);\r
+\r
+                       userExprFun.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Row, "setColumn", "void", 2);\r
+               }\r
+               userExprFun.getField(field);\r
+               userExprFun.methodReturn();\r
+\r
+               // we are now done modifying userExprFun\r
+               userExprFun.complete();\r
+\r
+        // what we return is the access of the field, i.e. the pointer to the method.\r
+           acb.pushMethodReference(mb, userExprFun);\r
+       }\r
+\r
+       /**\r
+         *     Build an empty row with the size and shape of the ResultColumnList.\r
+         *\r
+         *     @return an empty row of the correct size and shape.\r
+         * @exception StandardException                Thrown on error\r
+        */\r
+       public  ExecRow buildEmptyRow()\r
+               throws StandardException\r
+       {\r
+               int                                     columnCount = size();\r
+               ExecRow                         row = getExecutionFactory().getValueRow( columnCount );\r
+               int                                     position = 1;\r
+\r
+               for (int index = 0; index < columnCount; index++)\r
+               {\r
+                   ResultColumn rc = (ResultColumn) elementAt(index);\r
+                       DataTypeDescriptor dataType = rc.getTypeServices();\r
+                       DataValueDescriptor dataValue = dataType.getNull();\r
+\r
+                       row.setColumn( position++, dataValue );\r
+               }\r
+\r
+               return  row;\r
+       }\r
+\r
+       /**\r
+         *     Build an empty index row for the given conglomerate.\r
+         *\r
+         *     @return an empty row of the correct size and shape.\r
+         * @exception StandardException                Thrown on error\r
+        */\r
+       public  ExecRow buildEmptyIndexRow(TableDescriptor td,\r
+                                                                               ConglomerateDescriptor cd,\r
+                                                                               StoreCostController scc,\r
+                                                                               DataDictionary dd)\r
+               throws StandardException\r
+       {\r
+               ResultColumn            rc;\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (! cd.isIndex())\r
+                       {\r
+                               SanityManager.THROWASSERT("ConglomerateDescriptor expected to be for index: " + cd);\r
+                       }\r
+               }\r
+\r
+               int[] baseCols = cd.getIndexDescriptor().baseColumnPositions();\r
+               ExecRow row = getExecutionFactory().getValueRow(baseCols.length + 1);\r
+\r
+               for (int i = 0; i < baseCols.length; i++)\r
+               {\r
+                       ColumnDescriptor coldes = td.getColumnDescriptor(baseCols[i]);\r
+                       DataTypeDescriptor dataType = coldes.getType();\r
+\r
+                       // rc = getResultColumn(baseCols[i]);\r
+                   // rc = (ResultColumn) at(baseCols[i] - 1);\r
+                       // dataType = rc.getTypeServices();\r
+                       DataValueDescriptor dataValue = dataType.getNull();\r
+\r
+                       row.setColumn(i + 1, dataValue );\r
+               }\r
+\r
+               RowLocation rlTemplate = scc.newRowLocationTemplate();\r
+\r
+               row.setColumn(baseCols.length + 1, rlTemplate);\r
+\r
+               return  row;\r
+       }\r
+\r
+\r
+       /**\r
+               Generates a row with the size and shape of the ResultColumnList.\r
+\r
+               Some structures, like FromBaseTable and DistinctNode,\r
+               need to generate rowAllocator functions to get a row\r
+               the size and shape of their ResultColumnList.  \r
+\r
+               We return the method pointer, which is a field access\r
+               in the generated class.\r
+\r
+               @exception StandardException\r
+        */\r
+       void generateHolder(ExpressionClassBuilder acb,\r
+                                                               MethodBuilder mb)\r
+                                                       throws StandardException \r
+       {\r
+               generateHolder(acb, mb, (FormatableBitSet) null, (FormatableBitSet) null);\r
+       }\r
+\r
+       /**\r
+               Generates a row with the size and shape of the ResultColumnList.\r
+\r
+               Some structures, like FromBaseTable and DistinctNode,\r
+               need to generate rowAllocator functions to get a row\r
+               the size and shape of their ResultColumnList.  \r
+\r
+               We return the method pointer, which is a field access\r
+               in the generated class.\r
+\r
+               @exception StandardException\r
+        */\r
+       void generateHolder(ExpressionClassBuilder acb,\r
+                                                               MethodBuilder mb,\r
+                                                               FormatableBitSet referencedCols,\r
+                                                               FormatableBitSet propagatedCols)\r
+                                                               throws StandardException {\r
+\r
+               // what we return is a pointer to the method.\r
+           acb.pushMethodReference(mb, generateHolderMethod(acb, referencedCols, propagatedCols));\r
+       }\r
+\r
+       MethodBuilder generateHolderMethod(ExpressionClassBuilder acb,\r
+                                                               FormatableBitSet referencedCols,\r
+                                                               FormatableBitSet propagatedCols)\r
+                                                       throws StandardException {\r
+               int                     numCols;\r
+               String          rowAllocatorMethod;\r
+               String          rowAllocatorType;\r
+               int                     highestColumnNumber = -1;\r
+\r
+               if (referencedCols != null)\r
+               {\r
+                       // Find the number of the last column referenced in the table\r
+                       for (int i = referencedCols.anySetBit();\r
+                                i != -1;\r
+                                i = referencedCols.anySetBit(i))\r
+                       {\r
+                               highestColumnNumber = i;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       highestColumnNumber = size() - 1;\r
+               }\r
+\r
+               // Within the constructor:\r
+               //       fieldX = getExecutionFactory().getValueRow(# cols);\r
+               // The body of the new method:\r
+               // { \r
+               //   fieldX.setColumn(1, col(1).generateColumn(ps)));\r
+               //   ... and so on for each column ...\r
+               //   return fieldX;\r
+               // }\r
+               // static Method exprN = method pointer to exprN;\r
+\r
+               // this sets up the method and the static field\r
+               MethodBuilder exprFun = acb.newExprFun();\r
+\r
+               // Allocate the right type of row, depending on\r
+               // whether we're scanning an index or a heap.\r
+               if (indexRow)\r
+               {\r
+                       rowAllocatorMethod = "getIndexableRow";\r
+                       rowAllocatorType = ClassName.ExecIndexRow;\r
+               }\r
+               else\r
+               {\r
+                       rowAllocatorMethod = "getValueRow";\r
+                       rowAllocatorType = ClassName.ExecRow;\r
+               }\r
+               numCols = size();\r
+\r
+               /* Declare the field */\r
+               LocalField lf = acb.newFieldDeclaration(Modifier.PRIVATE, ClassName.ExecRow);\r
+               // Generate the code to create the row in the constructor\r
+               genCreateRow(acb, lf, rowAllocatorMethod, rowAllocatorType, highestColumnNumber + 1);\r
+\r
+               // now we fill in the body of the function\r
+\r
+               int colNum;\r
+\r
+               // If there is a referenced column map, the first column to fill\r
+               // in is the first one in the bit map - otherwise, it is\r
+               // column 0.\r
+               if (referencedCols != null)\r
+                       colNum = referencedCols.anySetBit();\r
+               else\r
+                       colNum = 0;\r
+\r
+               for (int index = 0; index < numCols; index++)\r
+               {\r
+                       ResultColumn rc = ((ResultColumn) elementAt(index));\r
+\r
+                       /* Special code generation for RID since expression is CurrentRowLocationNode.\r
+                        * Really need yet another node type that does its own code generation.\r
+                        */\r
+                       if (rc.getExpression() instanceof CurrentRowLocationNode)\r
+                       {\r
+                               ConglomerateController cc = null;\r
+                               int savedItem;\r
+                               RowLocation rl;\r
+                               \r
+                               cc = getLanguageConnectionContext().\r
+                                               getTransactionCompile().openConglomerate(\r
+                                                       conglomerateId,\r
+                            false,\r
+                                                       0,\r
+                                                       TransactionController.MODE_RECORD,\r
+                                                       TransactionController.ISOLATION_READ_COMMITTED);\r
+                               try\r
+                               {\r
+                                       rl = cc.newRowLocationTemplate();\r
+                               }\r
+                               finally\r
+                               {\r
+                                       if (cc != null)\r
+                                       {\r
+                                               cc.close();\r
+                                       }\r
+                               }\r
+\r
+                               savedItem = acb.addItem(rl);\r
+                                                               \r
+                               // get the RowLocation template\r
+                               exprFun.getField(lf); // instance for setColumn\r
+                               exprFun.push(highestColumnNumber + 1); // first arg\r
+\r
+                               exprFun.pushThis(); // instance for getRowLocationTemplate\r
+                               exprFun.push(savedItem); // first arg\r
+                               exprFun.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Activation, "getRowLocationTemplate",\r
+                                                                       ClassName.RowLocation, 1);\r
+\r
+                               exprFun.upCast(ClassName.DataValueDescriptor);\r
+                               exprFun.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Row, "setColumn",\r
+                                                                                       "void", 2);\r
+                               continue;\r
+                       }\r
+\r
+                       /* Skip over those columns whose source is the immediate\r
+                        * child result set.  (No need to generate a wrapper\r
+                        * for a SQL NULL when we are smart enough not to pass\r
+                        * that wrapper to the store.)\r
+                        * NOTE: Believe it or not, we have to check for the case\r
+                        * where referencedCols is not null, but no bits are set.\r
+                        * This can happen when we need to get all of the columns\r
+                        * from the heap due to a check constraint.\r
+                        */\r
+                       if (propagatedCols != null &&\r
+                               propagatedCols.getNumBitsSet() != 0)\r
+                       {\r
+                               /* We can skip this RC if it is simply propagating \r
+                                * a column from the source result set.\r
+                                */\r
+                               ValueNode sourceExpr = rc.getExpression();\r
+\r
+                               if (sourceExpr instanceof VirtualColumnNode)\r
+                               {\r
+                                       // There is a referenced columns bit set, so use\r
+                                       // it to figure out what the next column number is.\r
+                                       // colNum = referencedCols.anySetBit(colNum);\r
+                                       continue;\r
+                               }\r
+                       }\r
+\r
+                       // generate the column space creation call\r
+                       // generate statements of the form\r
+               // r.setColumn(columnNumber, columnShape);\r
+               //\r
+               // This assumes that there are no "holes" in the column positions,\r
+               // and that column positions reflect the stored format/order\r
+                       exprFun.getField(lf); // instance\r
+                       exprFun.push(colNum + 1); // first arg\r
+                       rc.generateHolder(acb, exprFun);\r
+\r
+                       exprFun.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.Row, "setColumn", "void", 2);\r
+\r
+                       // If there is a bit map of referenced columns, use it to\r
+                       // figure out what the next column is, otherwise just go\r
+                       // to the next column.\r
+                       if (referencedCols != null)\r
+                               colNum = referencedCols.anySetBit(colNum);\r
+                       else\r
+                               colNum++;\r
+       }\r
+                       \r
+               // generate:\r
+               // return fieldX;\r
+               // and add to the end of exprFun's body.\r
+               exprFun.getField(lf);\r
+               exprFun.methodReturn();\r
+\r
+               // we are done putting stuff in exprFun:\r
+               exprFun.complete();\r
+\r
+               return exprFun;\r
+       }\r
+\r
+       /**\r
+        * Generate the code to create an empty row in the constructor.\r
+        *\r
+        * @param acb                                   The ACB.\r
+        * @param field                                 The field for the new row.\r
+        * @param rowAllocatorMethod    The method to call.\r
+        * @param rowAllocatorType              The row type.\r
+        * @param numCols                               The number of columns in the row.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       private void genCreateRow(ExpressionClassBuilder acb,\r
+                                                         LocalField field,\r
+                                                         String rowAllocatorMethod, \r
+                                                         String rowAllocatorType, \r
+                                                         int numCols)\r
+               throws StandardException\r
+       {\r
+               // Create the row in the constructor\r
+               //       fieldX = getExecutionFactory().getValueRow(# cols);\r
+\r
+               MethodBuilder cb = acb.getConstructor();\r
+\r
+               acb.pushGetExecutionFactoryExpression(cb); // instance\r
+               cb.push(numCols);\r
+               cb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null,\r
+                                                       rowAllocatorMethod, rowAllocatorType, 1);\r
+               cb.setField(field);\r
+               /* Increase the statement counter in constructor.  Code size in\r
+                * constructor can become too big (more than 64K) for Java compiler\r
+                * to handle (beetle 4293).  We set constant columns in other\r
+                * methods if constructor has too many statements already.\r
+                */\r
+               cb.statementNumHitLimit(1);             // ignore return value\r
+       }\r
+\r
+       /**\r
+        * Make a ResultDescription for use in a ResultSet.\r
+        * This is useful when generating/executing a NormalizeResultSet, since\r
+        * it can appear anywhere in the tree.\r
+        *\r
+        * @return      A ResultDescription for this ResultSetNode.\r
+        */\r
+       public ResultColumnDescriptor[] makeResultDescriptors()\r
+       {\r
+           ResultColumnDescriptor colDescs[] = new ResultColumnDescriptor[size()];\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                   // the ResultColumn nodes are descriptors, so take 'em...\r
+            colDescs[index] = getExecutionFactory().getResultColumnDescriptor(((ResultColumnDescriptor) elementAt(index)));\r
+               }\r
+\r
+               return colDescs;\r
+       }\r
+\r
+       /**\r
+        * Expand any *'s in the ResultColumnList.  In addition, we will guarantee that\r
+        * each ResultColumn has a name.  (All generated names will be unique across the\r
+        * entire statement.)\r
+        *\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+\r
+       public void expandAllsAndNameColumns(FromList fromList)\r
+                                       throws StandardException\r
+       {\r
+               boolean                 expanded = false;\r
+               ResultColumnList allExpansion;\r
+               TableName                       fullTableName;\r
+\r
+               /* First walk result column list looking for *'s to expand */\r
+               for (int index = 0; index < size(); index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+                       if (rc instanceof AllResultColumn)\r
+                       {\r
+                               expanded = true;\r
+\r
+                               //fullTableName = ((AllResultColumn) rc).getFullTableName();\r
+                TableName temp = rc.getTableNameObject();\r
+                if(temp != null) {\r
+                   String sName = temp.getSchemaName();\r
+                   String tName = temp.getTableName();\r
+                   fullTableName = makeTableName(sName,tName);\r
+                }\r
+                else\r
+                   fullTableName = null;\r
+                               allExpansion = fromList.expandAll(fullTableName);\r
+\r
+                               /* Make sure that every column has a name */\r
+                               allExpansion.nameAllResultColumns();\r
+\r
+                               /* Replace the AllResultColumn with the expanded list. \r
+                                * We will update the VirtualColumnIds once below.\r
+                                */\r
+                               removeElementAt(index);\r
+                               for (int inner = 0; inner < allExpansion.size(); inner++)\r
+                               {\r
+                                       insertElementAt(allExpansion.elementAt(inner), index + inner);\r
+                               }\r
+\r
+                               // If the rc was a "*", we need to set the initial list size\r
+                               // to the number of columns that are actually returned to\r
+                               // the user.\r
+                               markInitialSize();\r
+                       }\r
+                       else\r
+                       {\r
+                               /* Make sure that every column has a name */\r
+                               rc.guaranteeColumnName();\r
+                       }\r
+               }\r
+\r
+               /* Go back and update the VirtualColumnIds if we expanded any *'s */\r
+               if (expanded)\r
+               {\r
+                       int size = size();\r
+\r
+                       for (int index = 0; index < size; index++)\r
+                       {\r
+                               /* Vectors are 0-based, VirtualColumnIds are 1-based. */\r
+                               ((ResultColumn) elementAt(index)).setVirtualColumnId(index + 1);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Generate (unique across the entire statement) column names for those\r
+        * ResultColumns in this list which are not named.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void nameAllResultColumns()\r
+               throws StandardException\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+\r
+                       resultColumn.guaranteeColumnName();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Copy the types and lengths for this RCL (the target)\r
+        * to another RCL (the source).  \r
+        * This is useful when adding a NormalizeResultSetNode.\r
+        *\r
+        * @param sourceRCL     The source RCL\r
+        */\r
+       public void copyTypesAndLengthsToSource(ResultColumnList sourceRCL) throws StandardException\r
+       {\r
+               /* Source and target can have different lengths. */\r
+               int size = Math.min(size(), sourceRCL.size());\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn sourceRC = (ResultColumn) sourceRCL.elementAt(index);\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+                       sourceRC.setType(resultColumn.getTypeServices());\r
+                       sourceRC.getExpression().setType(resultColumn.getTypeServices());\r
+               }\r
+       }\r
+               \r
+\r
+       /*\r
+       ** Check whether the column lengths and types of the result columns\r
+       ** match the expressions under those columns.  This is useful for\r
+       ** INSERT and UPDATE statements.  For SELECT statements this method\r
+       ** should always return true.  There is no need to call this for a\r
+       ** DELETE statement.\r
+       ** NOTE: We skip over generated columns since they won't have a\r
+       ** column descriptor.\r
+       **\r
+       ** @return      true means all the columns match their expressions,\r
+       **              false means at least one column does not match its\r
+       **              expression\r
+       */\r
+\r
+       boolean columnTypesAndLengthsMatch()\r
+               throws StandardException\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+\r
+                       /* Skip over generated columns */\r
+                       if (resultColumn.isGenerated())\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       if (! resultColumn.columnTypeAndLengthMatch())\r
+                               return false;\r
+               }\r
+\r
+               return true;\r
+       }\r
+\r
+       boolean columnTypesAndLengthsMatch(ResultColumnList otherRCL)\r
+               throws StandardException\r
+       {\r
+               boolean                 retval = true;\r
+\r
+               /* We check every RC, even after finding 1 that requires\r
+                * normalization, because the conversion of constants to\r
+                * the appropriate type occurs under this loop.\r
+                */\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+\r
+                       ResultColumn otherResultColumn = (ResultColumn) otherRCL.elementAt(index);\r
+\r
+                       /* Skip over generated columns */\r
+                       if (resultColumn.isGenerated() || otherResultColumn.isGenerated())\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       if (! resultColumn.columnTypeAndLengthMatch(otherResultColumn))\r
+                       {\r
+                               retval = false;\r
+                       }\r
+               }\r
+\r
+               return retval;\r
+       }\r
+\r
+       /**\r
+        * Determine whether this RCL is a No-Op projection of the given RCL.\r
+        * It only makes sense to do this if the given RCL is from the child\r
+        * result set of the ProjectRestrict that this RCL is from.\r
+        *\r
+        * @param childRCL      The ResultColumnList of the child result set.\r
+        *\r
+        * @return      true if this RCL is a No-Op projection of the given RCL.\r
+        */\r
+       public boolean nopProjection(ResultColumnList childRCL)\r
+       {\r
+               /*\r
+               ** This RCL is a useless projection if each column in the child\r
+               ** if the same as the column in this RCL.  This is impossible\r
+               ** if the two RCLs have different numbers of columns.\r
+               */\r
+               if (this.size() != childRCL.size())\r
+               {\r
+                       return false;\r
+               }\r
+\r
+               /*\r
+               ** The two lists have the same numbers of elements.  Are the lists\r
+               ** identical?  In other words, is the expression in every ResultColumn\r
+               ** in the PRN's RCL a ColumnReference that points to the corresponding\r
+               ** column in the child?\r
+               */\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn thisColumn = (ResultColumn) elementAt(index);\r
+                       ResultColumn referencedColumn = null;\r
+\r
+                       /*\r
+                       ** A No-Op projection can point to a VirtualColumnNode or a\r
+                       ** ColumnReference.\r
+                       */\r
+                       if (thisColumn.getExpression() instanceof VirtualColumnNode)\r
+                       {\r
+                               referencedColumn =\r
+                                       ((VirtualColumnNode) (thisColumn.getExpression())).\r
+                                                                                                                       getSourceColumn();\r
+                       }\r
+                       else if (thisColumn.getExpression() instanceof ColumnReference)\r
+                       {\r
+                               referencedColumn =\r
+                                       ((ColumnReference) (thisColumn.getExpression())).\r
+                                                                                                                               getSource();\r
+                       }\r
+                       else\r
+                       {\r
+                               return false;\r
+                       }\r
+\r
+                       ResultColumn childColumn = (ResultColumn) childRCL.elementAt(index);\r
+\r
+                       if (referencedColumn != childColumn)\r
+                       {\r
+                               return false;\r
+                       }\r
+               }\r
+\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        *  Create a shallow copy of a ResultColumnList and its ResultColumns.\r
+        *  (All other pointers are preserved.)\r
+        *  Useful for building new ResultSetNodes during preprocessing.\r
+        *\r
+        *  @return None.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public ResultColumnList copyListAndObjects()\r
+                                       throws StandardException\r
+       {\r
+               ResultColumn     newResultColumn;\r
+               ResultColumn     origResultColumn;\r
+               ResultColumnList newList;\r
+\r
+               /* Create the new ResultColumnList */\r
+               newList = (ResultColumnList) getNodeFactory().getNode(\r
+                                                                               C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                               getContextManager());\r
+\r
+               /* Walk the current list - for each ResultColumn in the list, make a copy\r
+                * and add it to the new list.\r
+                */\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       origResultColumn = (ResultColumn) elementAt(index);\r
+\r
+                       newResultColumn = origResultColumn.cloneMe();\r
+\r
+                       newList.addResultColumn(newResultColumn);\r
+               }\r
+        newList.copyOrderBySelect(this);\r
+               return newList;\r
+       }\r
+\r
+       /**\r
+        * Remove any columns that may have been added for an order by clause.\r
+        * In a query like:\r
+        * <pre>select a from t order by b</pre> b is added to the select list\r
+        * However in the final projection, after the sort is complete, b will have\r
+        * to be removed. \r
+        *\r
+        */\r
+       public void removeOrderByColumns() \r
+       {\r
+               int idx = size() - 1;\r
+               for (int i = 0; i < orderBySelect; i++, idx--) {\r
+                       removeElementAt(idx);\r
+               }\r
+               orderBySelect = 0;\r
+       }\r
+       \r
+       /**\r
+        * Walk the list and replace ResultColumn.expression with a new \r
+        * VirtualColumnNode.  This is useful when propagating a ResultColumnList\r
+        * up the query tree.\r
+        * NOTE: This flavor marks all of the underlying RCs as referenced.\r
+        *\r
+        * @param sourceResultSet               ResultSetNode that is source of value\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void genVirtualColumnNodes(ResultSetNode sourceResultSet, \r
+                                                                         ResultColumnList sourceResultColumnList)\r
+                               throws StandardException\r
+       {\r
+               genVirtualColumnNodes(sourceResultSet, sourceResultColumnList, true);\r
+       }\r
+\r
+\r
+\r
+       /**\r
+        * Walk the list and replace ResultColumn.expression with a new \r
+        * VirtualColumnNode.  This is useful when propagating a ResultColumnList\r
+        * up the query tree.\r
+        *\r
+        * @param sourceResultSet               ResultSetNode that is source of value\r
+        * @param markReferenced                Whether or not to mark the underlying RCs\r
+        *                                                              as referenced\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void genVirtualColumnNodes(ResultSetNode sourceResultSet, \r
+                                                                         ResultColumnList sourceResultColumnList,\r
+                                                                         boolean markReferenced)\r
+                               throws StandardException\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+\r
+                       /* dts = resultColumn.getExpression().getTypeServices(); */\r
+                       DataTypeDescriptor dts = resultColumn.getTypeServices();\r
+\r
+                       /* Vectors are 0-based, VirtualColumnIds are 1-based */\r
+                       resultColumn.expression = (ValueNode) getNodeFactory().getNode(\r
+                                                       C_NodeTypes.VIRTUAL_COLUMN_NODE,\r
+                                                       sourceResultSet,\r
+                                                       sourceResultColumnList.elementAt(index),\r
+                                                       ReuseFactory.getInteger(index + 1),\r
+                                                       getContextManager());\r
+\r
+                       /* Mark the ResultColumn as being referenced */\r
+                       if (markReferenced)\r
+                       {\r
+                               resultColumn.setReferenced();\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Walk the list and adjust the virtualColumnIds in the ResultColumns\r
+        * by the specified amount.  If ResultColumn.expression is a VirtualColumnNode,\r
+        * then we adjust the columnId there as well.\r
+        *\r
+        * @param adjust                The size of the increment.\r
+        */\r
+       public void adjustVirtualColumnIds(int adjust)\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+                       resultColumn.adjustVirtualColumnId(adjust);\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               if ( !\r
+                                       (resultColumn.getExpression() instanceof VirtualColumnNode))\r
+                               {\r
+                                       SanityManager.THROWASSERT(\r
+                                               "resultColumn.getExpression() is expected to be " +\r
+                                               "instanceof VirtualColumnNode" +\r
+                                               " not " +\r
+                                               resultColumn.getExpression().getClass().getName());\r
+                               }\r
+                       }\r
+\r
+                       ((VirtualColumnNode) resultColumn.getExpression()).columnId += adjust;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Project out any unreferenced ResultColumns from the list and \r
+        * reset the virtual column ids in the referenced ResultColumns.\r
+        * If all ResultColumns are projected out, then the list is not empty.\r
+        * \r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void     doProjection() throws StandardException\r
+       {\r
+               int                             numDeleted = 0;\r
+               int size = size();\r
+               ResultColumnList deletedRCL = new ResultColumnList();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+\r
+                       /* RC's for FromBaseTables are marked as referenced during binding.\r
+                        * For other nodes, namely JoinNodes, we need to go 1 level\r
+                        * down the RC/VCN chain to see if the RC is referenced.  This is\r
+                        * because we propagate the referencing info from the bottom up.\r
+                        */\r
+                       if ((! resultColumn.isReferenced()) &&\r
+                               (resultColumn.getExpression() instanceof VirtualColumnNode) &&\r
+                               !(((VirtualColumnNode) resultColumn.getExpression()).getSourceColumn().isReferenced()))\r
+                       {\r
+                               // Remember the RC to delete when done\r
+                               deletedRCL.addElement(resultColumn);\r
+\r
+                               /* Remember how many we have deleted and decrement the\r
+                                * VirtualColumnIds for all nodes which appear after us\r
+                                * in the list.\r
+                                */\r
+                               numDeleted++;\r
+                       }\r
+                       else\r
+                       {\r
+                               /* Decrement the VirtualColumnId for each node in the list\r
+                                * after the 1st deleted one.\r
+                                */\r
+                if (numDeleted >= 1)\r
+                    resultColumn.adjustVirtualColumnId( - numDeleted);\r
+                               /* Make sure that the RC is marked as referenced! */\r
+                               resultColumn.setReferenced();\r
+                       }\r
+               }\r
+\r
+               // Go back and delete the RCs to be delete from the list\r
+               for (int index = 0; index < deletedRCL.size(); index++)\r
+               {\r
+                       removeElement((ResultColumn) deletedRCL.elementAt(index));\r
+               }\r
+       }\r
+\r
+       /** \r
+        * Check the uniqueness of the column names within a column list.\r
+        *\r
+        * @param errForGenCols Raise an error for any generated column names.\r
+        *\r
+        * @return String       The first duplicate column name, if any.\r
+        */\r
+       public String verifyUniqueNames(boolean errForGenCols)\r
+                                       throws StandardException\r
+       {\r
+               int size = size();\r
+               Hashtable       ht = new Hashtable(size + 2, (float) .999);\r
+               ResultColumn rc;\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       rc = (ResultColumn) elementAt(index);\r
+                       if (errForGenCols && rc.isNameGenerated())\r
+                               throw StandardException.newException(SQLState.LANG_DB2_VIEW_REQUIRES_COLUMN_NAMES);\r
+                       /* Verify that this column's name is unique within the list */\r
+                       String colName = ((ResultColumn) elementAt(index)).getName();\r
+\r
+                       Object object = ht.put(colName, colName);\r
+\r
+                       if (object != null &&\r
+                               ((String) object).equals(colName))\r
+                       {\r
+                               return colName;\r
+                       }\r
+               }\r
+\r
+               /* No duplicate column names */\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Validate the derived column list (DCL) and propagate the info\r
+        * from the list to the final ResultColumnList.\r
+        *\r
+        * @param derivedRCL    The derived column list\r
+        * @param tableName             The table name for the FromTable\r
+        *\r
+        * @exception StandardException Thrown on error\r
+        */\r
+       public void propagateDCLInfo(ResultColumnList derivedRCL, String tableName)\r
+                                       throws StandardException\r
+       {\r
+               String duplicateColName;\r
+\r
+               /* Do both lists, if supplied by user, have the same degree? */\r
+               if (derivedRCL.size() != size() &&\r
+                   ! derivedRCL.getCountMismatchAllowed())\r
+               {\r
+                       if (visibleSize() != derivedRCL.size()) {\r
+                               throw StandardException.newException(SQLState.LANG_DERIVED_COLUMN_LIST_MISMATCH, tableName);\r
+                       }\r
+               }\r
+\r
+               /* Check the uniqueness of the column names within the derived list */\r
+               duplicateColName = derivedRCL.verifyUniqueNames(false);\r
+               if (duplicateColName != null)\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_DERIVED, duplicateColName);\r
+               }\r
+\r
+               /* We can finally copy the derived names into the final list */\r
+               copyResultColumnNames(derivedRCL);\r
+       }\r
+\r
+       /**\r
+        * Look for and reject ? parameters under ResultColumns.  This is done for\r
+        * SELECT statements.\r
+        *\r
+        * @exception StandardException         Thrown if a ? parameter found directly\r
+        *                                                                      under a ResultColumn\r
+        */\r
+\r
+       void rejectParameters() throws StandardException\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+                       rc.rejectParameter();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Check for (and reject) XML values directly under the ResultColumns.\r
+        * This is done for SELECT/VALUES statements.  We reject values\r
+        * in this case because JDBC does not define an XML type/binding\r
+        * and thus there's no standard way to pass such a type back\r
+        * to a JDBC application.\r
+        *\r
+        * Note that we DO allow an XML column in a top-level RCL\r
+        * IF that column was added to the RCL by _us_ instead of\r
+        * by the user.  For example, if we have a table:\r
+        *\r
+        * create table t1 (i int, x xml)\r
+        *\r
+        * and the user query is:\r
+        *\r
+        * select i from t1 order by x\r
+        *\r
+        * the "x" column will be added (internally) to the RCL\r
+        * as part of ORDER BY processing--and so we need to\r
+        * allow that XML column to be bound without throwing\r
+        * an error.  If, as in this case, the XML column reference\r
+        * is invalid (we can't use ORDER BY on an XML column because\r
+        * XML values aren't ordered), a more appropriate error\r
+        * message should be returned to the user in later processing.\r
+        * If we didn't allow for this, the user would get an\r
+        * error saying that XML columns are not valid as part\r
+        * of the result set--but as far as s/he knows, there\r
+        * isn't such a column: only "i" is supposed to be returned\r
+        * (the RC for "x" was added to the RCL by _us_ as part of\r
+        * ORDER BY processing).\r
+        *\r
+        * ASSUMPTION: Any RCs that are generated internally and\r
+        * added to this RCL (before this RCL is bound) are added\r
+        * at the _end_ of the list.  If that's true, then any\r
+        * RC with an index greater than the size of the initial\r
+        * (user-specified) list must have been added internally\r
+        * and will not be returned to the user.\r
+        *\r
+        * @exception StandardException         Thrown if an XML value found\r
+        *                                                                      directly under a ResultColumn\r
+        */\r
+       void rejectXMLValues() throws StandardException\r
+       {\r
+               int sz = size();\r
+               ResultColumn rc = null;\r
+               for (int i = 1; i <= sz; i++) {\r
+\r
+                       if (i > initialListSize)\r
+                       // this RC was generated internally and will not\r
+                       // be returned to the user, so don't throw error.\r
+                               continue;\r
+\r
+                       rc = getResultColumn(i);\r
+                       if ((rc != null) && (rc.getType() != null) &&\r
+                               rc.getType().getTypeId().isXMLTypeId())\r
+                       { // Disallow it.\r
+                               throw StandardException.newException(\r
+                                       SQLState.LANG_ATTEMPT_TO_SELECT_XML);\r
+                       }\r
+\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Set the resultSetNumber in all of the ResultColumns.\r
+        *\r
+        * @param resultSetNumber       The resultSetNumber\r
+        */\r
+       public void setResultSetNumber(int resultSetNumber)\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ((ResultColumn) elementAt(index)).setResultSetNumber(resultSetNumber);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Mark all of the ResultColumns as redundant.\r
+        * Useful when chopping a ResultSetNode out of a tree when there are\r
+        * still references to its RCL.\r
+        */\r
+       public void setRedundant()\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ((ResultColumn) elementAt(index)).setRedundant();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Verify that all of the columns in the SET clause of a positioned update\r
+        * appear in the cursor's FOR UPDATE OF list.\r
+        *\r
+        * @param ucl                   The cursor's FOR UPDATE OF list.  (May be null.)\r
+        * @param cursorName    The cursor's name.\r
+        *\r
+        * @exception StandardException                 Thrown on error\r
+        */\r
+       public void checkColumnUpdateability(String[] ucl, String cursorName) \r
+                       throws StandardException\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+\r
+                       if (resultColumn.updated() &&\r
+                               ! resultColumn.foundInList(ucl))\r
+                       {\r
+                               throw StandardException.newException(SQLState.LANG_COLUMN_NOT_UPDATABLE_IN_CURSOR, \r
+                                                       resultColumn.getName(),\r
+                                                       cursorName);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Set up the result expressions for a UNION, INTERSECT, or EXCEPT:\r
+        *      o Verify union type compatiblity\r
+        *      o Get dominant type for result (type + max length + nullability)\r
+        *  o Create a new ColumnReference with dominant type and name of from this\r
+        *    RCL and make that the new expression.\r
+        *  o Set the type info for in the ResultColumn to the dominant type\r
+        *\r
+        * NOTE - We are assuming that caller has generated a new RCL for the UNION\r
+        * with the same names as the left side's RCL and copies of the expressions.\r
+        *\r
+        * @param otherRCL      RCL from other side of the UNION.\r
+        * @param tableNumber   The tableNumber for the UNION.\r
+        * @param level         The nesting level for the UNION.\r
+     * @param operatorName "UNION", "INTERSECT", or "EXCEPT"\r
+        *\r
+        * @exception StandardException                 Thrown on error\r
+        */\r
+       public void     setUnionResultExpression(ResultColumnList otherRCL,\r
+                                         int tableNumber,\r
+                                         int level,\r
+                                         String operatorName)\r
+               throws StandardException\r
+       {\r
+               TableName               dummyTN;\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (visibleSize() != otherRCL.visibleSize())\r
+                       {\r
+                               SanityManager.THROWASSERT(\r
+                                                       "size() = (" +\r
+                                                       size() +\r
+                                                       ") is expected to equal otherRCL.size (" +\r
+                                                       otherRCL.size() +\r
+                                                       ")");\r
+                       }\r
+               }\r
+\r
+               /* Make a dummy TableName to be shared by all new CRs */\r
+               dummyTN = (TableName) getNodeFactory().getNode(\r
+                                                                               C_NodeTypes.TABLE_NAME,\r
+                                                                               null,\r
+                                                                               null,\r
+                                                                               getContextManager());\r
+\r
+               ContextManager cm = getContextManager();\r
+\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       boolean          nullableResult;\r
+                       ColumnReference newCR;\r
+                       ResultColumn thisRC = (ResultColumn) elementAt(index);\r
+                       ResultColumn otherRC = (ResultColumn) otherRCL.elementAt(index);\r
+                       ValueNode        thisExpr = thisRC.getExpression();\r
+                       ValueNode        otherExpr = otherRC.getExpression();\r
+\r
+                       // If there is one row that is not 'autoincrement', the Union should\r
+                       // not be 'autoincrement'.\r
+                       if (!otherRC.isAutoincrementGenerated() && thisRC.isAutoincrementGenerated())\r
+                       {\r
+                               thisRC.resetAutoincrementGenerated();\r
+                       }\r
+                       /*\r
+                       ** If there are ? parameters in the ResultColumnList of a row\r
+                       ** in a table constructor, their types will not be set.  Just skip\r
+                       ** these - their types will be set later.  Each ? parameter will\r
+                       ** get the type of the first non-? in its column, so it can't\r
+                       ** affect the final dominant type.  It's possible that all the\r
+                       ** rows for a particular column will have ? parameters - this is\r
+                       ** an error condition that will be caught later.\r
+                       */\r
+                       TypeId thisTypeId = thisExpr.getTypeId();\r
+                       if (thisTypeId == null)\r
+                               continue;\r
+\r
+                       TypeId otherTypeId = otherExpr.getTypeId();\r
+                       if (otherTypeId == null)\r
+                               continue;\r
+\r
+                       /* \r
+                       ** Check type compatability.  We want to make sure that\r
+                       ** the types are assignable in either direction\r
+                       ** and they are comparable.\r
+                       */\r
+                       ClassFactory cf = getClassFactory();\r
+                       if (\r
+                               !thisExpr.getTypeCompiler().storable(otherTypeId, cf) &&\r
+                               !otherExpr.getTypeCompiler().storable(thisTypeId, cf))\r
+                       {\r
+                               throw StandardException.newException(SQLState.LANG_NOT_UNION_COMPATIBLE, \r
+                                                     thisTypeId.getSQLTypeName(),\r
+                                                     otherTypeId.getSQLTypeName(),\r
+                                                     operatorName);\r
+                       }\r
+\r
+                       DataTypeDescriptor resultType = thisExpr.getTypeServices().getDominantType(\r
+                                                                                               otherExpr.getTypeServices(),\r
+                                                                                               cf);\r
+\r
+                       newCR = (ColumnReference) getNodeFactory().getNode(\r
+                                                                               C_NodeTypes.COLUMN_REFERENCE,\r
+                                                                               thisRC.getName(),\r
+                                                                               dummyTN,\r
+                                                                               getContextManager());\r
+                       newCR.setType(resultType);\r
+                       /* Set the tableNumber and nesting levels in newCR.\r
+                        * If thisExpr is not a CR, then newCR cannot be\r
+                        * correlated, hence source and nesting levels are\r
+                        * the same.\r
+                        */\r
+                       if (thisExpr instanceof ColumnReference)\r
+                       {\r
+                               newCR.copyFields((ColumnReference) thisExpr);\r
+                       }\r
+                       else\r
+                       {\r
+                               newCR.setNestingLevel(level);\r
+                               newCR.setSourceLevel(level);\r
+                       }\r
+                       newCR.setTableNumber(tableNumber);\r
+                       thisRC.setExpression(newCR);\r
+                       thisRC.setType(\r
+                               thisRC.getTypeServices().getDominantType(\r
+                                       otherRC.getTypeServices(), cf));\r
+\r
+                       /* DB2 requires both sides of union to have same name for the result to\r
+                        * have that name. Otherwise, leave it or set it to a generated name */\r
+                       if (thisRC.getName() != null && !thisRC.isNameGenerated() &&\r
+                               otherRC.getName() != null)\r
+                       {\r
+                               /* Result name needs to be changed */\r
+                               if (otherRC.isNameGenerated())\r
+                               {\r
+                                       thisRC.setName(otherRC.getName());\r
+                                       thisRC.setNameGenerated(true);\r
+                               }\r
+                               else if (!thisRC.getName().equals(otherRC.getName()))\r
+                               {\r
+                                       /* Both sides have user specified names that don't match */\r
+                                       thisRC.setName(null);\r
+                                       thisRC.guaranteeColumnName();\r
+                                       thisRC.setNameGenerated(true);\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Do the 2 RCLs have the same type & length.\r
+        * This is useful for UNIONs when deciding whether a NormalizeResultSet is required.\r
+        *\r
+        * @param otherRCL      The other RCL.\r
+        *\r
+        * @return boolean      Whether or not there is an exact UNION type match on the 2 RCLs.\r
+        */\r
+       public boolean isExactTypeAndLengthMatch(ResultColumnList otherRCL) throws StandardException\r
+       {\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn thisRC = (ResultColumn) elementAt(index);\r
+                       ResultColumn otherRC = (ResultColumn) otherRCL.elementAt(index);\r
+\r
+                       if (! thisRC.getTypeServices().isExactTypeAndLengthMatch(\r
+                                                                                               otherRC.getTypeServices() ))\r
+                       {\r
+                               return false;\r
+                       }\r
+               }\r
+\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Does the column list contain any of the given column positions\r
+        * that are updated? Implements same named routine in UpdateList.\r
+        *\r
+        * @param columns       An array of column positions\r
+        *\r
+        * @return      True if this column list contains any of the given columns\r
+        */\r
+       public  boolean updateOverlaps(int[] columns)\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+\r
+                       if ( ! rc.updated())\r
+                               continue;\r
+\r
+                       int     column = rc.getColumnPosition();\r
+\r
+                       for (int i = 0; i < columns.length; i++)\r
+                       {\r
+                               if (columns[i] == column)\r
+                                       return true;\r
+                       }\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Return an array that contains references to the columns in this list\r
+        * sorted by position.\r
+        *\r
+        * @return      The sorted array.\r
+        */\r
+       ResultColumn[] getSortedByPosition()\r
+       {\r
+               int                             size = size();\r
+               ResultColumn[]  result;\r
+               \r
+               /*\r
+               ** Form an array of the original ResultColumns\r
+               */\r
+               result = new ResultColumn[size];\r
+\r
+               /*\r
+               ** Put the ResultColumns in the array\r
+               */\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       result[index] = (ResultColumn) elementAt(index);\r
+               }\r
+\r
+               /*\r
+               ** Sort the array by column position\r
+               */\r
+               java.util.Arrays.sort(result);\r
+               return result;\r
+       }\r
+\r
+       /**\r
+         *     Return an array of all my column positions, sorted in\r
+         *     ascending order.\r
+         *\r
+         *     @return a sorted array\r
+         */\r
+       public  int[]   sortMe()\r
+       {\r
+               ResultColumn[] sortedResultColumns = getSortedByPosition();\r
+               int[] sortedColumnIds = new int[sortedResultColumns.length];\r
+               for (int ix = 0; ix < sortedResultColumns.length; ix++)\r
+               {\r
+                       sortedColumnIds[ix] = sortedResultColumns[ix].getColumnPosition();\r
+               }\r
+               return sortedColumnIds;\r
+       }\r
+\r
+\r
+       /**\r
+        * Expand this ResultColumnList by adding all columns from the given\r
+        * table that are not in this list.  The result is sorted by column\r
+        * position.\r
+        *\r
+        * @param td    The TableDescriptor for the table in question\r
+        * @param tableName     The name of the table as given in the query\r
+        *\r
+        * @return      A new ResultColumnList expanded to include all columns in\r
+        *                      the given table.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public ResultColumnList expandToAll(TableDescriptor td,\r
+                                                               TableName tableName)\r
+                                               throws StandardException\r
+       {\r
+               ResultColumn                            rc;\r
+               ColumnDescriptor                        cd;\r
+               ResultColumnList                        retval;\r
+               ResultColumn[]                          originalRCS;\r
+               int                                                     posn;\r
+\r
+               /* Get a new ResultColumnList */\r
+               retval = (ResultColumnList) getNodeFactory().getNode(\r
+                                                                               C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                               getContextManager());\r
+\r
+               /*\r
+               ** Form a sorted array of the ResultColumns\r
+               */\r
+               originalRCS = getSortedByPosition();\r
+\r
+               posn = 0;\r
\r
+               /* Iterate through the ColumnDescriptors for the given table */\r
+               ColumnDescriptorList cdl = td.getColumnDescriptorList();\r
+               int                                      cdlSize = cdl.size();\r
+\r
+               for (int index = 0; index < cdlSize; index++)\r
+               {\r
+                       cd = (ColumnDescriptor) cdl.elementAt(index);\r
+\r
+                       if ((posn < originalRCS.length) &&\r
+                               (cd.getPosition() == originalRCS[posn].getColumnPosition()))\r
+                       {\r
+                               rc = originalRCS[posn];\r
+                               posn++;\r
+                       }\r
+                       else\r
+                       {\r
+                               /* Build a ResultColumn/ColumnReference pair for the column */\r
+                               rc = makeColumnReferenceFromName( tableName, cd.getColumnName() );\r
+\r
+                               /* Bind the new ResultColumn */\r
+                               rc.bindResultColumnByPosition(td, cd.getPosition());\r
+                       }\r
+\r
+                       /* Add the ResultColumn to the list */\r
+                       retval.addResultColumn(rc);\r
+               }\r
+\r
+               if (SanityManager.DEBUG)\r
+               SanityManager.ASSERT(posn == originalRCS.length,\r
+               "ResultColumns in original list not added to expanded ResultColumnList");\r
+\r
+               return retval;\r
+       }\r
+\r
+       /**\r
+        * Bind any untyped null nodes to the types in the given ResultColumnList.\r
+        * Nodes that don't know their type may pass down nulls to\r
+        * children nodes.  In the case of something like a union, it knows\r
+        * to try its right and left result sets against each other. \r
+        * But if a null reaches us, it means we have a null type that\r
+        * we don't know how to handle.\r
+        *\r
+        * @param bindingRCL    The ResultColumnList with the types to bind to.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void bindUntypedNullsToResultColumns(ResultColumnList bindingRCL)\r
+                               throws StandardException\r
+       {\r
+               if (bindingRCL == null)\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_NULL_IN_VALUES_CLAUSE);\r
+               }\r
+               \r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(bindingRCL.size() >= this.size(),\r
+                                       "More columns in result column list than in base table");\r
+\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn    bindingRC = (ResultColumn) bindingRCL.elementAt(index);\r
+                       ResultColumn    thisRC = (ResultColumn) elementAt(index);\r
+\r
+                       thisRC.typeUntypedNullExpression(bindingRC);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Mark all the columns in this list as updated by an update statement.\r
+        */\r
+       void markUpdated()\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ((ResultColumn) elementAt(index)).markUpdated();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Mark all the (base) columns in this list as updatable by a positioned update\r
+        * statement.  This is necessary\r
+        * for positioned update statements, because we expand the column list\r
+        * to include all the columns in the base table, and we need to be able\r
+        * to tell which ones the user is really trying to update so we can\r
+        * determine correctly whether all the updated columns are in the\r
+        * "for update" list.\r
+        */\r
+       void markUpdatableByCursor()\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       //determine if the column is a base column and not a derived column\r
+                       if (((ResultColumn) elementAt(index)).getSourceTableName() != null)\r
+                               ((ResultColumn) elementAt(index)).markUpdatableByCursor();\r
+               }\r
+       }\r
+\r
+       /** \r
+        * @see QueryTreeNode#disablePrivilegeCollection\r
+        */\r
+       public void disablePrivilegeCollection()\r
+       {\r
+               super.disablePrivilegeCollection();\r
+\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+                       ((ResultColumn) elementAt(index)).disablePrivilegeCollection();                 \r
+       }\r
+       \r
+       /**\r
+        * Verify that all of the column names in this list are contained\r
+        * within the ColumnDefinitionNodes within the TableElementList.\r
+        *\r
+        * \r
+        * @return String       The 1st column name, if any, that is not in the list.\r
+        */\r
+       public String verifyCreateConstraintColumnList(TableElementList tel)\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       String colName = ((ResultColumn) elementAt(index)).getName();\r
+\r
+                       if (! tel.containsColumnName(colName))\r
+                       {\r
+                               return colName;\r
+                       }\r
+               }\r
+               return null;\r
+       }\r
+\r
+       /**\r
+        * Export the result column names to the passed in String[].\r
+        *\r
+        * @param columnNames   String[] to hold the column names.\r
+        */\r
+       public void exportNames(String[] columnNames)\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (size() != columnNames.length)\r
+                       {\r
+                               SanityManager.THROWASSERT(\r
+                                       "size() (" +\r
+                                       size() + \r
+                                       ") is expected to equal columnNames.length (" +\r
+                                       columnNames.length +\r
+                                       ")");\r
+                       }\r
+               }\r
+\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       columnNames[index] = ((ResultColumn) elementAt(index)).getName();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Given a ResultColumn at the next deepest level in the tree, \r
+        * search this RCL for its parent ResultColumn.\r
+        *\r
+        * @param childRC       The child ResultColumn\r
+        *\r
+        * @return ResultColumn The parent ResultColumn\r
+        */\r
+       public ResultColumn findParentResultColumn(ResultColumn childRC)\r
+       {\r
+               ResultColumn    parentRC = null;\r
+\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn    rc =  (ResultColumn) elementAt(index);\r
+\r
+                       if (rc.getExpression() instanceof ColumnReference)\r
+                       {\r
+                               ColumnReference cr = (ColumnReference) rc.getExpression();\r
+\r
+                               if (cr.getSource() == childRC)\r
+                               {\r
+                                       parentRC = rc;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       else if (rc.getExpression() instanceof VirtualColumnNode)\r
+                       {\r
+                               VirtualColumnNode vcn = (VirtualColumnNode) rc.getExpression();\r
+\r
+                               if (vcn.getSourceColumn() == childRC)\r
+                               {\r
+                                       parentRC = rc;\r
+                                       break;\r
+                               }\r
+                       }\r
+\r
+               }\r
+\r
+               return parentRC;\r
+       }\r
+\r
+       /**\r
+        * Mark as updatable all the columns in this result column list\r
+        * that match the columns in the given update column list.\r
+        *\r
+        * @param updateColumns         A ResultColumnList representing the columns\r
+        *                                                      to be updated.\r
+        */\r
+       void markUpdated(ResultColumnList updateColumns)\r
+       {\r
+               ResultColumn    updateColumn;\r
+               ResultColumn    resultColumn;\r
+\r
+               int size = updateColumns.size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       updateColumn = (ResultColumn) updateColumns.elementAt(index);\r
+\r
+                       resultColumn = getResultColumn(updateColumn.getName());\r
+\r
+                       /*\r
+                       ** This ResultColumnList may not be bound yet - for update\r
+                       ** statements, we mark the updated columns *before* we bind\r
+                       ** the RCL.  This ordering is important because we add columns\r
+                       ** to the RCL after marking the update columns and before\r
+                       ** binding.\r
+                       **\r
+                       ** So, it can happen that there is an invalid column name in\r
+                       ** the list.  This condition will cause an exception when the\r
+                       ** RCL is bound.  Just ignore it for now.\r
+                       */\r
+                       if (resultColumn != null)\r
+                       {\r
+                               resultColumn.markUpdated();\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Mark all the columns in the select sql that this result column list represents\r
+        * as updatable if they match the columns in the given update column list.\r
+        *\r
+        * @param updateColumns         A Vector representing the columns\r
+        *                                                      to be updated.\r
+        */\r
+       void markColumnsInSelectListUpdatableByCursor(Vector updateColumns)\r
+       {\r
+               commonCodeForUpdatableByCursor(updateColumns, true);\r
+       }\r
+\r
+       /**\r
+        * dealingWithSelectResultColumnList true means we are dealing with\r
+        * ResultColumnList for a select sql. When dealing with ResultColumnList for\r
+        * select sql, it is possible that not all the updatable columns are\r
+        * projected in the select column list and hence it is possible that we may\r
+        * not find the column to be updated in the ResultColumnList and that is why\r
+        * special handling is required when dealingWithSelectResultColumnList is true.\r
+        * eg select c11, c13 from t1 for update of c11, c12\r
+        * In the eg above, we will find updatable column c11 in the select column\r
+        * list but we will not find updatable column c12 in the select column list\r
+        */\r
+       private void commonCodeForUpdatableByCursor(Vector updateColumns, boolean dealingWithSelectResultColumnList)\r
+       {\r
+               /*\r
+               ** If there is no update column list, or the list is empty, then it means that\r
+               ** all the columns which have a base table associated with them are updatable.\r
+               */\r
+               if ( (updateColumns == null) || (updateColumns.size() == 0) )\r
+               {\r
+                       markUpdatableByCursor();\r
+               }\r
+               else\r
+               {\r
+                       int                             ucSize = updateColumns.size();\r
+                       ResultColumn    resultColumn;\r
+                       String columnName;\r
+\r
+                       for (int index = 0; index < ucSize; index++)\r
+                       {\r
+                               columnName = (String) updateColumns.elementAt(index);\r
+\r
+                               resultColumn = getResultColumn(columnName);\r
+                               if (SanityManager.DEBUG)\r
+                               {\r
+                                       if (resultColumn == null && !dealingWithSelectResultColumnList)\r
+                                       {\r
+                                               SanityManager.THROWASSERT("No result column found with name " +\r
+                                                       columnName);\r
+                                       }\r
+                               }\r
+                               //Following if means the column specified in FOR UPDATE clause is not\r
+                               //part of the select list\r
+                               if (resultColumn == null && dealingWithSelectResultColumnList)\r
+                                       continue;\r
+                               resultColumn.markUpdatableByCursor();\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Mark as updatable all the columns in this result column list\r
+        * that match the columns in the given update column list\r
+        *\r
+        * @param updateColumns         A Vector representing the columns\r
+        *                                                      to be updated.\r
+        */\r
+       void markUpdatableByCursor(Vector updateColumns)\r
+       {\r
+               commonCodeForUpdatableByCursor(updateColumns, false);\r
+       }\r
+\r
+       /**\r
+        * Returns true if the given column position is for a column that will\r
+        * be or could be updated by the positioned update of a cursor.\r
+        *\r
+        * @param columnPosition        The position of the column in question\r
+        *\r
+        * @return      true if the column is updatable\r
+        */\r
+       boolean updatableByCursor(int columnPosition)\r
+       {\r
+               return getResultColumn(columnPosition).updatableByCursor();\r
+       }\r
+\r
+\r
+       /** \r
+        * Return whether or not this RCL can be flattened out of a tree.\r
+        * It can only be flattened if the expressions are all cloneable.\r
+        *\r
+        * @return boolean      Whether or not this RCL can be flattened out of a tree.\r
+        */\r
+       public boolean isCloneable()\r
+       {\r
+               boolean retcode = true;\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn    rc =  (ResultColumn) elementAt(index);\r
+\r
+                       if (! rc.getExpression().isCloneable())\r
+                       {\r
+                               retcode = false;\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               return retcode;\r
+       }\r
+\r
+       /**\r
+        * Remap all ColumnReferences in this tree to be clones of the\r
+        * underlying expression.\r
+        *\r
+        * @exception StandardException                 Thrown on error\r
+        */\r
+       public void remapColumnReferencesToExpressions() throws StandardException\r
+       {\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+\r
+                       // The expression may be null if this column is an identity\r
+                       // column generated always. If the expression is not null, it\r
+                       // is a ColumnReference; we call through to the ColumnReference\r
+                       // to give it a chance to remap itself from the outer query\r
+                       // node to this one.\r
+                       if (rc.getExpression() != null)\r
+                               rc.setExpression(\r
+                                       rc.getExpression().remapColumnReferencesToExpressions());\r
+               }\r
+       }\r
+\r
+       /*\r
+       ** Indicate that the conglomerate is an index, so we need to generate a\r
+       ** RowLocation as the last column of the result set.\r
+       **\r
+       ** @param cid   The conglomerate id of the index\r
+       */\r
+       void setIndexRow(long cid, boolean forUpdate)\r
+       {\r
+               indexRow = true;\r
+               conglomerateId = cid;\r
+               this.forUpdate = forUpdate;\r
+       }\r
+\r
+       /* Debugging methods */\r
+\r
+       /**\r
+        * Verify that all ResultColumns and their expressions have type information\r
+        * and that the type information between the respective RCs and\r
+        * expressions matches.\r
+        *\r
+        * @return boolean      Whether or not the type information is consistent\r
+        */\r
+       public boolean hasConsistentTypeInfo() throws StandardException\r
+       {\r
+               boolean isConsistent = true;\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+                       {\r
+                               ResultColumn    rc = (ResultColumn) elementAt(index);\r
+                               ValueNode               expr = rc.getExpression();\r
+                               DataTypeDescriptor rcDTS = rc.getTypeServices();\r
+                               DataTypeDescriptor exDTS = expr.getTypeServices();\r
+\r
+                               if (rcDTS == null || exDTS == null)\r
+                               {\r
+                                       isConsistent = false;\r
+                                       break;\r
+                               }\r
+\r
+                               if (rcDTS.getClass().getName() !=\r
+                                       exDTS.getClass().getName())\r
+                               {\r
+                                       isConsistent = false;\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               return isConsistent;\r
+       }\r
+\r
+       /**\r
+        * Return whether or not this RCL contains an AllResultColumn.\r
+        * This is useful when dealing with SELECT * views which \r
+        * reference tables that may have had columns added to them via \r
+        * ALTER TABLE since the view was created.\r
+        *\r
+        * @return Whether or not this RCL contains an AllResultColumn.\r
+        */\r
+       public boolean containsAllResultColumn()\r
+       {\r
+               boolean containsAllResultColumn = false;\r
+\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       if (elementAt(index) instanceof AllResultColumn)\r
+                       {\r
+                               containsAllResultColumn = true;\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               return containsAllResultColumn;\r
+       }\r
+\r
+       /**\r
+        * Count the number of RCs in the list that are referenced.\r
+        *\r
+        * @return      The number of RCs in the list that are referenced.\r
+        */\r
+       public int countReferencedColumns()\r
+       {\r
+               int numReferenced = 0;\r
+\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+                       if (rc.isReferenced())\r
+                       {\r
+                               numReferenced++;\r
+                       }\r
+               }\r
+               return numReferenced;\r
+       }\r
+\r
+       /**\r
+        * Record the column ids of the referenced columns in the specified array.\r
+        *\r
+        * @param idArray       int[] for column ids\r
+        * @param basis         0 (for 0-based ids) or 1 (for 1-based ids)\r
+        */\r
+       public void recordColumnReferences(int[] idArray, int basis)\r
+       {\r
+               int currArrayElement = 0;\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+\r
+                       if (rc.isReferenced())\r
+                       {\r
+                               idArray[currArrayElement++] = index + basis;\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Record the top level ColumnReferences in the specified array\r
+        * and table map\r
+        * This is useful when checking for uniqueness conditions.\r
+        * NOTE: All top level CRs assumed to be from the same table.\r
+        *               The size of the array is expected to be the # of columns\r
+        *               in the table of interest + 1, so we use 1-base column #s.\r
+        *\r
+        * @param colArray1     boolean[] for columns\r
+        * @param tableColMap   JBitSet[] for tables\r
+        * @param tableNumber   Table number of column references\r
+        */\r
+       public void recordColumnReferences(boolean[] colArray1, JBitSet[] tableColMap,\r
+                       int tableNumber)\r
+       {\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       int columnNumber;\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+\r
+                       if (! (rc.getExpression() instanceof ColumnReference))\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       columnNumber = ((ColumnReference) rc.getExpression()).getColumnNumber();\r
+                       colArray1[columnNumber] = true;\r
+                       tableColMap[tableNumber].set(columnNumber);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Return whether or not all of the RCs in the list whose\r
+        * expressions are ColumnReferences are \r
+        * from the same table.  One place this\r
+        * is useful for distinct elimination based on the existence\r
+        * of a uniqueness condition.\r
+        *\r
+        * @return      -1 if all of the top level CRs in the RCL\r
+        *                      are not ColumnReferences from the same table,\r
+        *                      else the tableNumber\r
+        */\r
+       int allTopCRsFromSameTable()\r
+       {\r
+               int tableNumber = -1;\r
+\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+                       ValueNode vn = rc.getExpression();\r
+                       if (! (vn instanceof ColumnReference))\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       // Remember the tableNumber from the first CR\r
+                       ColumnReference cr = (ColumnReference) vn;\r
+                       if (tableNumber == -1)\r
+                       {\r
+                               tableNumber = cr.getTableNumber();\r
+                       }\r
+                       else if (tableNumber != cr.getTableNumber())\r
+                       {\r
+                               return -1;\r
+                       }\r
+               }\r
+               return tableNumber;\r
+       }\r
+\r
+       /**\r
+        * Clear the column references from the RCL. (Restore RCL back to a state\r
+        * where none of the RCs are marked as referenced.)\r
+        */\r
+       public void clearColumnReferences()\r
+       {\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+\r
+                       if (rc.isReferenced())\r
+                       {\r
+                               rc.setUnreferenced();\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Copy the referenced RCs from this list to the supplied target list.\r
+        *\r
+        * @param targetList    The list to copy to\r
+        */\r
+       public void copyReferencedColumnsToNewList(ResultColumnList targetList)\r
+       {\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+\r
+                       if (rc.isReferenced())\r
+                       {\r
+                               targetList.addElement(rc);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Copy the RCs from this list to the supplied target list.\r
+        *\r
+        * @param targetList    The list to copy to,\r
+        * @param copyList      1 based bitMap we copy columns associated with set bits.\r
+        */\r
+       public void copyColumnsToNewList(ResultColumnList targetList, FormatableBitSet copyList)\r
+       {\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+                       if (copyList.isSet(rc.getColumnPosition())) \r
+                       {\r
+                               targetList.addElement(rc);\r
+                       }\r
+               }\r
+       }\r
+\r
+\r
+       /**\r
+        * Get a FormatableBitSet of the columns referenced in this rcl\r
+        *\r
+        * @return the FormatableBitSet\r
+        */\r
+       public FormatableBitSet getColumnReferenceMap()\r
+       {\r
+               FormatableBitSet colMap = new FormatableBitSet(size());\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+                       if (rc.isReferenced())\r
+                       {\r
+                               colMap.set(index);\r
+                       }       \r
+               }\r
+               return colMap;\r
+       }\r
+\r
+    /**\r
+     * Or in any isReferenced booleans from the virtual column chain. That is the isReferenced bits on each\r
+     * ResultColumn on the list will be set if the ResultColumn is referenced or if any VirtualColumnNode in its\r
+     * expression chain refers to a referenced column.\r
+     */\r
+    void pullVirtualIsReferenced()\r
+    {\r
+        int size = size();\r
+        for( int index = 0; index < size; index++)\r
+        {\r
+            ResultColumn rc = (ResultColumn) elementAt(index);\r
+            rc.pullVirtualIsReferenced();\r
+        }\r
+    } // end of pullVirtualIsReferenced\r
+\r
+       public void clearTableNames()\r
+       {\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+                       rc.clearTableName();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Set the value of whether or not a count mismatch is allowed between\r
+        * this RCL, as a derived column list, and an underlying RCL.  This is allowed\r
+        * for SELECT * views when an underlying table has had columns added to it\r
+        * via ALTER TABLE.\r
+        *\r
+        * @param allowed       Whether or not a mismatch is allowed.\r
+        */\r
+       protected void setCountMismatchAllowed(boolean allowed)\r
+       {\r
+               countMismatchAllowed = allowed;\r
+       }\r
+\r
+       /**\r
+        * Return whether or not a count mismatch is allowed between this RCL,\r
+        * as a derived column list, and an underlying RCL.  This is allowed\r
+        * for SELECT * views when an underlying table has had columns added to it\r
+        * via ALTER TABLE.\r
+        *\r
+        * return Whether or not a mismatch is allowed.\r
+        */\r
+\r
+       protected boolean getCountMismatchAllowed()\r
+       {\r
+               return countMismatchAllowed;\r
+       }\r
+\r
+       /**\r
+        * Get the size of all the columns added\r
+        * together.  Does <B>NOT</B> include the\r
+        * column overhead that the store requires.\r
+        * Also, will be a very rough estimate for\r
+        * user types.\r
+        *\r
+        * @return the size\r
+        */\r
+       public int getTotalColumnSize()\r
+       {\r
+               int colSize = 0;\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       colSize += ((ResultColumn) elementAt(index)).getMaximumColumnSize();\r
+               }\r
+               return colSize;\r
+       }\r
+\r
+       /** \r
+        * Generate an RCL to match the contents of a ResultSetMetaData.\r
+        * This is useful when dealing with VTIs.\r
+        *\r
+        * @param rsmd                  The ResultSetMetaData.\r
+        * @param tableName             The TableName for the BCNs.\r
+        * @param javaClassName The name of the VTI\r
+        *\r
+        * @exception StandardException                 Thrown on error\r
+        */\r
+       public void createListFromResultSetMetaData(ResultSetMetaData rsmd,\r
+                                                                                               TableName tableName,\r
+                                                                                               String javaClassName)\r
+                       throws StandardException\r
+       {\r
+               try\r
+               {\r
+                       // JDBC columns #s are 1-based\r
+                       // Check to make sure # of columns >= 1\r
+                       int numColumns = rsmd.getColumnCount();\r
+\r
+                       if (numColumns <= 0)\r
+                       {\r
+                               throw StandardException.newException(SQLState.LANG_INVALID_V_T_I_COLUMN_COUNT, \r
+                                                                       javaClassName, String.valueOf(numColumns));\r
+                       }\r
+\r
+                       for (int index = 1; index <= numColumns; index++)\r
+                       {\r
+                               boolean nullableResult = \r
+                                       (rsmd.isNullable(index) != ResultSetMetaData.columnNoNulls);\r
+\r
+                               TypeId cti;\r
+\r
+                               int jdbcColumnType = rsmd.getColumnType(index);\r
+\r
+                               switch (jdbcColumnType) {\r
+                               case org.apache.derby.iapi.reference.JDBC20Translation.SQL_TYPES_JAVA_OBJECT:\r
+                               case Types.OTHER:\r
+                               {\r
+                                       cti = TypeId.getUserDefinedTypeId(rsmd.getColumnTypeName(index), false);\r
+                                       break;\r
+                               }\r
+                               default:\r
+                               {\r
+                                       cti = TypeId.getBuiltInTypeId(jdbcColumnType);\r
+                                       break;\r
+                               }\r
+                               }\r
+\r
+                               // Handle the case where a VTI returns a bad column type\r
+                               if (cti == null)\r
+                               {\r
+                                       throw StandardException.newException(SQLState.LANG_BAD_J_D_B_C_TYPE_INFO, Integer.toString(index));\r
+                               }\r
+\r
+                               // Get the maximum byte storage for this column\r
+                               int maxWidth;\r
+\r
+                               /* Get maximum byte storage from rsmd for variable\r
+                                * width types, set it to MAXINT for the long types,\r
+                                * otherwise get it from the TypeId\r
+                                */\r
+                               if (cti.variableLength())\r
+                               {\r
+                                       maxWidth = rsmd.getColumnDisplaySize(index);\r
+                               }\r
+                               else if (jdbcColumnType == Types.LONGVARCHAR ||\r
+                                                jdbcColumnType == Types.LONGVARBINARY)\r
+                               {\r
+                                       maxWidth = Integer.MAX_VALUE;\r
+                               }\r
+                               else\r
+                               {\r
+                                       maxWidth = 0;\r
+                               }\r
+\r
+                               int precision = cti.isDecimalTypeId() ? rsmd.getPrecision(index) : 0;\r
+                               int scale = cti.isDecimalTypeId() ? rsmd.getScale(index) : 0;\r
+                               DataTypeDescriptor dts = new DataTypeDescriptor(cti, \r
+                                                                                       precision,\r
+                                                                                       scale, \r
+                                                                                       nullableResult, \r
+                                                                                       maxWidth);\r
+                               ValueNode bcn = (ValueNode) getNodeFactory().getNode(\r
+                                                                                       C_NodeTypes.BASE_COLUMN_NODE,\r
+                                                                                       rsmd.getColumnName(index),\r
+                                                                                       tableName,\r
+                                                                                       dts,\r
+                                                                                       getContextManager());\r
+                               ResultColumn rc = (ResultColumn) getNodeFactory().getNode(\r
+                                                                               C_NodeTypes.RESULT_COLUMN,\r
+                                                                               rsmd.getColumnName(index),\r
+                                                                               bcn,\r
+                                                                               getContextManager());\r
+                               rc.setType(dts);\r
+                               addResultColumn(rc);\r
+                       }\r
+               }\r
+               catch (Throwable t)\r
+               {\r
+                       if (t instanceof StandardException)\r
+                       {\r
+                               throw (StandardException) t;\r
+                       }\r
+                       else\r
+                       {\r
+                               throw StandardException.unexpectedUserException(t);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Add an RC to the end of the list for the RID from an index.\r
+        * NOTE: RC.expression is a CurrentRowLocationNode.  This was previously only used\r
+        * for non-select DML.  We test for this node when generating the holder above\r
+        * and generate the expected code.  (We really should create yet another new node\r
+        * type with its own code generation.)\r
+        *\r
+        * @exception StandardException                 Thrown on error\r
+        */\r
+       public void addRCForRID()\r
+               throws StandardException\r
+       {\r
+               ResultColumn            rowLocationColumn;\r
+               CurrentRowLocationNode          rowLocationNode;\r
+\r
+               /* Generate the RowLocation column */\r
+               rowLocationNode = (CurrentRowLocationNode) getNodeFactory().getNode(\r
+                                                                               C_NodeTypes.CURRENT_ROW_LOCATION_NODE,\r
+                                                                               getContextManager());\r
+               rowLocationColumn =\r
+                               (ResultColumn) getNodeFactory().getNode(\r
+                                                                       C_NodeTypes.RESULT_COLUMN,\r
+                                                                       "",\r
+                                                                       rowLocationNode,\r
+                                                                       getContextManager());\r
+               rowLocationColumn.markGenerated();\r
+\r
+               /* Append to the ResultColumnList */\r
+               addResultColumn(rowLocationColumn);\r
+       }\r
+\r
+       /**\r
+        * Walk the list and mark all RCs as unreferenced.  This is useful\r
+        * when recalculating which RCs are referenced at what level like\r
+        * when deciding which columns need to be returned from a non-matching\r
+        * index scan (as opposed to those returned from the base table).\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void markAllUnreferenced()\r
+                               throws StandardException\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+                       resultColumn.setUnreferenced();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Determine if all of the RC.expressions are columns in the source result set.\r
+        * This is useful for determining if we need to do reflection\r
+        * at execution time.\r
+        *\r
+        * @param sourceRS      The source ResultSet.\r
+        *\r
+        * @return Whether or not all of the RC.expressions are columns in the source result set.\r
+        */\r
+       boolean allExpressionsAreColumns(ResultSetNode sourceRS)\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn    resultColumn;\r
+                       ValueNode               expr;\r
+\r
+                       resultColumn = (ResultColumn) elementAt(index);\r
+                       expr = resultColumn.getExpression();\r
+                       if (! (expr instanceof VirtualColumnNode) &&\r
+                               ! (expr instanceof ColumnReference))\r
+                       {\r
+                               return false;\r
+                       }\r
+\r
+                       /* If the expression is a VirtualColumnNode, make sure that the column\r
+                        * is coming from the source result set, ie, that it is not a correlated\r
+                        * column.\r
+                        */\r
+                       if (expr instanceof VirtualColumnNode)\r
+                       {\r
+                               VirtualColumnNode vcn = (VirtualColumnNode) expr;\r
+                               if (vcn.getSourceResultSet() != sourceRS)\r
+                               {\r
+                                       vcn.setCorrelated();\r
+                                       return false;\r
+                               }\r
+                       }\r
+\r
+                       /* Make sure this is not a correlated CR */\r
+                       if (expr instanceof ColumnReference)\r
+                       {\r
+                               ColumnReference cr = (ColumnReference) expr;\r
+                               if (cr.getCorrelated())\r
+                               {\r
+                                       return false;\r
+                               }\r
+                       }\r
+               }\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Map the source columns to these columns.  Build an array to represent the mapping.\r
+        * For each RC, if the expression is simply a VCN or a CR then set the array element to be\r
+        * the virtual column number of the source RC.  Otherwise, set the array element to\r
+        * -1.\r
+        * This is useful for determining if we need to do reflection\r
+        * at execution time.\r
+        *\r
+        * @return      Array representiong mapping of RCs to source RCs.\r
+        */\r
+       int[] mapSourceColumns()\r
+       {\r
+               int[]                   mapArray = new int[size()];\r
+               ResultColumn    resultColumn;\r
+\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       resultColumn = (ResultColumn) elementAt(index);\r
+                       if (resultColumn.getExpression() instanceof VirtualColumnNode)\r
+                       {\r
+                               VirtualColumnNode vcn = (VirtualColumnNode) resultColumn.getExpression();\r
+\r
+                               // Can't deal with correlated VCNs\r
+                               if (vcn.getCorrelated())\r
+                               {\r
+                                       mapArray[index] = -1;\r
+                               }\r
+                               else\r
+                               {\r
+                                       // Virtual column #s are 1-based\r
+                                       mapArray[index] = vcn.getSourceColumn().getVirtualColumnId();\r
+                               }\r
+                       }\r
+                       else if (resultColumn.getExpression() instanceof ColumnReference)\r
+                       {\r
+                               ColumnReference cr = (ColumnReference) resultColumn.getExpression();\r
+\r
+                               // Can't deal with correlated CRs\r
+                               if (cr.getCorrelated())\r
+                               {\r
+                                       mapArray[index] = -1;\r
+                               }\r
+                               else\r
+                               {\r
+                                       // Virtual column #s are 1-based\r
+                                       mapArray[index] = cr.getSource().getVirtualColumnId();\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               mapArray[index] = -1;\r
+                       }\r
+               }\r
+\r
+               return mapArray;\r
+       }\r
+\r
+       /** Set the nullability of every ResultColumn in this list */\r
+       public void setNullability(boolean nullability)\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+                       resultColumn.setNullability(nullability);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Generate a FormatableBitSet representing the columns that are referenced in this RCL.\r
+        * The caller decides if they want this FormatableBitSet if every RC is referenced.\r
+        * \r
+        * @param positionedUpdate Whether or not the scan that the RCL \r
+        *                                              belongs to is for update w/o a column list\r
+        * @param always                Whether or not caller always wants a non-null FormatableBitSet if\r
+        *                                              all RCs are referenced.\r
+        * @param onlyBCNs              If true, only set bit if expression is a BaseColumnNode,\r
+        *                                              otherwise set bit for all referenced RCs.\r
+        *\r
+        * @return The FormatableBitSet representing the referenced RCs.\r
+       */\r
+\r
+       FormatableBitSet getReferencedFormatableBitSet(boolean positionedUpdate, boolean always, boolean onlyBCNs) \r
+       {\r
+               int     index;\r
+               int colsAdded = 0;\r
+               int size = size();\r
+\r
+               FormatableBitSet newReferencedCols = new FormatableBitSet(size);\r
+\r
+               /*\r
+               ** For an updatable cursor, we need\r
+               ** all columns.\r
+               */\r
+               if (positionedUpdate)\r
+               {\r
+                       if (always)\r
+                       {\r
+                               /* Set all bits in the bit map */\r
+                               for (index = 0; index < size; index++)\r
+                               {\r
+                                       newReferencedCols.set(index);\r
+                               }\r
+\r
+                               return newReferencedCols;\r
+                       }\r
+                       else\r
+                       {\r
+                               return null;\r
+                       }\r
+               }\r
+       \r
+               for (index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn oldCol = (ResultColumn) elementAt(index);\r
+                       if (oldCol.isReferenced())\r
+                       {\r
+                               /* Skip RCs whose expression is not a BCN\r
+                                * when requested to do so.\r
+                                */\r
+                               if (onlyBCNs && ! (oldCol.getExpression() instanceof BaseColumnNode))\r
+                               {\r
+                                       continue;\r
+                               }\r
+                               newReferencedCols.set(index);\r
+                               colsAdded++;\r
+                       }\r
+               }\r
+\r
+               /* Return the FormatableBitSet if not all RCs are referenced or if\r
+                * the caller always wants the FormatableBitSet returned.\r
+                */\r
+               if (colsAdded != index || always)\r
+               {\r
+                       return newReferencedCols;\r
+               }\r
+               else\r
+               {\r
+                       return null;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Create a new, compacted RCL based on the referenced RCs\r
+        * in this list.  If the RCL being compacted is for an\r
+        * updatable scan, then we simply return this.\r
+        *\r
+        * The caller tells us whether or not they want a new list\r
+        * if there is no compaction because all RCs are referenced.\r
+        * This is useful in the case where the caller needs a new\r
+        * RCL for existing RCs so that it can augment the new list.\r
+        * \r
+        * @param positionedUpdate Whether or not the scan that the RCL \r
+        *                                              belongs to is for update w/o a column list\r
+        * @param always                Whether or not caller always wants a new RCL\r
+        *\r
+        * @return The compacted RCL if compaction occurred, otherwise return this RCL.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       ResultColumnList compactColumns(boolean positionedUpdate, boolean always) \r
+               throws StandardException\r
+       {\r
+               int     index;\r
+               int colsAdded = 0;\r
+\r
+               /*\r
+               ** For an updatable cursor, we need\r
+               ** all columns.\r
+               */\r
+               if (positionedUpdate)\r
+               {\r
+                       return this;\r
+               }\r
+       \r
+               ResultColumnList newCols = (ResultColumnList) getNodeFactory().getNode(\r
+                                                                                               C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                                               getContextManager());\r
+\r
+               int size = size();\r
+               for (index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn oldCol = (ResultColumn) elementAt(index);\r
+                       if (oldCol.isReferenced())\r
+                       {\r
+                               newCols.addResultColumn(oldCol);\r
+                               colsAdded++;\r
+                       }\r
+               }\r
+\r
+               /* Return new RCL if we found unreferenced columns or if\r
+                * the caller always wants a new list. \r
+                */\r
+               if (colsAdded != index || always)\r
+               {\r
+                       return newCols;\r
+               }\r
+               else\r
+               {\r
+                       return this;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Remove the columns which are join columns (in the\r
+        * joinColumns RCL) from this list.  This is useful\r
+        * for a JOIN with a USING clause.\r
+        * \r
+        * @param joinColumns   The list of join columns\r
+        */\r
+       void removeJoinColumns(ResultColumnList joinColumns)\r
+       {\r
+               int jcSize = joinColumns.size();\r
+               for (int index = 0; index < jcSize; index++)\r
+               {\r
+                       ResultColumn joinRC = (ResultColumn) joinColumns.elementAt(index);\r
+                       String columnName = joinRC.getName();\r
+\r
+                       // columnName should always be non-null\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               SanityManager.ASSERT(columnName != null,\r
+                                       "columnName should be non-null");\r
+                       }\r
+\r
+                       ResultColumn rightRC = getResultColumn(columnName);\r
+\r
+                       // Remove the RC from this list.\r
+                       if (rightRC != null)\r
+                       {\r
+                               removeElement(rightRC);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Get the join columns from this list.\r
+        * This is useful for a join with a USING clause.  \r
+        * (ANSI specifies that the join columns appear 1st.) \r
+        *\r
+        * @param joinColumns   A list of the join columns.\r
+        *\r
+        * @return A list of the join columns from this list\r
+        */\r
+       ResultColumnList getJoinColumns(ResultColumnList joinColumns)\r
+       {\r
+               ResultColumnList        newRCL = new ResultColumnList();\r
+\r
+               /* Find all of the join columns and put them 1st on the\r
+                * new RCL.\r
+                */\r
+               int jcSize = joinColumns.size();\r
+               for (int index = 0; index < jcSize; index++)\r
+               {\r
+                       ResultColumn joinRC = (ResultColumn) joinColumns.elementAt(index);\r
+                       String columnName = joinRC.getName();\r
+\r
+                       // columnName should always be non-null\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               SanityManager.ASSERT(columnName != null,\r
+                                       "columnName should be non-null");\r
+                       }\r
+\r
+                       ResultColumn xferRC = getResultColumn(columnName);\r
+\r
+                       // Add the RC to the new list.\r
+                       newRCL.addElement(xferRC);\r
+               }\r
+               return newRCL;\r
+       }\r
+\r
+       /**\r
+        * Reset the virtual column ids for all of the\r
+        * underlying RCs.  (Virtual column ids are 1-based.)\r
+        */\r
+       void resetVirtualColumnIds()\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       /* ResultColumns are 1-based */\r
+                       ((ResultColumn) elementAt(index)).setVirtualColumnId(index + 1);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Return whether or not the same result row can be used for all\r
+        * rows returned by the associated ResultSet.  This is possible\r
+        * if all entries in the list are constants or AggregateNodes.\r
+        *\r
+        * @return Whether or not the same result row can be used for all\r
+        * rows returned by the associated ResultSet. \r
+        */\r
+       boolean reusableResult()\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+\r
+                       if ((rc.getExpression() instanceof ConstantNode) ||\r
+                               (rc.getExpression() instanceof AggregateNode))\r
+                       {\r
+                               continue;\r
+                       }\r
+                       return false;\r
+               }\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Get an array of column positions (1-based) for all the columns\r
+        * in this RCL. Assumes that all the columns are in the passed-in\r
+        * table\r
+        *\r
+        * @return the array of strings\r
+        *\r
+        *      @exception      throws StandardException on error\r
+        */\r
+       public int[] getColumnPositions( TableDescriptor td )\r
+               throws StandardException\r
+       {\r
+               int                             size = size();\r
+               int[]                           myPositions = new int[ size ];\r
+               String                          columnName;\r
+               ColumnDescriptor        cd;\r
+\r
+               for ( int index = 0; index < size; index++ )\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt( index );\r
+                       columnName = resultColumn.getName();\r
+                       cd = td.getColumnDescriptor( columnName );\r
+\r
+                       if ( cd == null )\r
+                       {\r
+                               throw StandardException.newException\r
+                                       ( SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, columnName, td.getQualifiedName() );\r
+                       }\r
+\r
+                       myPositions[ index ] = cd.getPosition();\r
+               }\r
+\r
+               return myPositions;\r
+       }\r
+\r
+       /**\r
+        * Get an array of strings for all the columns\r
+        * in this RCL.\r
+        *\r
+        * @return the array of strings\r
+        */\r
+       public String[] getColumnNames()\r
+       {\r
+               String strings[] = new String[size()];\r
+\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn resultColumn = (ResultColumn) elementAt(index);\r
+                       strings[index] = resultColumn.getName();\r
+               }\r
+               return strings;\r
+       }\r
+\r
+       /**\r
+        * Replace any DEFAULTs with the associated tree for the default.\r
+        *\r
+        * @param ttd   The TableDescriptor for the target table.\r
+        * @param tcl   The RCL for the target table.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       void replaceDefaults(TableDescriptor ttd, ResultColumnList tcl) \r
+               throws StandardException\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+\r
+                       if (rc.isDefaultColumn())\r
+                       {\r
+                               //                              DefaultNode defaultNode = (DefaultNode) rc.getExpression();\r
+                               // Get ColumnDescriptor by name or by position?\r
+                               ColumnDescriptor cd;\r
+                               if (tcl == null)\r
+                               {\r
+                                       cd = ttd.getColumnDescriptor(index + 1);\r
+                               }\r
+                               else\r
+                               {\r
+                                       ResultColumn trc = (ResultColumn) tcl.elementAt(index);\r
+                                       cd = ttd.getColumnDescriptor(trc.getName());\r
+                               }\r
+\r
+                               // Too many RCs if no ColumnDescriptor\r
+                               if (cd == null)\r
+                               {\r
+                                       throw StandardException.newException(SQLState.LANG_TOO_MANY_RESULT_COLUMNS, \r
+                                                                       ttd.getQualifiedName());\r
+                               }\r
+\r
+                               if (cd.isAutoincrement())\r
+                               {\r
+                                       rc.setAutoincrementGenerated();\r
+                               } // end of if ()\r
+                               \r
+                               DefaultInfoImpl defaultInfo = (DefaultInfoImpl) cd.getDefaultInfo();\r
+                               if (defaultInfo != null)\r
+                               {\r
+                                       /* Query is dependent on the DefaultDescriptor */\r
+                                       DefaultDescriptor defaultDescriptor = cd.getDefaultDescriptor(getDataDictionary());\r
+                                       getCompilerContext().createDependency(defaultDescriptor);\r
+\r
+                                       rc.setExpression(\r
+                                               DefaultNode.parseDefault(\r
+                                                       defaultInfo.getDefaultText(),\r
+                                                       getLanguageConnectionContext(),\r
+                                                       getCompilerContext()));\r
+\r
+                               }\r
+                               else\r
+                               {\r
+                                       rc.setExpression(\r
+                                               (ValueNode) getNodeFactory().getNode(\r
+                                                                               C_NodeTypes.UNTYPED_NULL_CONSTANT_NODE,\r
+                                                                               getContextManager()));\r
+                               }\r
+                               rc.setDefaultColumn(false);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Walk the RCL and check for DEFAULTs.  DEFAULTs\r
+        * are invalid at the time that this method is called,\r
+        * so we throw an exception if found.\r
+        * NOTE: The grammar allows:\r
+        *              VALUES DEFAULT;\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       void checkForInvalidDefaults()\r
+               throws StandardException\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+\r
+                       if (rc.isAutoincrementGenerated())\r
+                               continue;\r
+\r
+                       if (rc.isDefaultColumn())\r
+                       {\r
+                               throw StandardException.newException(SQLState.LANG_INVALID_USE_OF_DEFAULT);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Verify that all of the RCs in this list are comparable.\r
+        * \r
+        * @exception StandardException         Thrown on error\r
+     */\r
+       void verifyAllOrderable() \r
+               throws StandardException\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+                       rc.verifyOrderable();\r
+               }\r
+       }\r
+\r
+       /**\r
+         *     Build this ResultColumnList from a table description and\r
+         *     an array of column IDs.\r
+         *\r
+         *     @param  table           describes the table\r
+         *     @param  columnIDs       column positions in that table (1-based)\r
+         *\r
+         * @exception StandardException                Thrown on error\r
+         */\r
+       public  void    populate\r
+       (\r
+               TableDescriptor table,\r
+               int[]                   columnIDs\r
+       )\r
+               throws StandardException\r
+       {\r
+               if ( columnIDs == null ) { return; }\r
+\r
+               int                                             count = columnIDs.length;\r
+               TableName                               tableName = makeTableName( table.getSchemaName(), table.getName() );\r
+               String                                  columnName;\r
+               int                                             columnPosition;\r
+               ResultColumn                    rc;\r
+\r
+               for ( int i = 0; i < count; i++ )\r
+               {\r
+                       columnPosition = columnIDs[ i ];\r
+                       columnName = table.getColumnDescriptor( columnPosition ).getColumnName();\r
+\r
+                       rc = makeColumnFromName( columnName );\r
+\r
+                       addResultColumn( rc );\r
+               }\r
+\r
+       }\r
+\r
+       private ResultColumn    makeColumnFromName( String columnName )\r
+               throws StandardException\r
+       {\r
+               ResultColumn    resultColumn = (ResultColumn) getNodeFactory().getNode\r
+                       (\r
+                               C_NodeTypes.RESULT_COLUMN,\r
+                               columnName,\r
+                               null,\r
+                               getContextManager()\r
+                       );\r
+\r
+               return resultColumn;\r
+       }\r
+\r
+       private ResultColumn    makeColumnReferenceFromName\r
+       (\r
+               TableName       tableName,\r
+               String          columnName\r
+       )\r
+               throws StandardException\r
+       {\r
+               ContextManager  cm = getContextManager();\r
+               NodeFactory             nodeFactory = getNodeFactory();\r
+\r
+               ResultColumn    rc = (ResultColumn) nodeFactory.getNode\r
+                       (\r
+                               C_NodeTypes.RESULT_COLUMN,\r
+                               null,\r
+                               nodeFactory.getNode\r
+                               (\r
+                                       C_NodeTypes.COLUMN_REFERENCE,\r
+                                       columnName,\r
+                                       tableName,\r
+                                       cm\r
+                               ),\r
+                               cm\r
+                       );\r
+\r
+               return  rc;\r
+       }\r
+       \r
+       /**\r
+        * check if any autoincrement columns exist in the result column list.\r
+        * called from insert or update where you cannot insert/update the value\r
+        * of an autoincrement column.\r
+        *\r
+        * @exception StandardException         If the column is an ai column\r
+        */\r
+       public void checkAutoincrement(ResultColumnList sourceRSRCL)\r
+               throws StandardException\r
+       {\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(index);\r
+                       ResultColumn sourceRC = \r
+                               (ResultColumn)((sourceRSRCL == null) ? null : sourceRSRCL.elementAt(index));\r
+                       ColumnDescriptor cd = rc.getTableColumnDescriptor();\r
+                       \r
+                       if ((cd != null) && (cd.isAutoincrement()))\r
+                       {\r
+                               if ((sourceRC != null) && \r
+                                       (sourceRC.isAutoincrementGenerated()))\r
+                               {\r
+                                       sourceRC.setColumnDescriptor(cd.getTableDescriptor(), cd);\r
+\r
+                               }else{\r
+                                       if(cd.isAutoincAlways())\r
+                                               throw StandardException.newException(SQLState.LANG_AI_CANNOT_MODIFY_AI,\r
+                                                                       rc.getName());\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       public void incOrderBySelect()\r
+       {\r
+               orderBySelect++;\r
+       }\r
+\r
+       private void decOrderBySelect()\r
+       {\r
+               orderBySelect--;\r
+       }\r
+\r
+       public int getOrderBySelect()\r
+       {\r
+               return orderBySelect;\r
+       }\r
+\r
+    public void copyOrderBySelect( ResultColumnList src)\r
+    {\r
+        orderBySelect = src.orderBySelect;\r
+    }\r
+\r
+       /* ****\r
+        * Take note of the size of this RCL _before_ we start\r
+        * processing/binding it.  This is so that, at bind time,\r
+        * we can tell if any columns in the RCL were added\r
+        * internally by us (i.e. they were not specified by the\r
+        * user and thus will not be returned to the user).\r
+        */\r
+       protected void markInitialSize() {\r
+               initialListSize = size();\r
+       }\r
+\r
+       private int numGeneratedColumns() \r
+       {\r
+               int numGenerated = 0;\r
+               int sz = size();\r
+               for (int i = sz - 1; i >= 0; i--) \r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(i);\r
+                       if (rc.isGenerated()) \r
+                       {\r
+                               numGenerated++;\r
+                       }\r
+               }\r
+               return numGenerated;\r
+       }\r
+               \r
+       /**\r
+        * @return the number of generated columns in this RCL.\r
+        */\r
+       int numGeneratedColumnsForGroupBy()\r
+       {\r
+               int numGenerated = 0;\r
+               int sz = size();\r
+               for (int i = sz - 1; i >= 0; i--) {\r
+                       ResultColumn rc = (ResultColumn) elementAt(i);\r
+                       if (rc.isGenerated() && rc.isGroupingColumn())\r
+                       {\r
+                               numGenerated++;\r
+                       }\r
+               }\r
+               return numGenerated;\r
+       }\r
+       \r
+       /**\r
+        * Remove any generated columns from this RCL.\r
+        */\r
+       void removeGeneratedGroupingColumns()\r
+       {\r
+               int sz = size();\r
+               for (int i = sz - 1; i >= 0; i--) \r
+               {\r
+                       ResultColumn rc = (ResultColumn) elementAt(i);\r
+                       if (rc.isGenerated() && rc.isGroupingColumn()) \r
+                       {\r
+                               removeElementAt(i);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * @return the number of columns that will be visible during execution. \r
+        * During compilation we can add columns for a group by/order by but these\r
+        * to an RCL but these are projected out during query execution. \r
+        */\r
+       public int visibleSize() \r
+       {\r
+               return size() - orderBySelect - numGeneratedColumns();\r
+       }\r
+}\r