📄 resultsetnode.java
字号:
/* if (defaultInfo.getDefaultValue() != null) { } else */ { // Generate the tree for the default String defaultText = defaultInfo.getDefaultText(); ValueNode defaultTree = parseDefault(defaultText); defaultTree = defaultTree.bindExpression( getFromList(), (SubqueryList) null, (Vector) null); newResultColumn = (ResultColumn) getNodeFactory().getNode( C_NodeTypes.RESULT_COLUMN, defaultTree.getTypeServices(), defaultTree, getContextManager()); DefaultDescriptor defaultDescriptor = colDesc.getDefaultDescriptor(dataDictionary); if (SanityManager.DEBUG) { SanityManager.ASSERT(defaultDescriptor != null, "defaultDescriptor expected to be non-null"); } getCompilerContext().createDependency(defaultDescriptor); } } else if (colDesc.isAutoincrement()) { newResultColumn = (ResultColumn)getNodeFactory().getNode( C_NodeTypes.RESULT_COLUMN, colDesc, null, getContextManager()); newResultColumn.setAutoincrementGenerated(); } else { newResultColumn = (ResultColumn) getNodeFactory().getNode( C_NodeTypes.RESULT_COLUMN, colType, getNullNode( colType.getTypeId(), getContextManager() ), getContextManager() ); } } // Mark the new RC as generated for an unmatched column in an insert newResultColumn.markGeneratedForUnmatchedColumnInInsert(); return newResultColumn; } /** * Parse a default and turn it into a query tree. * * @param defaultText Text of Default. * * @return The parsed default as a query tree. * * @exception StandardException Thrown on failure */ public ValueNode parseDefault ( String defaultText ) throws StandardException { Parser p; ValueNode defaultTree; LanguageConnectionContext lcc = getLanguageConnectionContext(); CompilerContext compilerContext = getCompilerContext(); /* Get a Statement to pass to the parser */ /* We're all set up to parse. We have to build a compilable SQL statement * before we can parse - So, we goober up a VALUES defaultText. */ String values = "VALUES " + defaultText; /* ** Get a new compiler context, so the parsing of the select statement ** doesn't mess up anything in the current context (it could clobber ** the ParameterValueSet, for example). */ CompilerContext newCC = lcc.pushCompilerContext(); p = newCC.getParser(); /* Finally, we can call the parser */ // Since this is always nested inside another SQL statement, so topLevel flag // should be false QueryTreeNode qt = p.parseStatement(values); if (SanityManager.DEBUG) { if (! (qt instanceof CursorNode)) { SanityManager.THROWASSERT( "qt expected to be instanceof CursorNode, not " + qt.getClass().getName()); } CursorNode cn = (CursorNode) qt; if (! (cn.getResultSetNode() instanceof RowResultSetNode)) { SanityManager.THROWASSERT( "cn.getResultSetNode() expected to be instanceof RowResultSetNode, not " + cn.getResultSetNode().getClass().getName()); } } defaultTree = ((ResultColumn) ((CursorNode) qt).getResultSetNode().getResultColumns().elementAt(0)). getExpression(); lcc.popCompilerContext(newCC); return defaultTree; } /** * 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 ResultDescription makeResultDescription() { ExecutionContext ec = (ExecutionContext) getContextManager().getContext( ExecutionContext.CONTEXT_ID); ResultColumnDescriptor[] colDescs = makeResultDescriptors(ec); return ec.getExecutionFactory().getResultDescription(colDescs, null ); } /** Determine if this result set is updatable or not, for a cursor (i.e., is it a cursor-updatable select). This returns false and we expect selectnode to refine it for further checking. * * @exception StandardException Thrown on error */ boolean isUpdatableCursor(DataDictionary dd) throws StandardException { if (SanityManager.DEBUG) SanityManager.DEBUG("DumpUpdateCheck","cursor is not a select result set"); return false; } /** return the target table of an updatable cursor result set. since this is not updatable, just return null. */ FromTable getCursorTargetTable() { return null; } /** Mark this ResultSetNode as the target table of an updatable cursor. Most types of ResultSetNode can't be target tables. @return true if the target table supports positioned updates. */ public boolean markAsCursorTargetTable() { return false; } /** Mark this ResultSetNode as *not* the target table of an updatable cursor. */ void notCursorTargetTable() { cursorTargetTable = false; } /** * Put a ProjectRestrictNode on top of this ResultSetNode. * ColumnReferences must continue to point to the same ResultColumn, so * that ResultColumn must percolate up to the new PRN. However, * that ResultColumn will point to a new expression, a VirtualColumnNode, * which points to the FromTable and the ResultColumn that is the source for * the ColumnReference. * (The new PRN will have the original of the ResultColumnList and * the ResultColumns from that list. The FromTable will get shallow copies * of the ResultColumnList and its ResultColumns. ResultColumn.expression * will remain at the FromTable, with the PRN getting a new * VirtualColumnNode for each ResultColumn.expression.) * * This is useful for UNIONs, where we want to generate a DistinctNode above * the UnionNode to eliminate the duplicates, because DistinctNodes expect * their immediate child to be a PRN. * * @return The generated ProjectRestrictNode atop the original ResultSetNode. * * @exception StandardException Thrown on error */ public ResultSetNode genProjectRestrict() throws StandardException { ResultColumnList prRCList; /* We get a shallow copy of the ResultColumnList and its * ResultColumns. (Copy maintains ResultColumn.expression for now.) */ prRCList = resultColumns; resultColumns = resultColumns.copyListAndObjects(); /* Replace ResultColumn.expression with new VirtualColumnNodes * in the ProjectRestrictNode's ResultColumnList. (VirtualColumnNodes include * pointers to source ResultSetNode, this, and source ResultColumn.) */ prRCList.genVirtualColumnNodes(this, resultColumns); /* Finally, we create the new ProjectRestrictNode */ return (ResultSetNode) getNodeFactory().getNode( C_NodeTypes.PROJECT_RESTRICT_NODE, this, prRCList, null, /* Restriction */ null, /* Restriction as PredicateList */ null, /* Project subquery list */ null, /* Restrict subquery list */ null, getContextManager() ); } /** * Put a ProjectRestrictNode on top of each FromTable in the FromList. * ColumnReferences must continue to point to the same ResultColumn, so * that ResultColumn must percolate up to the new PRN. However, * that ResultColumn will point to a new expression, a VirtualColumnNode, * which points to the FromTable and the ResultColumn that is the source for * the ColumnReference. * (The new PRN will have the original of the ResultColumnList and * the ResultColumns from that list. The FromTable will get shallow copies * of the ResultColumnList and its ResultColumns. ResultColumn.expression * will remain at the FromTable, with the PRN getting a new * VirtualColumnNode for each ResultColumn.expression.) * We then project out the non-referenced columns. If there are no referenced * columns, then the PRN's ResultColumnList will consist of a single ResultColumn * whose expression is 1. * * @param numTables Number of tables in the DML Statement * * @return The generated ProjectRestrictNode atop the original FromTable. * * @exception StandardException Thrown on error */ protected ResultSetNode genProjectRestrict(int numTables) throws StandardException { return genProjectRestrict(); } /** * Put a NormalizeResultSetNode on top of the specified ResultSetNode. * ColumnReferences must continue to point to the same ResultColumn, so * that ResultColumn must percolate up to the new PRN. However, * that ResultColumn will point to a new expression, a VirtualColumnNode, * which points to the FromTable and the ResultColumn that is the source for * the ColumnReference. * (The new NRSN will have the original of the ResultColumnList and * the ResultColumns from that list. The FromTable will get shallow copies * of the ResultColumnList and its ResultColumns. ResultColumn.expression * will remain at the FromTable, with the PRN getting a new * VirtualColumnNode for each ResultColumn.expression.) * * This is useful for UNIONs, where we want to generate a DistinctNode above * the UnionNode to eliminate the duplicates, because the type going into the * sort has to agree with what the sort expects. * (insert into t1 (smallintcol) values 1 union all values 2; * * @param normalizeChild Child result set for new NRSN. * @param forUpdate If the normalize result set is being used as a * child for an update statement, then this is true. * * @return The generated NormalizeResultSetNode atop the original UnionNode. * * @exception StandardException Thrown on error * @see NormalizeResultSetNode#init */ public NormalizeResultSetNode genNormalizeResultSetNode(ResultSetNode normalizeChild, boolean forUpdate) throws StandardException { NormalizeResultSetNode nrsn; ResultColumnList prRCList; /* We get a shallow copy of the ResultColumnList and its * ResultColumns. (Copy maintains ResultColumn.expression for now.) */ prRCList = resultColumns; resultColumns = resultColumns.copyListAndObjects(); /* Replace ResultColumn.expression with new VirtualColumnNodes * in the NormalizeResultSetNode's ResultColumnList. (VirtualColumnNodes include * pointers to source ResultSetNode, this, and source ResultColumn.) */ prRCList.genVirtualColumnNodes(this, resultColumns); /* Finally, we create the new NormalizeResultSetNode */ nrsn = (NormalizeResultSetNode) getNodeFactory().getNode( C_NodeTypes.NORMALIZE_RESULT_SET_NODE, normalizeChild, prRCList, null, new Boolean(forUpdate), getContextManager()); // Propagate the referenced table map if it's already been created if (normalizeChild.getReferencedTableMap() != null) { nrsn.setReferencedTableMap((JBitSet) normalizeChild.getReferencedTableMap().clone()); } return nrsn; } /** * Generate the code for a NormalizeResultSet. The call must push two items before calling this method <OL> <LI> pushGetResultSetFactoryExpression <LI> the expression to normalize </OL> * * @param acb The ActivationClassBuilder * @param mb The method to put the generated code in * @param resultSetNumber The result set number for the NRS * @param resultDescription The ERD for the ResultSet * * * @exception StandardException Thrown on error */ public void generateNormalizationResultSet( ActivationClassBuilder acb, MethodBuilder mb, int resultSetNumber, ResultDescription resultDescription) throws StandardException { int erdNumber = acb.addItem(resultDescription); // instance and first arg are pushed by caller acb.pushThisAsActivation(mb); mb.push(resultSetNumber); mb.push(erdNumber); mb.push(getCostEstimate().rowCount()); mb.push(getCostEstimate().getEstimatedCost()); mb.push(false); closeMethodArgument(acb, mb); mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getNormalizeResultSet", ClassName.NoPutResultSet, 8); } /** * The optimizer's decision on the access path for a result set * may require the generation of extra result sets. For example, * if it chooses an index for a FromBaseTable, we need an IndexToBaseRowNode * above the FromBaseTable (and the FromBaseTable has to change its * column list to match the index. * * This method in the parent class does not generate any extra result sets. * It may be overridden in child classes. * * @return A ResultSetNode tree modified to do any extra processing for * the chosen access path * * @exception StandardException Thrown on error */ public ResultSetNode changeAccessPath() throws StandardException { return this; } /** * Search to see if a query references the specifed table name. * * @param name Table name (String) to search for. * @param baseTable Whether or not name is for a base table * * @return true if found, else false * * @exception StandardException Thrown on error */ public boolean referencesTarget(String name, boolean baseTable)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -