📄 deletenode.java
字号:
constructor.putField(ClassName.BaseActivation, "raParentResultSets", ClassName.CursorResultSet + "[]"); constructor.endStatement(); } } /* ** 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.DELETE; } /** * Gets the map of all columns which must be read out of the base table. * These are the columns needed to: * * o maintain indices * o maintain foreign keys * * 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. * * @param dd the data dictionary to look in * @param baseTable the base table descriptor * * @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 ) throws StandardException { boolean[] needsDeferredProcessing = new boolean[1]; needsDeferredProcessing[0] = requiresDeferredProcessing(); Vector conglomVector = new Vector(); relevantTriggers = new GenericDescriptorList(); FormatableBitSet columnMap = DeleteNode.getDeleteReadMap(baseTable, conglomVector, relevantTriggers, needsDeferredProcessing ); markAffectedIndexes( conglomVector ); adjustDeferredFlag( needsDeferredProcessing[0] ); return columnMap; } /** * In case of referential actions, we require to perform * DML (UPDATE or DELETE) on the dependent tables. * Following function returns the DML Node for the dependent table. */ private QueryTreeNode getDependentTableNode(String tableName, int refAction, ColumnDescriptorList cdl) throws StandardException { QueryTreeNode node=null; int index = tableName.indexOf('.'); String schemaName = tableName.substring(0 , index); String tName = tableName.substring(index+1); if(refAction == StatementType.RA_CASCADE) { node = getEmptyDeleteNode(schemaName , tName); ((DeleteNode)node).isDependentTable = true; ((DeleteNode)node).graphHashTable = graphHashTable; } if(refAction == StatementType.RA_SETNULL) { node = getEmptyUpdateNode(schemaName , tName, cdl); ((UpdateNode)node).isDependentTable = true; ((UpdateNode)node).graphHashTable = graphHashTable; } return node; } private QueryTreeNode getEmptyDeleteNode(String schemaName, String targetTableName) throws StandardException { ValueNode whereClause = null; TableName tableName = null; FromTable fromTable = null; QueryTreeNode retval; SelectNode resultSet; tableName = new TableName(); tableName.init(schemaName , targetTableName); NodeFactory nodeFactory = getNodeFactory(); FromList fromList = (FromList) nodeFactory.getNode(C_NodeTypes.FROM_LIST, getContextManager()); fromTable = (FromTable) nodeFactory.getNode( C_NodeTypes.FROM_BASE_TABLE, tableName, null, ReuseFactory.getInteger(FromBaseTable.DELETE), null, getContextManager()); //we would like to use references index & table scan instead of //what optimizer says for the dependent table scan. Properties targetProperties = new FormatableProperties(); targetProperties.put("index", "null"); ((FromBaseTable) fromTable).setTableProperties(targetProperties); fromList.addFromTable(fromTable); resultSet = (SelectNode) nodeFactory.getNode( C_NodeTypes.SELECT_NODE, null, null, /* AGGREGATE list */ fromList, /* FROM list */ whereClause, /* WHERE clause */ null, /* GROUP BY list */ getContextManager()); retval =(QueryTreeNode) nodeFactory.getNode( C_NodeTypes.DELETE_NODE, tableName, resultSet, getContextManager()); return retval; } private QueryTreeNode getEmptyUpdateNode(String schemaName, String targetTableName, ColumnDescriptorList cdl) throws StandardException { ValueNode whereClause = null; TableName tableName = null; FromTable fromTable = null; QueryTreeNode retval; SelectNode resultSet; tableName = new TableName(); tableName.init(schemaName , targetTableName); NodeFactory nodeFactory = getNodeFactory(); FromList fromList = (FromList) nodeFactory.getNode(C_NodeTypes.FROM_LIST, getContextManager()); fromTable = (FromTable) nodeFactory.getNode( C_NodeTypes.FROM_BASE_TABLE, tableName, null, ReuseFactory.getInteger(FromBaseTable.DELETE), null, getContextManager()); //we would like to use references index & table scan instead of //what optimizer says for the dependent table scan. Properties targetProperties = new FormatableProperties(); targetProperties.put("index", "null"); ((FromBaseTable) fromTable).setTableProperties(targetProperties); fromList.addFromTable(fromTable); resultSet = (SelectNode) nodeFactory.getNode( C_NodeTypes.SELECT_NODE, getSetClause(tableName, cdl), null, /* AGGREGATE list */ fromList, /* FROM list */ whereClause, /* WHERE clause */ null, /* GROUP BY list */ getContextManager()); retval =(QueryTreeNode) nodeFactory.getNode( C_NodeTypes.UPDATE_NODE, tableName, resultSet, getContextManager()); return retval; } private ResultColumnList getSetClause(TableName tabName, ColumnDescriptorList cdl) throws StandardException { ResultColumn resultColumn; ValueNode valueNode; NodeFactory nodeFactory = getNodeFactory(); ResultColumnList columnList = (ResultColumnList) nodeFactory.getNode( C_NodeTypes.RESULT_COLUMN_LIST, getContextManager()); valueNode = (ValueNode) nodeFactory.getNode(C_NodeTypes.UNTYPED_NULL_CONSTANT_NODE, getContextManager()); for(int index =0 ; index < cdl.size() ; index++) { ColumnDescriptor cd = (ColumnDescriptor) cdl.elementAt(index); //only columns that are nullable need to be set to 'null' for ON //DELETE SET NULL if((cd.getType()).isNullable()) { resultColumn = (ResultColumn) nodeFactory.getNode( C_NodeTypes.RESULT_COLUMN, cd, valueNode, getContextManager()); columnList.addResultColumn(resultColumn); } } return columnList; } public QueryTreeNode optimize() throws StandardException { if(cascadeDelete) { for(int index=0 ; index < dependentNodes.length ; index++) { dependentNodes[index] = dependentNodes[index].optimize(); } } return super.optimize(); } /** * Builds a bitmap of all columns which should be read from the * Store in order to satisfy an DELETE statement. * * * 1) finds all indices on this table * 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 DELETE triggers on the table * 5) if there are any DELETE triggers, marks all columns in the bitmap * 6) adds the triggers to an evolving list of triggers * * @param conglomVector OUT: vector of affected indices * @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 requires * deferred processing * * @return a FormatableBitSet of columns to be read out of the base table * * @exception StandardException Thrown on error */ private static FormatableBitSet getDeleteReadMap ( TableDescriptor baseTable, Vector conglomVector, GenericDescriptorList relevantTriggers, boolean[] needsDeferredProcessing ) throws StandardException { int columnCount = baseTable.getMaxColumnID(); FormatableBitSet columnMap = new FormatableBitSet(columnCount + 1); /* ** 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. ** ** Notice that we don't need to add constraint ** columns. This is because we add all key constraints ** (e.g. foreign keys) as a side effect of adding their ** indexes above. And we don't need to deal with ** check constraints on a delete. ** ** Adding indexes also takes care of the replication ** requirement of having the primary key. */ DMLModStatementNode.getXAffectedIndexes(baseTable, null, columnMap, conglomVector ); /* ** If we have any triggers, then get all the columns ** because we don't know what the user will ultimately ** reference. */ baseTable.getAllRelevantTriggers( StatementType.DELETE, (int[])null, relevantTriggers ); if ( relevantTriggers.size() > 0 ) { needsDeferredProcessing[0] = true; } if (relevantTriggers.size() > 0) { for (int i = 1; i <= columnCount; i++) { columnMap.set(i); } } return columnMap; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -