📄 resultcolumnlist.java
字号:
{ ValueNode rcExpr = resultColumn.getExpression(); if (rcExpr == null || ! (rcExpr instanceof ColumnReference)) { continue; } ColumnReference cr = (ColumnReference) rcExpr; if( ! tableName.equals( cr.getTableNameNode())) continue; } /* We finally got past the qualifiers, now see if the column * names are equal. */ if (columnName.equals( resultColumn.getName()) ) { if (retVal == null) { retVal = resultColumn; } else if (index < size - orderBySelect) { throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_FOR_ORDER_BY, columnName); } else {// remove the column due to pullup of orderby item removeElement(resultColumn); decOrderBySelect(); break; } } } return retVal; } /** * Copy the result column names from the given ResultColumnList * to this ResultColumnList. This is useful for insert-select, * where the columns being inserted into may be different from * the columns being selected from. The result column list for * an insert is supposed to have the column names being inserted * into. * * @param nameList The ResultColumnList from which to copy * the column names * * @return Nothing * */ void copyResultColumnNames(ResultColumnList nameList) { /* List checking is done during bind(). Lists should be the * same size when we are called. */ if (SanityManager.DEBUG) { if ((! countMismatchAllowed) && size() != nameList.size()) { SanityManager.THROWASSERT( "The size of the 2 lists is expected to be the same. size() = " + size() + ", nameList.size() = " + nameList.size()); } } int size = (countMismatchAllowed) ? nameList.size() : size(); for (int index = 0; index < size; index++) { ResultColumn thisResultColumn = (ResultColumn) elementAt(index); ResultColumn nameListResultColumn = (ResultColumn) nameList.elementAt(index); thisResultColumn.setName(nameListResultColumn.getName()); thisResultColumn.setNameGenerated(nameListResultColumn.isNameGenerated()); } } /** * This class needs a treePrint method, even though it is not a * descendant of QueryTreeNode, because its members contain tree * nodes, and these have to be printed and indented properly. * * @param depth The depth at which to indent the sub-nodes * * @return Nothing */ public void treePrint(int depth) { if (SanityManager.DEBUG) { for (int index = 0; index < size(); index++) { ((ResultColumn) elementAt(index) ).treePrint(depth); } } } /** * Bind the expressions in this ResultColumnList. This means binding * the expression under each ResultColumn node. * * @param fromList The FROM list for the query this * expression is in, for binding columns. * @param subqueryList The subquery list being built as we find SubqueryNodes * @param aggregateVector The aggregate vector being built as we find AggregateNodes * * @return Nothing * * @exception StandardException Thrown on error */ public void bindExpressions( FromList fromList, SubqueryList subqueryList, Vector aggregateVector) throws StandardException { /* First we expand the *'s in the result column list */ expandAllsAndNameColumns(fromList); /* Now we bind each result column */ int size = size(); for (int index = 0; index < size; index++) { ValueNode vn = (ValueNode) elementAt(index); vn = ((ResultColumn) vn ).bindExpression( fromList, subqueryList, aggregateVector); setElementAt(vn, index); } } /** * Bind the result columns to the expressions that live under them. * All this does is copy the datatype information to from each expression * to each result column. This is useful for SELECT statements, where * the result type of each column is the type of the column's expression. * * @return Nothing * * @exception StandardException Thrown on error */ public void bindResultColumnsToExpressions() throws StandardException { int size = size(); for (int index = 0; index < size; index++) { ((ResultColumn) elementAt(index) ).bindResultColumnToExpression(); } } /** * Bind the result columns by their names. This is useful for update * statements, and for INSERT statements like "insert into t (a, b, c) * values (1, 2, 3)" where the user specified a column list. * Also, verify that the result column list does not contain any duplicates. * NOTE: We pass the ResultColumns position in the ResultColumnList so * that the VirtualColumnId gets set. * * @param tableDescriptor The descriptor for the table being * updated or inserted into * @param statement DMLStatementNode containing this list * * @return Nothing * * @exception StandardException Thrown on error */ public void bindResultColumnsByName(TableDescriptor targetTableDescriptor, DMLStatementNode statement) throws StandardException { int size = size(); Hashtable ht = new Hashtable(size + 2, (float) .999); for (int index = 0; index < size; index++) { ResultColumn rc = (ResultColumn) elementAt(index); /* Verify that this column's name is unique within the list */ String colName = rc.getName(); Object object = ht.put(colName, colName); if (object != null && ((String) object).equals(colName)) { if (SanityManager.DEBUG) { SanityManager.ASSERT((statement instanceof UpdateNode) || (statement instanceof InsertNode), "statement is expected to be instanceof UpdateNode or InsertNode"); } if (statement instanceof UpdateNode) { throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_UPDATE, colName); } else { throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_INSERT, colName); } } rc.bindResultColumnByName( targetTableDescriptor, index + 1 ); } } /** * Bind the result columns by their names. This is useful for update * VTI statements, and for INSERT statements like "insert into new t() (a, b, c) * values (1, 2, 3)" where the user specified a column list. * Also, verify that the result column list does not contain any duplicates. * NOTE: We pass the ResultColumns position in the ResultColumnList so * that the VirtualColumnId gets set. * * @param fullRCL The full RCL for the target table * @param statement DMLStatementNode containing this list * * @return Nothing * * @exception StandardException Thrown on error */ public void bindResultColumnsByName(ResultColumnList fullRCL, FromVTI targetVTI, DMLStatementNode statement) throws StandardException { int size = size(); Hashtable ht = new Hashtable(size + 2, (float) .999); for (int index = 0; index < size; index++) { ResultColumn matchRC; ResultColumn rc = (ResultColumn) elementAt(index); /* Verify that this column's name is unique within the list */ String colName = rc.getName(); Object object = ht.put(colName, colName); if (object != null && ((String) object).equals(colName)) { if (SanityManager.DEBUG) { SanityManager.ASSERT((statement instanceof UpdateNode) || (statement instanceof InsertNode), "statement is expected to be instanceof UpdateNode or InsertNode"); } if (statement instanceof UpdateNode) { throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_UPDATE, colName); } else { throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_INSERT, colName); } } matchRC = fullRCL.getResultColumn(null, rc.getName()); if (matchRC == null) { throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, rc.getName(), targetVTI.getNewInvocation().getJavaClassName()); } /* We have a match. We need to create a dummy ColumnDescriptor * since calling code expects one to get column info. */ ColumnDescriptor cd = new ColumnDescriptor( rc.getName(), matchRC.getVirtualColumnId(), matchRC.getType(), null, null, (TableDescriptor) null, null, 0, 0); rc.setColumnDescriptor(null, cd); rc.setVirtualColumnId(index + 1); } } /** * Bind the result columns by ordinal position. This is useful for * INSERT statements like "insert into t values (1, 2, 3)", where the * user did not specify a column list. * * @param tableDescriptor The descriptor for the table being * inserted into * * @return Nothing * * @exception StandardException Thrown on error */ public void bindResultColumnsByPosition(TableDescriptor targetTableDescriptor) throws StandardException { int size = size(); for (int index = 0; index < size; index++) { /* ** Add one to the iterator index, because iterator indexes start at zero, ** and column numbers start at one. */ ((ResultColumn) elementAt(index) ).bindResultColumnByPosition( targetTableDescriptor, index + 1); } } /** * Preprocess the expression trees under the RCL. * We do a number of transformations * here (including subqueries, IN lists, LIKE and BETWEEN) plus * subquery flattening. * NOTE: This is done before the outer ResultSetNode is preprocessed. * * @param numTables Number of tables in the DML Statement * @param outerFromList FromList from outer query block * @param outerSubqueryList SubqueryList from outer query block * @param outerPredicateList PredicateList from outer query block * * @return Nothing * * @exception StandardException Thrown on error */ public void preprocess(int numTables, FromList outerFromList, SubqueryList outerSubqueryList, PredicateList outerPredicateList) throws StandardException { int size = size(); for (int index = 0; index < size; index++) { ResultColumn resultColumn = (ResultColumn) elementAt(index); setElementAt(resultColumn.preprocess(numTables, outerFromList, outerSubqueryList, outerPredicateList), index); } } /** Verify that all the result columns have expressions that are storable for them. Check versus the given ResultColumnList. @exception StandardException Thrown on error */ void checkStorableExpressions(ResultColumnList toStore) throws StandardException { int size = size(); for (int index = 0; index < size; index++) { ResultColumn otherRC = (ResultColumn) toStore.elementAt(index); ((ResultColumn) elementAt(index) ).checkStorableExpression(otherRC); } } /** Return an array holding the 0 based heap offsets of the StreamStorable columns in this ResultColumnList. This returns null if this list does not contain any StreamStorableColumns. The list this returns does not contain duplicates. This should only be used for a resultColumnList the refers to a single heap such as the target for an Insert, Update or Delete. @param heapColCount the number of heap columns @exception StandardException Thrown on error */ public int[] getStreamStorableColIds(int heapColCount) throws StandardException { //@#$ //System.out.println("getStreamStorableColids"); int ssCount = 0; boolean[] isSS = new boolean[heapColCount];//Should be table length. int size = size(); for (int index = 0; index < size; index++) { ResultColumn rc = (ResultColumn) elementAt(index); if (rc.getTypeId().streamStorable()) { //System.out.println(" streamStorable=true"); ColumnDescriptor cd = rc.getTableColumnDescriptor(); isSS[cd.getPosition()-1] = true; } } for (int ix=0;ix<isSS.length;ix++) if (isSS[ix]) ssCount++; if (ssCount==0)return null; int[] result = new int[ssCount]; int resultOffset=0; for (int heapOffset=0;heapOffset<isSS.length;heapOffset++) { if (isSS[heapOffset]) result[resultOffset++]=heapOffset; } return result; } /** Verify that all the result columns have expressions that are storable for them. Check versus the expressions under the ResultColumns. @exception StandardException Thrown on error */ void checkStorableExpressions() throws StandardException { int size = size(); for (int index = 0; index < size; index++) { ((ResultColumn) elementAt(index) ).checkStorableExpression(); } } /** * Generate the code to place the columns' values into * a row variable named "r". This wrapper is here * rather than in ResultColumn, because that class does * not know about the position of the columns in the list. * * @exception StandardException Thrown on error */ public void generate(ActivationClassBuilder acb, MethodBuilder mb) throws StandardException
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -