📄 updatenode.java
字号:
** set to table. */ if (targetTableDescriptor.getLockGranularity() == TableDescriptor.TABLE_LOCK_GRANULARITY) { lockMode = TransactionController.MODE_TABLE; } return getGenericConstantActionFactory().getUpdateConstantAction ( heapConglomId, targetTableDescriptor.getTableType(), tc.getStaticCompiledConglomInfo(heapConglomId), indicesToMaintain, indexConglomerateNumbers, indexSCOCIs, indexNames, emptyHeapRow, deferred, targetTableDescriptor.getUUID(), lockMode, false, changedColumnIds, null, null, getFKInfo(), getTriggerInfo(), (readColsBitSet == null) ? (FormatableBitSet)null : new FormatableBitSet(readColsBitSet), getReadColMap(targetTableDescriptor.getNumberOfColumns(),readColsBitSet), resultColumnList.getStreamStorableColIds(targetTableDescriptor.getNumberOfColumns()), (readColsBitSet == null) ? targetTableDescriptor.getNumberOfColumns() : readColsBitSet.getNumBitsSet(), positionedUpdate, resultSet.isOneRowResultSet() ); } /** * Updates are deferred if they update a column in the index * used to scan the table being updated. */ protected void setDeferredForUpdateOfIndexColumn() { /* Don't bother checking if we're already deferred */ if (! deferred ) { /* Get the conglomerate descriptor for the target table */ ConglomerateDescriptor updateCD = targetTable. getTrulyTheBestAccessPath(). getConglomerateDescriptor(); /* If it an index? */ if (updateCD != null && updateCD.isIndex()) { int [] baseColumns = updateCD.getIndexDescriptor().baseColumnPositions(); /* Are any of the index columns updated? */ if (resultSet. getResultColumns(). updateOverlaps(baseColumns)) { deferred = true; } } } } /** * Code generation for update. * The generated code will contain: * o A static member for the (xxx)ResultSet with the RowLocations and * new update values * o The static member will be assigned the appropriate ResultSet within * the nested calls to get the ResultSets. (The appropriate cast to the * (xxx)ResultSet will be generated.) * o The CurrentRowLocation() in SelectNode's select list will generate * a new method for returning the RowLocation as well as a call to * that method when generating the (xxx)ResultSet. * * @param acb The ActivationClassBuilder for the class being built * @param mb The method for the execute() method to be built * * * @exception StandardException Thrown on error */ public void generate(ActivationClassBuilder acb, MethodBuilder mb) throws StandardException { //If the DML is on the temporary table, generate the code to mark temporary table as modified in the current UOW generateCodeForTemporaryTable(acb, mb); /* generate the parameters */ if(!isDependentTable) generateParameterValueSet(acb); /* Create the static declaration for the scan ResultSet which generates the * RowLocations to be updated * RESOLVE - Need to deal with the type of the static member. */ acb.newFieldDeclaration(Modifier.PRIVATE, ClassName.CursorResultSet, acb.newRowLocationScanResultSetName()); /* ** Generate the update result set, giving it either the original ** source or the normalize result set, the constant action, ** and "this". */ acb.pushGetResultSetFactoryExpression(mb); resultSet.generate(acb, mb); // arg 1 if( null != targetVTI) { targetVTI.assignCostEstimate(resultSet.getNewCostEstimate()); acb.pushThisAsActivation(mb); // arg 2 mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getUpdateVTIResultSet", ClassName.ResultSet, 2); } else { // generate code to evaluate CHECK CONSTRAINTS generateCheckConstraints( checkConstraints, acb, mb ); // arg 2 acb.pushThisAsActivation(mb); if(isDependentTable) { mb.push(acb.addItem(makeConstantAction())); mb.push(acb.addItem(makeResultDescription())); mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getDeleteCascadeUpdateResultSet", ClassName.ResultSet, 5); }else { mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getUpdateResultSet", ClassName.ResultSet, 3); } } /* ** ensure all parameters have been generated */ if(!isDependentTable) generateParameterHolders(acb); } /** * Return the type of statement, something from * StatementType. * * @return the type of statement */ protected final int getStatementType() { return StatementType.UPDATE; } /** * Gets the map of all columns which must be read out of the base table. * These are the columns needed to<UL>: * <LI>maintain indices</LI> * <LI>maintain foreign keys</LI> * <LI>support Replication's Delta Optimization</LI></UL> * <p> * The returned map is a FormatableBitSet with 1 bit for each column in the * table plus an extra, unsued 0-bit. If a 1-based column id must * be read from the base table, then the corresponding 1-based bit * is turned ON in the returned FormatableBitSet. * <p> * <B>NOTE</B>: this method is not expected to be called when * all columns are being updated (i.e. updateColumnList is null). * * @param dd the data dictionary to look in * @param baseTable the base table descriptor * @param updateColumnList the rcl for the update. CANNOT BE NULL * * @return a FormatableBitSet of columns to be read out of the base table * * @exception StandardException Thrown on error */ public FormatableBitSet getReadMap ( DataDictionary dd, TableDescriptor baseTable, ResultColumnList updateColumnList ) throws StandardException { boolean[] needsDeferredProcessing = new boolean[1]; needsDeferredProcessing[0] = requiresDeferredProcessing(); Vector conglomVector = new Vector(); relevantCdl = new ConstraintDescriptorList(); relevantTriggers = new GenericDescriptorList(); FormatableBitSet columnMap = UpdateNode.getUpdateReadMap(baseTable, updateColumnList, conglomVector, relevantCdl, relevantTriggers, needsDeferredProcessing ); markAffectedIndexes( conglomVector ); adjustDeferredFlag( needsDeferredProcessing[0] ); return columnMap; } /** * Construct the changedColumnIds array. Note we sort its entries by * columnId. */ private int[] getChangedColumnIds(ResultColumnList rcl) { if (rcl == null) { return (int[])null; } else { return rcl.sortMe(); } } /** * Builds a bitmap of all columns which should be read from the * Store in order to satisfy an UPDATE statement. * * Is passed a list of updated columns. Does the following: * * 1) finds all indices which overlap the updated columns * 2) adds the index columns to a bitmap of affected columns * 3) adds the index descriptors to a list of conglomerate * descriptors. * 4) finds all constraints which overlap the updated columns * and adds the constrained columns to the bitmap * 5) finds all triggers which overlap the updated columns. * 6) if there are any triggers, marks all columns in the bitmap * 7) adds the triggers to an evolving list of triggers * * @param updateColumnList a list of updated columns * @param conglomVector OUT: vector of affected indices * @param relevantConstraints IN/OUT. Empty list is passed in. We hang constraints on it as we go. * @param relevantTriggers IN/OUT. Passed in as an empty list. Filled in as we go. * @param needsDeferredProcessing IN/OUT. true if the statement already needs * deferred processing. set while evaluating this * routine if a trigger or constraint requires * deferred processing * * @return a FormatableBitSet of columns to be read out of the base table * * @exception StandardException Thrown on error */ public static FormatableBitSet getUpdateReadMap ( TableDescriptor baseTable, ResultColumnList updateColumnList, Vector conglomVector, ConstraintDescriptorList relevantConstraints, GenericDescriptorList relevantTriggers, boolean[] needsDeferredProcessing ) throws StandardException { if (SanityManager.DEBUG) { SanityManager.ASSERT(updateColumnList != null, "updateColumnList is null"); } int columnCount = baseTable.getMaxColumnID(); FormatableBitSet columnMap = new FormatableBitSet(columnCount + 1); /* ** Add all the changed columns. We don't strictly ** need the before image of the changed column in all cases, ** but it makes life much easier since things are set ** up around the assumption that we have the before ** and after image of the column. */ int[] changedColumnIds = updateColumnList.sortMe(); for (int ix = 0; ix < changedColumnIds.length; ix++) { columnMap.set(changedColumnIds[ix]); } /* ** Get a list of the indexes that need to be ** updated. ColumnMap contains all indexed ** columns where 1 or more columns in the index ** are going to be modified. */ DMLModStatementNode.getXAffectedIndexes(baseTable, updateColumnList, columnMap, conglomVector ); /* ** Add all columns needed for constraints. We don't ** need to bother with foreign key/primary key constraints ** because they are added as a side effect of adding ** their indexes above. */ baseTable.getAllRelevantConstraints ( StatementType.UPDATE, false, changedColumnIds, needsDeferredProcessing, relevantConstraints ); int rclSize = relevantConstraints.size(); for (int index = 0; index < rclSize; index++) { ConstraintDescriptor cd = relevantConstraints.elementAt(index); if (cd.getConstraintType() != DataDictionary.CHECK_CONSTRAINT) { continue; } int[] refColumns = ((CheckConstraintDescriptor)cd).getReferencedColumns(); for (int i = 0; i < refColumns.length; i++) { columnMap.set(refColumns[i]); } } /* ** If we have any triggers, then get all the columns ** because we don't know what the user will ultimately ** reference. */ baseTable.getAllRelevantTriggers( StatementType.UPDATE, changedColumnIds, relevantTriggers ); if ( relevantTriggers.size() > 0 ) { needsDeferredProcessing[0] = true; } if (relevantTriggers.size() > 0) { for (int i = 1; i <= columnCount; i++) { columnMap.set(i); } } return columnMap; }} // end of UpdateNode
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -