📄 tableelementlist.java
字号:
cdn = (ConstraintDefinitionNode) element; if (cdn.getConstraintType() != DataDictionary.CHECK_CONSTRAINT) { continue; } checkTree = cdn.getCheckCondition(); // bind the check condition // verify that it evaluates to a boolean final int previousReliability = cc.getReliability(); try { /* Each check constraint can have its own set of dependencies. * These dependencies need to be shared with the prepared * statement as well. We create a new auxiliary provider list * for the check constraint, "push" it on the compiler context * by swapping it with the current auxiliary provider list * and the "pop" it when we're done by restoring the old * auxiliary provider list. */ ProviderList apl = new ProviderList(); ProviderList prevAPL = cc.getCurrentAuxiliaryProviderList(); cc.setCurrentAuxiliaryProviderList(apl); // Tell the compiler context to only allow deterministic nodes cc.setReliability( CompilerContext.CHECK_CONSTRAINT ); checkTree = checkTree.bindExpression(fromList, (SubqueryList) null, aggregateVector); // no aggregates, please if (aggregateVector.size() != 0) { throw StandardException.newException(SQLState.LANG_INVALID_CHECK_CONSTRAINT, cdn.getConstraintText()); } checkTree = checkTree.checkIsBoolean(); cdn.setCheckCondition(checkTree); /* Save the APL off in the constraint node */ if (apl.size() > 0) { cdn.setAuxiliaryProviderList(apl); } // Restore the previous AuxiliaryProviderList cc.setCurrentAuxiliaryProviderList(prevAPL); } finally { cc.setReliability(previousReliability); } /* We have a valid check constraint, now build an array of * 1-based columnIds that the constraint references. */ ResultColumnList rcl = table.getResultColumns(); int numReferenced = rcl.countReferencedColumns(); int[] checkColumnReferences = new int[numReferenced]; rcl.recordColumnReferences(checkColumnReferences, 1); cdn.setCheckColumnReferences(checkColumnReferences); /* Now we build a list with only the referenced columns and * copy it to the cdn. Thus we can build the array of * column names for the referenced columns during generate(). */ ResultColumnList refRCL = (ResultColumnList) getNodeFactory().getNode( C_NodeTypes.RESULT_COLUMN_LIST, getContextManager()); rcl.copyReferencedColumnsToNewList(refRCL); /* A column check constraint can only refer to that column. If this is a * column constraint, we should have an RCL with that column */ if (cdn.getColumnList() != null) { String colName = ((ResultColumn)(cdn.getColumnList().elementAt(0))).getName(); if (numReferenced > 1 || !colName.equals(((ResultColumn)(refRCL.elementAt(0))).getName())) throw StandardException.newException(SQLState.LANG_DB2_INVALID_CHECK_CONSTRAINT, colName); } cdn.setColumnList(refRCL); /* Clear the column references in the RCL so each check constraint * starts with a clean list. */ rcl.clearColumnReferences(); } } /** * Fill in the ConstraintConstantAction[] for this create/alter table. * * @param conActions The ConstraintConstantAction[] to be filled in. * @param tableName The name of the Table being created. * @param tableSd The schema for that table. * @param dd The DataDictionary * * @exception StandardException Thrown on failure */ void genConstraintActions( ConstraintConstantAction[] conActions, String tableName, SchemaDescriptor tableSd, DataDictionary dd) throws StandardException { int size = size(); int conActionIndex = 0; for (int index = 0; index < size; index++) { String[] columnNames = null; TableElementNode ten = (TableElementNode) elementAt(index); IndexConstantAction indexAction = null; if (! ten.hasConstraint()) { continue; } if (ten instanceof ColumnDefinitionNode) { continue; } ConstraintDefinitionNode constraintDN = (ConstraintDefinitionNode) ten; if (constraintDN.getColumnList() != null) { columnNames = new String[constraintDN.getColumnList().size()]; constraintDN.getColumnList().exportNames(columnNames); } int constraintType = constraintDN.getConstraintType(); String constraintText = constraintDN.getConstraintText(); /* ** If the constraint is not named (e.g. ** create table x (x int primary key)), then ** the constraintSd is the same as the table. */ String constraintName = constraintDN.getConstraintMoniker(); /* At execution time, we will generate a unique name for the backing * index (for CREATE CONSTRAINT) and we will look up the conglomerate * name (for DROP CONSTRAINT). */ if (constraintDN.requiresBackingIndex()) { indexAction = genIndexAction(constraintDN.requiresUniqueIndex(), null, constraintDN, columnNames, true, tableSd, tableName, constraintType, dd); } if (constraintType == DataDictionary.DROP_CONSTRAINT) { conActions[conActionIndex] = getGenericConstantActionFactory(). getDropConstraintConstantAction( constraintName, constraintDN.getDropSchemaName(), /// FiX tableName, td.getUUID(), tableSd.getSchemaName(), indexAction, constraintDN.getDropBehavior(), constraintDN.getVerifyType()); } else { ProviderList apl = constraintDN.getAuxiliaryProviderList(); ConstraintInfo refInfo = null; ProviderInfo[] providerInfos = null; if (constraintDN instanceof FKConstraintDefinitionNode) { refInfo = ((FKConstraintDefinitionNode)constraintDN).getReferencedConstraintInfo(); } /* Create the ProviderInfos, if the constraint is dependent on any Providers */ if (apl != null && apl.size() > 0) { /* Get all the dependencies for the current statement and transfer * them to this view. */ DependencyManager dm = dd.getDependencyManager(); providerInfos = dm.getPersistentProviderInfos(apl); } else { providerInfos = new ProviderInfo[0]; // System.out.println("TABLE ELEMENT LIST EMPTY"); } conActions[conActionIndex++] = getGenericConstantActionFactory(). getCreateConstraintConstantAction( constraintName, constraintType, tableName, ((td != null) ? td.getUUID() : (UUID) null), tableSd.getSchemaName(), columnNames, indexAction, constraintText, true, // enabled refInfo, providerInfos); } } } //check if one array is same as another private boolean columnsMatch(String[] columnNames1, String[] columnNames2) { int srcCount, srcSize, destCount,destSize; boolean match = true; if (columnNames1.length != columnNames2.length) return false; srcSize = columnNames1.length; destSize = columnNames2.length; for (srcCount = 0; srcCount < srcSize; srcCount++) { match = false; for (destCount = 0; destCount < destSize; destCount++) { if (columnNames1[srcCount].equals(columnNames2[destCount])) { match = true; break; } } if (match == false) return false; } return true; } private IndexConstantAction genIndexAction( boolean isUnique, String indexName, ConstraintDefinitionNode cdn, String[] columnNames, boolean isConstraint, SchemaDescriptor sd, String tableName, int constraintType, DataDictionary dd) throws StandardException { if ( indexName == null ) { indexName = cdn.getBackingIndexName(dd); } if (constraintType == DataDictionary.DROP_CONSTRAINT) { return getGenericConstantActionFactory().getDropIndexConstantAction( null, indexName, tableName, sd.getSchemaName(), td.getUUID(), td.getHeapConglomerateId()); } else { boolean[] isAscending = new boolean[columnNames.length]; for (int i = 0; i < isAscending.length; i++) isAscending[i] = true; return getGenericConstantActionFactory().getCreateIndexConstantAction( isUnique, "BTREE", // indexType sd.getSchemaName(), indexName, tableName, ((td != null) ? td.getUUID() : (UUID) null), 0, // conglomId columnNames, isAscending, isConstraint, cdn.getBackingIndexUUID(), cdn.getProperties()); } } /** * Check to make sure that there are no duplicate column names * in the list. (The comparison here is case sensitive. * The work of converting column names that are not quoted * identifiers to upper case is handled by the parser.) * RESOLVE: This check will also be performed by alter table. * * @param ddlStmt DDLStatementNode which contains this list * @param ht Hashtable for enforcing uniqueness. * @param colName Column name to check for. * * @exception StandardException Thrown on error */ private void checkForDuplicateColumns(DDLStatementNode ddlStmt, Hashtable ht, String colName) throws StandardException { Object object = ht.put(colName, colName); if (object != null) { /* RESOLVE - different error messages for create and alter table */ if (ddlStmt instanceof CreateTableNode) { throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_CREATE, colName); } } } /** * Check to make sure that there are no duplicate constraint names * in the list. (The comparison here is case sensitive. * The work of converting column names that are not quoted * identifiers to upper case is handled by the parser.) * RESOLVE: This check will also be performed by alter table. * * @param ddlStmt DDLStatementNode which contains this list * * @exception StandardException Thrown on error */ private void checkForDuplicateConstraintNames(DDLStatementNode ddlStmt, Hashtable ht, String constraintName) throws StandardException { if (constraintName == null) return; Object object = ht.put(constraintName, constraintName); if (object != null) { /* RESOLVE - different error messages for create and alter table */ if (ddlStmt instanceof CreateTableNode) { /* RESOLVE - new error message */ throw StandardException.newException(SQLState.LANG_DUPLICATE_CONSTRAINT_NAME_CREATE, constraintName); } } } /** * Verify that a primary/unique table constraint has a valid column list. * (All columns in table and no duplicates.) * * @param ddlStmt The outer DDLStatementNode * @param cdn The ConstraintDefinitionNode * * @exception StandardException Thrown if the column list is invalid */ private void verifyUniqueColumnList(DDLStatementNode ddlStmt, ConstraintDefinitionNode cdn) throws StandardException { String invalidColName; /* Verify that every column in the list appears in the table's list of columns */ if (ddlStmt instanceof CreateTableNode) { invalidColName = cdn.getColumnList().verifyCreateConstraintColumnList(this); if (invalidColName != null) { throw StandardException.newException(SQLState.LANG_INVALID_CREATE_CONSTRAINT_COLUMN_LIST, ddlStmt.getRelativeName(), invalidColName); } } else { /* RESOLVE - alter table will need to get table descriptor */ } /* Check the uniqueness of the column names within the list */ invalidColName = cdn.getColumnList().verifyUniqueNames(false); if (invalidColName != null) { throw StandardException.newException(SQLState.LANG_DUPLICATE_CONSTRAINT_COLUMN_NAME, invalidColName); } } /** * Set all columns in that appear in a PRIMARY KEY constraint in a CREATE TABLE statement to NOT NULL. * * @param cdn The ConstraintDefinitionNode for a PRIMARY KEY constraint */ private void setColumnListToNotNull(ConstraintDefinitionNode cdn) { ResultColumnList rcl = cdn.getColumnList(); int rclSize = rcl.size(); for (int index = 0; index < rclSize; index++) { String colName = ((ResultColumn) rcl.elementAt(index)).getName(); DataTypeDescriptor dtd = getColumnDataTypeDescriptor(colName); dtd.setNullability(false); } } private void checkForNullColumns(ConstraintDefinitionNode cdn, TableDescriptor td) throws StandardException { ResultColumnList rcl = cdn.getColumnList(); int rclSize = rcl.size(); for (int index = 0; index < rclSize; index++) { String colName = ((ResultColumn) rcl.elementAt(index)).getName(); DataTypeDescriptor dtd; if (td == null) { dtd = getColumnDataTypeDescriptor(colName); } else { dtd = getColumnDataTypeDescriptor(colName, td); } // todo dtd may be null if the column does not exist, we should check that first if (dtd != null && dtd.isNullable()) { throw StandardException.newException(SQLState.LANG_DB2_ADD_UNIQUE_OR_PRIMARY_KEY_ON_NULL_COLS, colName); } } } private DataTypeDescriptor getColumnDataTypeDescriptor(String colName) { int size = size(); for (int index = 0; index < size; index++) { TableElementNode tableElement = (TableElementNode) elementAt(index); if (tableElement instanceof ColumnDefinitionNode) { ColumnDefinitionNode cdn = (ColumnDefinitionNode) tableElement; if (colName.equals(cdn.getColumnName())) { return cdn.getDataTypeServices(); } } } return null; } private DataTypeDescriptor getColumnDataTypeDescriptor(String colName, TableDescriptor td) { // check existing columns ColumnDescriptor cd = td.getColumnDescriptor(colName); if (cd != null) { return cd.getType(); } // check for new columns return getColumnDataTypeDescriptor(colName); } /** * Determine whether or not the parameter matches a column name in this list. * * @param colName The column name to search for. * * @return boolean Whether or not a match is found. */ public boolean containsColumnName(String colName) { int size = size(); for (int index = 0; index < size; index++) { TableElementNode tableElement = (TableElementNode) elementAt(index); if (tableElement instanceof ColumnDefinitionNode) { if (colName.equals(((ColumnDefinitionNode) tableElement).getName())) { return true; } } } return false; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -