📄 updatenode.java
字号:
*/ resultFromList = resultSet.getFromList(); if (SanityManager.DEBUG) SanityManager.ASSERT(resultFromList.size() == 1, "More than one table in result from list in an update."); /* Bind the original result columns by column name */ resultSet.bindResultColumns(targetTableDescriptor, targetVTI, resultSet.resultColumns, this, fromList); LanguageConnectionContext lcc = getLanguageConnectionContext(); if (lcc.getAutoincrementUpdate() == false) resultSet.getResultColumns().checkAutoincrement(null); /* ** Mark the columns in this UpdateNode's result column list as ** updateable in the ResultColumnList of the table being updated. ** only do this for FromBaseTables - if the result table is a ** CurrentOfNode, it already knows what columns in its cursor ** are updateable. */ boolean allColumns = false; if (targetTable instanceof FromBaseTable) { ((FromBaseTable) targetTable).markUpdated( resultSet.getResultColumns()); } else if (targetTable instanceof FromVTI) { resultColumnList = resultSet.getResultColumns(); } else { /* ** Positioned update: WHERE CURRENT OF */ if (SanityManager.DEBUG) { SanityManager.ASSERT(currentOfNode != null, "currentOfNode is null"); } ExecPreparedStatement cursorStmt = currentOfNode.getCursorStatement(); String[] ucl = cursorStmt.getUpdateColumns(); /* ** If there is no update column list, we need to build ** out the result column list to have all columns. */ if (ucl == null || (ucl.length == 0)) { /* ** Get the resultColumnList representing ALL of the columns in the ** base table. This is the "before" portion of the result row. */ getResultColumnList(); /* ** Add the "after" portion of the result row. This is the update ** list augmented to include every column in the target table. ** Those columns that are not being updated are set to themselves. ** The expanded list will be in the order of the columns in the base ** table. */ afterColumns = resultSet.getResultColumns().expandToAll( targetTableDescriptor, targetTable.getTableName()); /* ** Need to get all indexes here since we aren't calling ** getReadMap(). */ getAffectedIndexes(targetTableDescriptor, (ResultColumnList)null, (FormatableBitSet)null); allColumns = true; } else { /* Check the updatability */ resultSet.getResultColumns().checkColumnUpdateability(ucl, currentOfNode.getCursorName()); } } changedColumnIds = getChangedColumnIds(resultSet.getResultColumns()); /* ** We need to add in all the columns that are needed ** by the constraints on this table. */ if (!allColumns && targetVTI == null) { readColsBitSet = new FormatableBitSet(); FromBaseTable fbt = getResultColumnList(resultSet.getResultColumns()); afterColumns = resultSet.getResultColumns().copyListAndObjects(); readColsBitSet = getReadMap(dataDictionary, targetTableDescriptor, afterColumns); afterColumns = fbt.addColsToList(afterColumns, readColsBitSet); resultColumnList = fbt.addColsToList(resultColumnList, readColsBitSet); /* ** If all bits are set, then behave as if we chose all ** in the first place */ int i = 1; int size = targetTableDescriptor.getMaxColumnID(); for (; i <= size; i++) { if (!readColsBitSet.get(i)) { break; } } if (i > size) { readColsBitSet = null; allColumns = true; } } if (targetVTI == null) { /* ** Construct an empty heap row for use in our constant action. */ emptyHeapRow = targetTableDescriptor.getEmptyExecRow(getContextManager()); /* Append the list of "after" columns to the list of "before" columns, * preserving the afterColumns list. (Necessary for binding * check constraints.) */ resultColumnList.appendResultColumns(afterColumns, false); /* Generate the RowLocation column */ rowLocationNode = (CurrentRowLocationNode) getNodeFactory().getNode( C_NodeTypes.CURRENT_ROW_LOCATION_NODE, getContextManager()); } else { rowLocationNode = (NumericConstantNode) getNodeFactory().getNode( C_NodeTypes.INT_CONSTANT_NODE, ReuseFactory.getInteger( 0), getContextManager()); } rowLocationColumn = (ResultColumn) getNodeFactory().getNode( C_NodeTypes.RESULT_COLUMN, COLUMNNAME, rowLocationNode, getContextManager()); rowLocationColumn.markGenerated(); /* Append to the ResultColumnList */ resultColumnList.addResultColumn(rowLocationColumn); /* The last thing that we do to the generated RCL is to clear * the table name out from each RC. The table name is * unnecessary for an update. More importantly, though, it * creates a problem in the degenerate case with a positioned * update. The user must specify the base table name for a * positioned update. If a correlation name was specified for * the cursor, then a match for the ColumnReference would not * be found if we didn't null out the name. (Aren't you * glad you asked?) */ resultColumnList.clearTableNames(); /* Set the new result column list in the result set */ resultSet.setResultColumns(resultColumnList); /* Bind the expressions */ super.bindExpressions(); /* Bind untyped nulls directly under the result columns */ resultSet. getResultColumns(). bindUntypedNullsToResultColumns(resultColumnList); if (null != rowLocationColumn) { /* Bind the new ResultColumn */ rowLocationColumn.bindResultColumnToExpression(); } resultColumnList.checkStorableExpressions(); /* Insert a NormalizeResultSetNode above the source if the source * and target column types and lengths do not match. */ if (! resultColumnList.columnTypesAndLengthsMatch()) { resultSet = resultSet.genNormalizeResultSetNode(resultSet, true); resultColumnList.copyTypesAndLengthsToSource(resultSet.getResultColumns()); if (hasCheckConstraints(dataDictionary, targetTableDescriptor)) { /* Get and bind all check constraints on the columns * being updated. We want to bind the check constraints against * the after columns. We need to bind against the portion of the * resultColumns in the new NormalizeResultSet that point to * afterColumns. Create an RCL composed of just those RCs in * order to bind the check constraints. */ int afterColumnsSize = afterColumns.size(); afterColumns = (ResultColumnList) getNodeFactory().getNode( C_NodeTypes.RESULT_COLUMN_LIST, getContextManager()); ResultColumnList normalizedRCs = resultSet.getResultColumns(); for (int index = 0; index < afterColumnsSize; index++) { afterColumns.addElement(normalizedRCs.elementAt(index + afterColumnsSize)); } } } if( null != targetVTI) { deferred = VTIDeferModPolicy.deferIt( DeferModification.UPDATE_STATEMENT, targetVTI, resultColumnList.getColumnNames(), sel.getWhereClause()); } else // not VTI { /* we always include triggers in core language */ boolean hasTriggers = (getAllRelevantTriggers(dataDictionary, targetTableDescriptor, changedColumnIds, true).size() > 0); /* Get and bind all constraints on the columns being updated */ checkConstraints = bindConstraints( dataDictionary, getNodeFactory(), targetTableDescriptor, null, hasTriggers ? resultColumnList : afterColumns, changedColumnIds, readColsBitSet, false, true); /* we always include triggers in core language */ /* If the target table is also a source table, then * the update will have to be in deferred mode * For updates, this means that the target table appears in a * subquery. Also, self referencing foreign keys are * deferred. And triggers cause an update to be deferred. */ if (resultSet.subqueryReferencesTarget( targetTableDescriptor.getName(), true) || requiresDeferredProcessing()) { deferred = true; } } return this; } // end of bind() /** * Return true if the node references SESSION schema tables (temporary or permanent) * * @return true if references SESSION schema tables, else false * * @exception StandardException Thrown on error */ public boolean referencesSessionSchema() throws StandardException { //If this node references a SESSION schema table, then return true. return(resultSet.referencesSessionSchema()); } /** * Compile constants that Execution will use * * @exception StandardException Thrown on failure */ public ConstantAction makeConstantAction() throws StandardException { /* ** Updates are also deferred if they update a column in the index ** used to scan the table being updated. */ if (! deferred ) { ConglomerateDescriptor updateCD = targetTable. getTrulyTheBestAccessPath(). getConglomerateDescriptor(); if (updateCD != null && updateCD.isIndex()) { int [] baseColumns = updateCD.getIndexDescriptor().baseColumnPositions(); if (resultSet. getResultColumns(). updateOverlaps(baseColumns)) { deferred = true; } } } if( null == targetTableDescriptor) { /* Return constant action for VTI * NOTE: ConstantAction responsible for preserving instantiated * VTIs for in-memory queries and for only preserving VTIs * that implement Serializable for SPSs. */ return getGenericConstantActionFactory().getUpdatableVTIConstantAction( DeferModification.UPDATE_STATEMENT, deferred, changedColumnIds); } int lockMode = resultSet.updateTargetLockMode(); long heapConglomId = targetTableDescriptor.getHeapConglomerateId(); TransactionController tc = getLanguageConnectionContext().getTransactionCompile(); StaticCompiledOpenConglomInfo[] indexSCOCIs = new StaticCompiledOpenConglomInfo[indexConglomerateNumbers.length]; for (int index = 0; index < indexSCOCIs.length; index++) { indexSCOCIs[index] = tc.getStaticCompiledConglomInfo(indexConglomerateNumbers[index]); } /* ** Do table locking if the table's lock granularity is
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -