📄 resultcolumnlist.java
字号:
// If there is a bit map of referenced columns, use it to // figure out what the next column is, otherwise just go // to the next column. if (referencedCols != null) colNum = referencedCols.anySetBit(colNum); else colNum++; } // generate: // return fieldX; // and add to the end of exprFun's body. exprFun.getField(lf); exprFun.methodReturn(); // we are done putting stuff in exprFun: exprFun.complete(); return exprFun; } /** * Generate the code to create an empty row in the constructor. * * @param acb The ACB. * @param field The field for the new row. * @param rowAllocatorMethod The method to call. * @param rowAllocatorType The row type. * @param numCols The number of columns in the row. * * @return Nothing. * * @exception StandardException Thrown on error */ private void genCreateRow(ExpressionClassBuilder acb, LocalField field, String rowAllocatorMethod, String rowAllocatorType, int numCols) throws StandardException { // Create the row in the constructor // fieldX = getExecutionFactory().getValueRow(# cols); MethodBuilder cb = acb.getConstructor(); acb.pushGetExecutionFactoryExpression(cb); // instance cb.push(numCols); cb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, rowAllocatorMethod, rowAllocatorType, 1); cb.setField(field); /* Increase the statement counter in constructor. Code size in * constructor can become too big (more than 64K) for Java compiler * to handle (beetle 4293). We set constant columns in other * methods if constructor has too many statements already. */ cb.statementNumHitLimit(1); // ignore return value } /** * Make a ResultDescription for use in a ResultSet. * This is useful when generating/executing a NormalizeResultSet, since * it can appear anywhere in the tree. * * @return A ResultDescription for this ResultSetNode. */ public ResultColumnDescriptor[] makeResultDescriptors() { ExecutionContext ec = (ExecutionContext) getContextManager().getContext( ExecutionContext.CONTEXT_ID); return makeResultDescriptors(ec); } ResultColumnDescriptor[] makeResultDescriptors(ExecutionContext ec) { ResultColumnDescriptor colDescs[] = new ResultColumnDescriptor[size()]; int size = size(); for (int index = 0; index < size; index++) { // the ResultColumn nodes are descriptors, so take 'em... colDescs[index] = ec.getExecutionFactory().getResultColumnDescriptor(((ResultColumnDescriptor) elementAt(index))); } return colDescs; } /** * Expand any *'s in the ResultColumnList. In addition, we will guarantee that * each ResultColumn has a name. (All generated names will be unique across the * entire statement.) * * @param compilerContext The CompilerContext to use. * * @return None. * * @exception StandardException Thrown on error */ public void expandAllsAndNameColumns(FromList fromList) throws StandardException { boolean expanded = false; ResultColumnList allExpansion; TableName fullTableName; /* First walk result column list looking for *'s to expand */ for (int index = 0; index < size(); index++) { ResultColumn rc = (ResultColumn) elementAt(index); if (rc instanceof AllResultColumn) { expanded = true; //fullTableName = ((AllResultColumn) rc).getFullTableName(); TableName temp = rc.getTableNameObject(); if(temp != null) { String sName = temp.getSchemaName(); String tName = temp.getTableName(); fullTableName = makeTableName(sName,tName); } else fullTableName = null; allExpansion = fromList.expandAll(fullTableName); /* Make sure that every column has a name */ allExpansion.nameAllResultColumns(); /* Make sure that every RC and expression is marked as being in * the SELECT list. */ allExpansion.setClause(ValueNode.IN_SELECT_LIST); /* Replace the AllResultColumn with the expanded list. * We will update the VirtualColumnIds once below. */ removeElementAt(index); for (int inner = 0; inner < allExpansion.size(); inner++) { insertElementAt(allExpansion.elementAt(inner), index + inner); } // If the rc was a "*", we need to set the initial list size // to the number of columns that are actually returned to // the user. markInitialSize(); } else { /* Make sure that every column has a name */ rc.guaranteeColumnName(); } } /* Go back and update the VirtualColumnIds if we expanded any *'s */ if (expanded) { int size = size(); for (int index = 0; index < size; index++) { /* Vectors are 0-based, VirtualColumnIds are 1-based. */ ((ResultColumn) elementAt(index)).setVirtualColumnId(index + 1); } } } /** * Generate (unique across the entire statement) column names for those * ResultColumns in this list which are not named. * * @return None. * * @exception StandardException Thrown on error */ public void nameAllResultColumns() throws StandardException { int size = size(); for (int index = 0; index < size; index++) { ResultColumn resultColumn = (ResultColumn) elementAt(index); resultColumn.guaranteeColumnName(); } } /** * Copy the types and lengths for this RCL (the target) * to another RCL (the source). * This is useful when adding a NormalizeResultSetNode. * * @param sourcRCL The source RCL * * @return Nothing. */ public void copyTypesAndLengthsToSource(ResultColumnList sourceRCL) { /* Source and target can have different lengths. */ int size = (size() > sourceRCL.size()) ? size() : sourceRCL.size(); for (int index = 0; index < size; index++) { ResultColumn sourceRC = (ResultColumn) sourceRCL.elementAt(index); ResultColumn resultColumn = (ResultColumn) elementAt(index); sourceRC.setType(resultColumn.getTypeServices()); sourceRC.getExpression().setType(resultColumn.getTypeServices()); } } /* ** Check whether the column lengths and types of the result columns ** match the expressions under those columns. This is useful for ** INSERT and UPDATE statements. For SELECT statements this method ** should always return true. There is no need to call this for a ** DELETE statement. ** NOTE: We skip over generated columns since they won't have a ** column descriptor. ** ** @return true means all the columns match their expressions, ** false means at least one column does not match its ** expression */ boolean columnTypesAndLengthsMatch() throws StandardException { int size = size(); for (int index = 0; index < size; index++) { ResultColumn resultColumn = (ResultColumn) elementAt(index); /* Skip over generated columns */ if (resultColumn.isGenerated()) { continue; } if (! resultColumn.columnTypeAndLengthMatch()) return false; } return true; } boolean columnTypesAndLengthsMatch(ResultColumnList otherRCL) throws StandardException { boolean retval = true; /* We check every RC, even after finding 1 that requires * normalization, because the conversion of constants to * the appropriate type occurs under this loop. */ int size = size(); for (int index = 0; index < size; index++) { ResultColumn resultColumn = (ResultColumn) elementAt(index); ResultColumn otherResultColumn = (ResultColumn) otherRCL.elementAt(index); /* Skip over generated columns */ if (resultColumn.isGenerated() || otherResultColumn.isGenerated()) { continue; } if (! resultColumn.columnTypeAndLengthMatch(otherResultColumn)) { retval = false; } } return retval; } /** * Determine whether this RCL is a No-Op projection of the given RCL. * It only makes sense to do this if the given RCL is from the child * result set of the ProjectRestrict that this RCL is from. * * @param childRCL The ResultColumnList of the child result set. * * @return true if this RCL is a No-Op projection of the given RCL. */ public boolean nopProjection(ResultColumnList childRCL) { /* ** This RCL is a useless projection if each column in the child ** if the same as the column in this RCL. This is impossible ** if the two RCLs have different numbers of columns. */ if (this.size() != childRCL.size()) { return false; } /* ** The two lists have the same numbers of elements. Are the lists ** identical? In other words, is the expression in every ResultColumn ** in the PRN's RCL a ColumnReference that points to the corresponding ** column in the child? */ int size = size(); for (int index = 0; index < size; index++) { ResultColumn thisColumn = (ResultColumn) elementAt(index); ResultColumn referencedColumn = null; /* ** A No-Op projection can point to a VirtualColumnNode or a ** ColumnReference. */ if (thisColumn.getExpression() instanceof VirtualColumnNode) { referencedColumn = ((VirtualColumnNode) (thisColumn.getExpression())). getSourceColumn(); } else if (thisColumn.getExpression() instanceof ColumnReference) { referencedColumn = ((ColumnReference) (thisColumn.getExpression())). getSource(); } else { return false; } ResultColumn childColumn = (ResultColumn) childRCL.elementAt(index); if (referencedColumn != childColumn) { return false; } } return true; } /** * Create a shallow copy of a ResultColumnList and its ResultColumns. * (All other pointers are preserved.) * Useful for building new ResultSetNodes during preprocessing. * * @return None. * * @exception StandardException Thrown on error */ public ResultColumnList copyListAndObjects() throws StandardException { ResultColumn newResultColumn; ResultColumn origResultColumn; ResultColumnList newList; /* Create the new ResultColumnList */ newList = (ResultColumnList) getNodeFactory().getNode( C_NodeTypes.RESULT_COLUMN_LIST, getContextManager()); /* Walk the current list - for each ResultColumn in the list, make a copy * and add it to the new list. */ int size = size(); for (int index = 0; index < size; index++) { origResultColumn = (ResultColumn) elementAt(index); newResultColumn = origResultColumn.cloneMe(); newList.addResultColumn(newResultColumn); } return newList; } /** * Walk the list and replace ResultColumn.expression with a new * VirtualColumnNode. This is useful when propagating a ResultColumnList * up the query tree. * NOTE: This flavor marks all of the underlying RCs as referenced. * * @param sourceResultSet ResultSetNode that is source of value * @param sourceResultColumn ResultColumn that is source of value * * @return None. * * @exception StandardException Thrown on error */ public void genVirtualColumnNodes(ResultSetNode sourceResultSet, ResultColumnList sourceResultColumnList) throws StandardException { genVirtualColumnNodes(sourceResultSet, sourceResultColumnList, true); } /** * Walk the list and replace ResultColumn.expression with a new * VirtualColumnNode. This is useful when propagating a ResultColumnList * up the query tree. * * @param sourceResultSet ResultSetNode that is source of value * @param sourceResultColumn ResultColumn that is source of value * @param markReferenced Whether or not to mark the underlying RCs * as referenced * * @return None. * * @exception StandardException Thrown on error */ public void genVirtualColumnNodes(ResultSetNode sourceResultSet, ResultColumnList sourceResultColumnList, boolean markReferenced) throws StandardException { int size = size(); for (int index = 0; index < size; index++) { ResultColumn resultColumn = (ResultColumn) elementAt(index); /* dts = resultColumn.getExpression().getTypeServices(); */ DataTypeDescriptor dts = resultColumn.getTypeServices(); /* Vectors are 0-based, VirtualColumnIds are 1-based */ resultColumn.expression = (ValueNode) getNodeFactory().getNode( C_NodeTypes.VIRTUAL_COLUMN_NODE, sourceResultSet, sourceResultColumnList.elementAt(index), ReuseFactory.getInteger(index + 1), getContextManager()); /* Mark the ResultColumn as being referenced */ if (markReferenced) { resultColumn.setReferenced();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -