📄 dmlmodstatementnode.java
字号:
* Get and bind the ResultColumnList representing the columns in the * target table, given a FromTable for the target table. * * @exception StandardException Thrown on error */ private void getResultColumnList(FromBaseTable fromBaseTable, ResultColumnList inputRcl) throws StandardException { if (inputRcl == null) { resultColumnList = fromBaseTable.getAllResultColumns(null); resultColumnList.bindResultColumnsByPosition(targetTableDescriptor); } else { resultColumnList = fromBaseTable.getResultColumnsForList(null, inputRcl, fromBaseTable.getTableNameField()); resultColumnList.bindResultColumnsByName(targetTableDescriptor, this); } } /** * Gets and binds all the constraints for an INSERT/UPDATE/DELETE. * First finds the constraints that are relevant to this node. * This is done by calling getAllRelevantConstriants(). If * getAllRelevantConstraints() has already been called, then * this list is used. Then it creates appropriate * dependencies. Then binds check constraints. It also * generates the array of FKInfo items that are used in * code generation. * Note: we have a new flag here to see if defer processing is enabled or * not, the only scenario that is disabled is when we reapply the * reply message we get from the source * * * @param dataDictionary The DataDictionary * @param nodeFactory Where to get query tree nodes. * @param targetTableDescriptor The TableDescriptor * @param dependent Parent object that will depend on all the constraints * that we look up. If this argument is null, then we * use the default dependent (the statement being compiled). * @param sourceRCL RCL of the table being changed * @param changedColumnIds If null, all columns being changed, otherwise array * of 1-based column ids for columns being changed * @param readColsBitSet bit set for the read scan * @param skipCheckConstraints whether to skip check constraints or not * @param includeTriggers whether triggers are included in the processing * * @return The bound, ANDed check constraints as a query tree. * * @exception StandardException Thrown on failure */ public ValueNode bindConstraints ( DataDictionary dataDictionary, NodeFactory nodeFactory, TableDescriptor targetTableDescriptor, Dependent dependent, ResultColumnList sourceRCL, int[] changedColumnIds, FormatableBitSet readColsBitSet, boolean skipCheckConstraints, boolean includeTriggers ) throws StandardException { bound = true; /* Nothing to do if updatable VTI */ if (targetVTI != null) { return null; } getAllRelevantConstraints(dataDictionary, targetTableDescriptor, skipCheckConstraints, changedColumnIds); createConstraintDependencies(dataDictionary, relevantCdl, dependent); generateFKInfo(relevantCdl, dataDictionary, targetTableDescriptor, readColsBitSet); getAllRelevantTriggers(dataDictionary, targetTableDescriptor, changedColumnIds, includeTriggers); createTriggerDependencies(relevantTriggers, dependent); generateTriggerInfo(relevantTriggers, targetTableDescriptor, changedColumnIds); if (skipCheckConstraints) { return null; } checkConstraints = generateCheckTree(relevantCdl, targetTableDescriptor); if (checkConstraints != null) { bindCheckConstraint(nodeFactory, targetTableDescriptor, sourceRCL, checkConstraints); } return checkConstraints; } /** * Binds an already parsed check constraint * * @param nodeFactory Where to get query tree nodes. * @param targetTableDescriptor The TableDescriptor for the constrained table. * @param resultColumnList Result columns. * @param checkConstraint Parsed query tree for check constraint * * @return The bound check constraint tree. * * @exception StandardException Thrown on failure */ public void bindCheckConstraint ( NodeFactory nodeFactory, TableDescriptor targetTableDescriptor, ResultColumnList sourceRCL, ValueNode checkConstraint ) throws StandardException { TableName targetTableName = makeTableName(targetTableDescriptor.getSchemaName(), targetTableDescriptor.getName()); /* We now have the check constraints as a query tree. Now, we prepare * to bind that query tree to the source's RCL. That way, the * generated code for the check constraints will be evaluated against the * source row to be inserted into the target table or * against the after portion of the source row for the update * into the target table. * o Goober up a new FromList which has a single table, * a goobered up FromBaseTable for the target table * which has the source's RCL as it RCL. * (This allows the ColumnReferences in the check constraint * tree to be bound to the right RCs.) * * Note that in some circumstances we may not actually verify * the constraint against the source RCL but against a temp * row source used for deferred processing because of a trigger. * In this case, the caller of bindConstraints (UpdateNode) * has chosen to pass in the correct RCL to bind against. */ FromList fakeFromList = (FromList) nodeFactory.getNode( C_NodeTypes.FROM_LIST, nodeFactory.doJoinOrderOptimization(), getContextManager()); FromBaseTable table = (FromBaseTable) nodeFactory.getNode( C_NodeTypes.FROM_BASE_TABLE, targetTableName, null, sourceRCL, null, getContextManager()); table.setTableNumber(0); fakeFromList.addFromTable(table); // Now we can do the bind. checkConstraint = checkConstraint.bindExpression( fakeFromList, (SubqueryList) null, (Vector) null); } /** * Determine whether or not there are check constraints on the * specified table. * * @param dd The DataDictionary to use * @param td The TableDescriptor for the table * * @return Whether or not there are check constraints on the specified table. * * @exception StandardException Thrown on failure */ protected boolean hasCheckConstraints(DataDictionary dd, TableDescriptor td) throws StandardException { ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td); if (cdl == null) return false; ConstraintDescriptorList ccCDL = cdl.getSubList(DataDictionary.CHECK_CONSTRAINT); return (ccCDL.size() > 0); } /** * Get the ANDing of all appropriate check constraints as 1 giant query tree. * * Makes the calling object (usually a Statement) dependent on all the constraints. * * @param cdl The constriant descriptor list * @param td The TableDescriptor * * @return The ANDing of all appropriate check constraints as a query tree. * * @exception StandardException Thrown on failure */ private ValueNode generateCheckTree ( ConstraintDescriptorList cdl, TableDescriptor td ) throws StandardException { ConstraintDescriptorList ccCDL = cdl.getSubList(DataDictionary.CHECK_CONSTRAINT); int ccCDLSize = ccCDL.size(); ValueNode checkTree = null; // Get the text of all the check constraints for (int index = 0; index < ccCDLSize; index++) { ConstraintDescriptor cd = ccCDL.elementAt(index); String constraintText = cd.getConstraintText(); // Get the query tree for this constraint ValueNode oneConstraint = parseCheckConstraint(constraintText, td); // Put a TestConstraintNode above the constraint tree TestConstraintNode tcn = (TestConstraintNode) getNodeFactory().getNode( C_NodeTypes.TEST_CONSTRAINT_NODE, oneConstraint, SQLState.LANG_CHECK_CONSTRAINT_VIOLATED, td.getQualifiedName(), cd.getConstraintName(), getContextManager()); // Link consecutive TestConstraintNodes with AND nodes if (checkTree == null) { checkTree = tcn; } else { checkTree = (ValueNode) getNodeFactory().getNode( C_NodeTypes.AND_NODE, tcn, checkTree, getContextManager()); } } return checkTree; } /** * Generate the FKInfo structures used during code generation. * For each constraint that isn't a check constraint, add another * one of these FKInfo structures and then package them up into * a single array. * * @param cdl The constriant descriptor list * @param dd The DataDictionary * @param td The TableDescriptor * @param readColsBitSet columns read * * @exception StandardException Thrown on failure */ private void generateFKInfo ( ConstraintDescriptorList cdl, DataDictionary dd, TableDescriptor td, FormatableBitSet readColsBitSet ) throws StandardException { Vector fkVector = new Vector(10); int type; UUID[] uuids = null; long[] conglomNumbers = null; String[] fkNames = null; ConstraintDescriptorList fkcdl; ReferencedKeyConstraintDescriptor refcd; boolean[] isSelfReferencingFK; ConstraintDescriptorList activeList = dd.getActiveConstraintDescriptors(cdl); int[] rowMap = getRowMap(readColsBitSet, td); int[] raRules = null; Vector refTableNames = new Vector(1); Vector refIndexConglomNum = new Vector(1); Vector refActions = new Vector(1); Vector refColDescriptors = new Vector(1); Vector fkColMap = new Vector(1); int activeSize = activeList.size(); for (int index = 0; index < activeSize; index++) { ConstraintDescriptor cd = activeList.elementAt(index); if (cd instanceof ForeignKeyConstraintDescriptor) { /* ** We are saving information for checking the ** primary/unique key that is referenced by this ** foreign key, so type is FOREIGN KEY. */ type = FKInfo.FOREIGN_KEY; refcd = ((ForeignKeyConstraintDescriptor)cd).getReferencedConstraint(); uuids = new UUID[1]; conglomNumbers = new long[1]; fkNames = new String[1]; isSelfReferencingFK = new boolean[1]; raRules = new int[1]; fkSetupArrays(dd, (ForeignKeyConstraintDescriptor)cd, 0, uuids, conglomNumbers, fkNames, isSelfReferencingFK, raRules); // oops, get the right constraint name -- for error // handling we want the FK name, not refcd name fkNames[0] = cd.getConstraintName(); } else if (cd instanceof ReferencedKeyConstraintDescriptor) { refcd = (ReferencedKeyConstraintDescriptor)cd; /* ** We are saving information for checking the ** foreign key(s) that is dependent on this referenced ** key, so type is REFERENCED KEY. */ type = FKInfo.REFERENCED_KEY; fkcdl = dd.getActiveConstraintDescriptors ( ((ReferencedKeyConstraintDescriptor)cd).getForeignKeyConstraints(ConstraintDescriptor.ENABLED) ); int size = fkcdl.size(); if (size == 0) { continue; } uuids = new UUID[size]; fkNames = new String[size]; conglomNumbers = new long[size]; isSelfReferencingFK = new boolean[size]; raRules = new int[size]; ForeignKeyConstraintDescriptor fkcd = null; TableDescriptor fktd; ColumnDescriptorList coldl; int[] refColumns; ColumnDescriptor cold; int[] colArray = remapReferencedColumns(cd, rowMap); for (int inner = 0; inner < size; inner++) { fkcd = (ForeignKeyConstraintDescriptor) fkcdl.elementAt(inner); fkSetupArrays(dd, fkcd, inner, uuids, conglomNumbers, fkNames, isSelfReferencingFK, raRules); if((raRules[inner] == StatementType.RA_CASCADE) || (raRules[inner] ==StatementType.RA_SETNULL)) { //find the referencing table Name fktd = fkcd.getTableDescriptor(); refTableNames.addElement(fktd.getSchemaName() + "." + fktd.getName()); refActions.addElement(new Integer(raRules[inner])); //find the referencing column name required for update null. refColumns = fkcd.getReferencedColumns(); coldl = fktd.getColumnDescriptorList(); ColumnDescriptorList releventColDes = new ColumnDescriptorList(); for(int i = 0 ; i < refColumns.length; i++) { cold =(ColumnDescriptor)coldl.elementAt(refColumns[i]-1); releventColDes.add(cold); } refColDescriptors.addElement(releventColDes); refIndexConglomNum.addElement(new Long(conglomNumbers[inner])); fkColMap.addElement(colArray); } } } else { continue; } TableDescriptor pktd = refcd.getTableDescriptor(); UUID pkuuid = refcd.getIndexId(); ConglomerateDescriptor pkIndexConglom = pktd.getConglomerateDescriptor(pkuuid);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -