Search in sources :

Example 6 with ConstraintDescriptorList

use of org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList in project derby by apache.

the class DMLModStatementNode method generateCheckTree.

/**
 * 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 constraint 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, boolean[] hasDeferrable) throws StandardException {
    ConstraintDescriptorList ccCDL = cdl.getSubList(DataDictionary.CHECK_CONSTRAINT);
    int ccCDLSize = ccCDL.size();
    ValueNode checkTree = null;
    for (ConstraintDescriptor cd : ccCDL) {
        if (cd.deferrable()) {
            hasDeferrable[0] = true;
            break;
        }
    }
    // 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 = new TestConstraintNode(oneConstraint, SQLState.LANG_CHECK_CONSTRAINT_VIOLATED, td.getQualifiedName(), cd, getContextManager());
        // Link consecutive TestConstraintNodes with AND nodes
        if (checkTree == null) {
            checkTree = tcn;
        } else {
            if (hasDeferrable[0]) {
                checkTree = new AndNoShortCircuitNode(tcn, checkTree, getContextManager());
            } else {
                checkTree = new AndNode(tcn, checkTree, getContextManager());
            }
        }
    }
    return checkTree;
}
Also used : ReferencedKeyConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor) ForeignKeyConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.ForeignKeyConstraintDescriptor) ConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor) ConstraintDescriptorList(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList)

Example 7 with ConstraintDescriptorList

use of org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList in project derby by apache.

the class DMLModStatementNode method hasCheckConstraints.

/**
 * 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);
}
Also used : ConstraintDescriptorList(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList)

Example 8 with ConstraintDescriptorList

use of org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList in project derby by apache.

the class DMLModStatementNode method getAllRelevantConstraints.

/**
 * Get all the constraints relevant to this DML operation
 *
 * @param dd				The DataDictionary
 * @param td				The TableDescriptor
 * @param changedColumnIds	If null, all columns being changed, otherwise array
 *							of 1-based column ids for columns being changed
 *
 * @return	the constraint descriptor list
 *
 * @exception StandardException		Thrown on failure
 */
protected ConstraintDescriptorList getAllRelevantConstraints(DataDictionary dd, TableDescriptor td, int[] changedColumnIds) throws StandardException {
    if (relevantCdl != null) {
        return relevantCdl;
    }
    boolean[] needsDeferredProcessing = new boolean[1];
    relevantCdl = new ConstraintDescriptorList();
    needsDeferredProcessing[0] = requiresDeferredProcessing;
    td.getAllRelevantConstraints(statementType, changedColumnIds, needsDeferredProcessing, relevantCdl);
    adjustDeferredFlag(needsDeferredProcessing[0]);
    return relevantCdl;
}
Also used : ConstraintDescriptorList(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList)

Example 9 with ConstraintDescriptorList

use of org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList in project derby by apache.

the class TableElementList method validate.

/**
 * Validate this TableElementList.  This includes checking for
 * duplicate columns names, and checking that user types really exist.
 *
 * @param ddlStmt	DDLStatementNode which contains this list
 * @param dd		DataDictionary to use
 * @param td		TableDescriptor for table, if existing table.
 *
 * @exception StandardException		Thrown on error
 */
void validate(DDLStatementNode ddlStmt, DataDictionary dd, TableDescriptor td) throws StandardException {
    this.td = td;
    int numAutoCols = 0;
    int size = size();
    HashSet<String> columnNames = new HashSet<String>(size + 2, 0.999f);
    HashSet<String> constraintNames = new HashSet<String>(size + 2, 0.999f);
    // all the primary key/unique key constraints for this table
    ArrayList<Object> constraints = new ArrayList<Object>();
    // special case for alter table (td is not null in case of alter table)
    if (td != null) {
        // In case of alter table, get the already existing primary key and unique
        // key constraints for this table. And then we will compare them with  new
        // primary key/unique key constraint column lists.
        ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td);
        ConstraintDescriptor cd;
        if (// table does have some pre-existing constraints defined on it
        cdl != null) {
            for (int i = 0; i < cdl.size(); i++) {
                cd = cdl.elementAt(i);
                // if the constraint type is not primary key or unique key, ignore it.
                if (cd.getConstraintType() == DataDictionary.PRIMARYKEY_CONSTRAINT || cd.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT) {
                    constraints.add(cd);
                }
            }
        }
    }
    int tableType = TableDescriptor.BASE_TABLE_TYPE;
    if (ddlStmt instanceof CreateTableNode)
        tableType = ((CreateTableNode) ddlStmt).tableType;
    for (TableElementNode tableElement : this) {
        if (tableElement instanceof ColumnDefinitionNode) {
            ColumnDefinitionNode cdn = (ColumnDefinitionNode) tableElement;
            if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE && (cdn.getType().getTypeId().isLongConcatableTypeId() || cdn.getType().getTypeId().isUserDefinedTypeId())) {
                throw StandardException.newException(SQLState.LANG_LONG_DATA_TYPE_NOT_ALLOWED, cdn.getColumnName());
            }
            checkForDuplicateColumns(ddlStmt, columnNames, cdn.getColumnName());
            cdn.checkUserType(td);
            cdn.bindAndValidateDefault(dd, td);
            cdn.validateAutoincrement(dd, td, tableType);
            if (tableElement instanceof ModifyColumnNode) {
                ModifyColumnNode mcdn = (ModifyColumnNode) cdn;
                mcdn.checkExistingConstraints(td);
                mcdn.useExistingCollation(td);
            } else if (cdn.isAutoincrementColumn()) {
                numAutoCols++;
            }
        } else if (tableElement.getElementType() == TableElementNode.AT_DROP_COLUMN) {
            String colName = tableElement.getName();
            if (td.getColumnDescriptor(colName) == null) {
                throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, colName, td.getQualifiedName());
            }
            break;
        }
        /* The rest of this method deals with validating constraints */
        if (!(tableElement.hasConstraint())) {
            continue;
        }
        ConstraintDefinitionNode cdn = (ConstraintDefinitionNode) tableElement;
        cdn.bind(ddlStmt, dd);
        // If constraint is primary key or unique key, add it to the list.
        if (cdn.getConstraintType() == DataDictionary.PRIMARYKEY_CONSTRAINT || cdn.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT) {
            /* In case of create table, the list can have only ConstraintDefinitionNode
				* elements. In case of alter table, it can have both ConstraintDefinitionNode
				* (for new constraints) and ConstraintDescriptor(for pre-existing constraints).
				*/
            Object destConstraint;
            String destName = null;
            String[] destColumnNames = null;
            for (int i = 0; i < constraints.size(); i++) {
                destConstraint = constraints.get(i);
                if (destConstraint instanceof ConstraintDefinitionNode) {
                    ConstraintDefinitionNode destCDN = (ConstraintDefinitionNode) destConstraint;
                    destName = destCDN.getConstraintMoniker();
                    destColumnNames = destCDN.getColumnList().getColumnNames();
                } else if (destConstraint instanceof ConstraintDescriptor) {
                    // will come here only for pre-existing constraints in case of alter table
                    ConstraintDescriptor destCD = (ConstraintDescriptor) destConstraint;
                    destName = destCD.getConstraintName();
                    destColumnNames = destCD.getColumnDescriptors().getColumnNames();
                }
                // check if there are multiple constraints with same set of columns
                if (columnsMatch(cdn.getColumnList().getColumnNames(), destColumnNames))
                    throw StandardException.newException(SQLState.LANG_MULTIPLE_CONSTRAINTS_WITH_SAME_COLUMNS, cdn.getConstraintMoniker(), destName);
            }
            constraints.add(cdn);
        }
        /* Make sure that there are no duplicate constraint names in the list */
        checkForDuplicateConstraintNames(ddlStmt, constraintNames, cdn.getConstraintMoniker());
        /* Make sure that the constraint we are trying to drop exists */
        if (cdn.getConstraintType() == DataDictionary.DROP_CONSTRAINT || cdn.getConstraintType() == DataDictionary.MODIFY_CONSTRAINT) {
            /*
				** If no schema descriptor, then must be an invalid
				** schema name.
				*/
            String dropConstraintName = cdn.getConstraintMoniker();
            if (dropConstraintName != null) {
                String dropSchemaName = cdn.getDropSchemaName();
                SchemaDescriptor sd = dropSchemaName == null ? td.getSchemaDescriptor() : getSchemaDescriptor(dropSchemaName);
                ConstraintDescriptor cd = dd.getConstraintDescriptorByName(td, sd, dropConstraintName, false);
                if (cd == null) {
                    throw StandardException.newException(SQLState.LANG_DROP_OR_ALTER_NON_EXISTING_CONSTRAINT, (sd.getSchemaName() + "." + dropConstraintName), td.getQualifiedName());
                }
                /* Statement is dependendent on the ConstraintDescriptor */
                getCompilerContext().createDependency(cd);
            }
        }
        // validation of primary key nullability moved to validatePrimaryKeyNullability().
        if (cdn.hasPrimaryKeyConstraint()) {
            // for PRIMARY KEY, check that columns are unique
            verifyUniqueColumnList(ddlStmt, cdn);
        } else if (cdn.hasUniqueKeyConstraint()) {
            // for UNIQUE, check that columns are unique
            verifyUniqueColumnList(ddlStmt, cdn);
            // disallow until database hard upgraded at least to 10.4.
            if (!dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_4, null)) {
                checkForNullColumns(cdn, td);
            }
        } else if (cdn.hasForeignKeyConstraint()) {
            // for FOREIGN KEY, check that columns are unique
            verifyUniqueColumnList(ddlStmt, cdn);
        }
    }
    // with ALTER TABLE ADD COLUMN.
    if (numAutoCols > 1 || (numAutoCols > 0 && td != null && td.tableHasAutoincrement())) {
        throw StandardException.newException(SQLState.LANG_MULTIPLE_AUTOINCREMENT_COLUMNS);
    }
}
Also used : SchemaDescriptor(org.apache.derby.iapi.sql.dictionary.SchemaDescriptor) ArrayList(java.util.ArrayList) ConstraintDescriptorList(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList) ConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor) HashSet(java.util.HashSet)

Example 10 with ConstraintDescriptorList

use of org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList in project derby by apache.

the class AlterTableConstantAction method modifyColumnConstraint.

/**
 * Workhorse for modifying column level constraints.
 * Right now it is restricted to modifying a null constraint to a not null
 * constraint.
 */
private void modifyColumnConstraint(String colName, boolean nullability) throws StandardException {
    ColumnDescriptor columnDescriptor = td.getColumnDescriptor(colName);
    // Get the type and change the nullability
    DataTypeDescriptor dataType = columnDescriptor.getType().getNullabilityType(nullability);
    // check if there are any unique constraints to update
    ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td);
    int columnPostion = columnDescriptor.getPosition();
    for (int i = 0; i < cdl.size(); i++) {
        ConstraintDescriptor cd = cdl.elementAt(i);
        if (cd.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT) {
            ColumnDescriptorList columns = cd.getColumnDescriptors();
            for (int count = 0; count < columns.size(); count++) {
                if (columns.elementAt(count).getPosition() != columnPostion)
                    break;
                // get backing index
                ConglomerateDescriptor desc = td.getConglomerateDescriptor(cd.getConglomerateId());
                // not null ie is backed by unique index
                if (!(desc.getIndexDescriptor().isUnique() || desc.getIndexDescriptor().hasDeferrableChecking())) {
                    break;
                }
                // replace backing index with a unique when not null index.
                recreateUniqueConstraintBackingIndexAsUniqueWhenNotNull(desc, td, activation, lcc);
            }
        }
    }
    ColumnDescriptor newColumnDescriptor = new ColumnDescriptor(colName, columnDescriptor.getPosition(), dataType, columnDescriptor.getDefaultValue(), columnDescriptor.getDefaultInfo(), td, columnDescriptor.getDefaultUUID(), columnDescriptor.getAutoincStart(), columnDescriptor.getAutoincInc(), columnDescriptor.getAutoincCycle());
    // Update the ColumnDescriptor with new default info
    dd.dropColumnDescriptor(td.getUUID(), colName, tc);
    dd.addDescriptor(newColumnDescriptor, td, DataDictionary.SYSCOLUMNS_CATALOG_NUM, false, tc);
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) ColumnDescriptorList(org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor) CheckConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.CheckConstraintDescriptor) ForeignKeyConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.ForeignKeyConstraintDescriptor) ConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor) ReferencedKeyConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor) ConstraintDescriptorList(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList) ConglomerateDescriptor(org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)

Aggregations

ConstraintDescriptorList (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList)24 ConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor)15 ReferencedKeyConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor)10 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)7 ForeignKeyConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ForeignKeyConstraintDescriptor)7 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)6 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)5 ColumnDescriptorList (org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList)5 TransactionController (org.apache.derby.iapi.store.access.TransactionController)5 ArrayList (java.util.ArrayList)4 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)4 DependencyManager (org.apache.derby.iapi.sql.depend.DependencyManager)4 ConglomerateDescriptor (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)4 TableDescriptor (org.apache.derby.iapi.sql.dictionary.TableDescriptor)4 UUID (org.apache.derby.catalog.UUID)3 CheckConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.CheckConstraintDescriptor)3 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)3 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)3 KeyConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.KeyConstraintDescriptor)2 SubKeyConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.SubKeyConstraintDescriptor)2