📄 deletenode.java
字号:
deferred = true; } } else { deferred = VTIDeferModPolicy.deferIt( DeferModification.DELETE_STATEMENT, targetVTI, null, sel.getWhereClause()); } sel = null; // done with sel /* Verify that all underlying ResultSets reclaimed their FromList */ if (SanityManager.DEBUG) { SanityManager.ASSERT(fromList.size() == 0, "fromList.size() is expected to be 0, not " + fromList.size() + " on return from RS.bindExpressions()"); } //In case of cascade delete , create nodes for //the ref action dependent tables and bind them. if(fkTableNames != null) { String currentTargetTableName = targetTableDescriptor.getSchemaName() + "." + targetTableDescriptor.getName(); if(!isDependentTable){ //graph node graphHashTable = new Hashtable(); } /*Check whether the current tatget is already been explored. *If we are seeing the same table name which we binded earlier *means we have cyclic references. */ if(!graphHashTable.containsKey(currentTargetTableName)) { cascadeDelete = true; int noDependents = fkTableNames.length; dependentNodes = new QueryTreeNode[noDependents]; graphHashTable.put(currentTargetTableName, new Integer(noDependents)); for(int i =0 ; i < noDependents ; i ++) { dependentNodes[i] = getDependentTableNode(fkTableNames[i], fkRefActions[i], fkColDescriptors[i]); dependentNodes[i].bind(); } } }else { //case where current dependent table does not have dependent tables if(isDependentTable) { String currentTargetTableName = targetTableDescriptor.getSchemaName() + "." + targetTableDescriptor.getName(); graphHashTable.put(currentTargetTableName, new Integer(0)); } } 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 delete table is on 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 { /* Different constant actions for base tables and updatable VTIs */ if (targetTableDescriptor != null) { // Base table 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 ** set to table. */ if (targetTableDescriptor.getLockGranularity() == TableDescriptor.TABLE_LOCK_GRANULARITY) { lockMode = TransactionController.MODE_TABLE; } ResultDescription resultDescription = null; if(isDependentTable) { //triggers need the result description , //dependent tables don't have a source from generation time //to get the result description resultDescription = makeResultDescription(); } return getGenericConstantActionFactory().getDeleteConstantAction ( heapConglomId, targetTableDescriptor.getTableType(), tc.getStaticCompiledConglomInfo(heapConglomId), indicesToMaintain, indexConglomerateNumbers, indexSCOCIs, emptyHeapRow, deferred, false, targetTableDescriptor.getUUID(), lockMode, null, null, null, 0, null, null, resultDescription, getFKInfo(), getTriggerInfo(), (readColsBitSet == null) ? (FormatableBitSet)null : new FormatableBitSet(readColsBitSet), getReadColMap(targetTableDescriptor.getNumberOfColumns(),readColsBitSet), resultColumnList.getStreamStorableColIds(targetTableDescriptor.getNumberOfColumns()), (readColsBitSet == null) ? targetTableDescriptor.getNumberOfColumns() : readColsBitSet.getNumBitsSet(), (UUID) null, resultSet.isOneRowResultSet(), dependentConstantActions); } else { /* 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.DELETE_STATEMENT, deferred); } } /** * Code generation for delete. * The generated code will contain: * o A static member for the (xxx)ResultSet with the RowLocations * 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 which will be stuffed in the call to the * ProjectRestrictResultSet. * o In case of referential actions, this function generate an * array of resultsets on its dependent tables. * * @param acb The ActivationClassBuilder for the class being built * @param mb 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); acb.pushGetResultSetFactoryExpression(mb); acb.newRowLocationScanResultSetName(); resultSet.generate(acb, mb); // arg 1 String resultSetGetter; int argCount; String parentResultSetId; // Base table if (targetTableDescriptor != null) { /* Create the declaration for the scan ResultSet which generates the * RowLocations to be deleted. * Note that the field cannot be static because there * can be multiple activations of the same activation class, * and they can't share this field. Only exprN fields can * be shared (or, more generally, read-only fields). * RESOLVE - Need to deal with the type of the field. */ acb.newFieldDeclaration(Modifier.PRIVATE, ClassName.CursorResultSet, acb.getRowLocationScanResultSetName()); if(cascadeDelete || isDependentTable) { resultSetGetter = "getDeleteCascadeResultSet"; } else { resultSetGetter = "getDeleteResultSet"; } argCount = 2; } else { argCount = 2; resultSetGetter = "getDeleteVTIResultSet"; } acb.pushThisAsActivation(mb); if(isDependentTable) { argCount = 3; mb.push(acb.addItem(makeConstantAction())); }else { if(cascadeDelete) { argCount = 3; mb.push(-1); //root table. } } String resultSetArrayType = ClassName.ResultSet + "[]"; if(cascadeDelete) { parentResultSetId = targetTableDescriptor.getSchemaName() + "." + targetTableDescriptor.getName(); // Generate the code to build the array LocalField arrayField = acb.newFieldDeclaration(Modifier.PRIVATE, resultSetArrayType); mb.pushNewArray(ClassName.ResultSet, dependentNodes.length); // new ResultSet[size] mb.setField(arrayField); argCount = 4; for(int index=0 ; index < dependentNodes.length ; index++) { dependentNodes[index].setRefActionInfo(fkIndexConglomNumbers[index], fkColArrays[index], parentResultSetId, true); mb.getField(arrayField); // first arg (resultset array reference) /*beetle:5360 : if too many statements are added to a method, *size of method can hit 65k limit, which will *lead to the class format errors at load time. *To avoid this problem, when number of statements added *to a method is > 2048, remaing statements are added to a new function *and called from the function which created the function. *See Beetle 5135 or 4293 for further details on this type of problem. */ if(mb.statementNumHitLimit(10)) { MethodBuilder dmb = acb.newGeneratedFun(ClassName.ResultSet, Modifier.PRIVATE); dependentNodes[index].generate(acb,dmb); //generates the resultset expression dmb.methodReturn(); dmb.complete(); /* Generate the call to the new method */ mb.pushThis(); //second arg will be generated by this call mb.callMethod(VMOpcode.INVOKEVIRTUAL, (String) null, dmb.getName(), ClassName.ResultSet, 0); }else { dependentNodes[index].generate(acb,mb); //generates the resultset expression } mb.setArrayElement(index); } mb.getField(arrayField); // fourth argument - array reference } else { if(isDependentTable) { argCount =4; mb.pushNull(resultSetArrayType); //No dependent tables for this table } } if(cascadeDelete || isDependentTable) { parentResultSetId = targetTableDescriptor.getSchemaName() + "." + targetTableDescriptor.getName(); argCount = 5; mb.push(parentResultSetId); } mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, resultSetGetter, ClassName.ResultSet, argCount); if(!isDependentTable && cascadeDelete) { int numResultSets = acb.getRowCount(); if(numResultSets > 0) { //generate activation.raParentResultSets = new NoPutResultSet[size] MethodBuilder constructor = acb.getConstructor(); constructor.pushThis(); constructor.pushNewArray(ClassName.CursorResultSet, numResultSets);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -