Search in sources :

Example 6 with ConstraintDescriptor

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

the class ModifyColumnNode method checkExistingConstraints.

/**
 * Check if the the column can be modified, and throw error if not.
 *
 * If the type of a column is being changed (for instance if the length
 * of the column is being increased) then make sure that this does not
 * violate any key constraints;
 * the column being altered is
 *   1. part of foreign key constraint
 *         ==> ERROR. This references a Primary Key constraint and the
 *             type and lengths of the pkey/fkey must match exactly.
 *   2. part of a unique/primary key constraint
 *         ==> OK if no fkey references this constraint.
 *         ==> ERROR if any fkey in the system references this constraint.
 *
 * @param td		The Table Descriptor on which the ALTER is being done.
 *
 * @exception StandardException		Thrown on Error.
 */
void checkExistingConstraints(TableDescriptor td) throws StandardException {
    if ((kind != K_MODIFY_COLUMN_TYPE) && (kind != K_MODIFY_COLUMN_CONSTRAINT) && (kind != K_MODIFY_COLUMN_CONSTRAINT_NOT_NULL))
        return;
    DataDictionary dd = getDataDictionary();
    ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td);
    int[] intArray = new int[1];
    intArray[0] = columnPosition;
    for (int index = 0; index < cdl.size(); index++) {
        ConstraintDescriptor existingConstraint = cdl.elementAt(index);
        if (!(existingConstraint instanceof KeyConstraintDescriptor))
            continue;
        if (!existingConstraint.columnIntersects(intArray))
            continue;
        int constraintType = existingConstraint.getConstraintType();
        // and fkey columns.
        if ((constraintType == DataDictionary.FOREIGNKEY_CONSTRAINT) && (kind == K_MODIFY_COLUMN_TYPE)) {
            throw StandardException.newException(SQLState.LANG_MODIFY_COLUMN_FKEY_CONSTRAINT, name, existingConstraint.getConstraintName());
        } else {
            if (!dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_4, null)) {
                // made nullable in soft upgrade mode from a pre-10.4 db.
                if (kind == K_MODIFY_COLUMN_CONSTRAINT && (existingConstraint.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT)) {
                    throw StandardException.newException(SQLState.LANG_MODIFY_COLUMN_EXISTING_CONSTRAINT, name);
                }
            }
            // is being made nullable; can't be done.
            if ((kind == K_MODIFY_COLUMN_CONSTRAINT) && ((existingConstraint.getConstraintType() == DataDictionary.PRIMARYKEY_CONSTRAINT))) {
                String errorState = (getLanguageConnectionContext().getDataDictionary().checkVersion(DataDictionary.DD_VERSION_DERBY_10_4, null)) ? SQLState.LANG_MODIFY_COLUMN_EXISTING_PRIMARY_KEY : SQLState.LANG_MODIFY_COLUMN_EXISTING_CONSTRAINT;
                throw StandardException.newException(errorState, name);
            }
            // unique key or primary key.
            ConstraintDescriptorList refcdl = dd.getForeignKeys(existingConstraint.getUUID());
            if (refcdl.size() > 0) {
                throw StandardException.newException(SQLState.LANG_MODIFY_COLUMN_REFERENCED, name, refcdl.elementAt(0).getConstraintName());
            }
            // Make the statement dependent on the primary key constraint.
            getCompilerContext().createDependency(existingConstraint);
        }
    }
}
Also used : ConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor) KeyConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.KeyConstraintDescriptor) KeyConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.KeyConstraintDescriptor) ConstraintDescriptorList(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary)

Example 7 with ConstraintDescriptor

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

the class RenameNode method renameColumnBind.

// do any checking needs to be done at bind time for rename column
private void renameColumnBind(DataDictionary dd) throws StandardException {
    ColumnDescriptor columnDescriptor = td.getColumnDescriptor(oldObjectName);
    /* Verify that old column name does exist in the table */
    if (columnDescriptor == null)
        throw StandardException.newException(SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE, oldObjectName, getFullName());
    /* Verify that new column name does not exist in the table */
    ColumnDescriptor cd = td.getColumnDescriptor(newObjectName);
    if (cd != null)
        throw descriptorExistsException(cd, td);
    // 
    // You cannot rename a column which is referenced by the generation
    // clause of a generated column.
    // 
    ColumnDescriptorList generatedColumns = td.getGeneratedColumns();
    int generatedColumnCount = generatedColumns.size();
    for (int i = 0; i < generatedColumnCount; i++) {
        ColumnDescriptor gc = generatedColumns.elementAt(i);
        String[] referencedColumns = gc.getDefaultInfo().getReferencedColumnNames();
        int refColCount = referencedColumns.length;
        for (int j = 0; j < refColCount; j++) {
            String refName = referencedColumns[j];
            if (oldObjectName.equals(refName)) {
                throw StandardException.newException(SQLState.LANG_GEN_COL_BAD_RENAME, oldObjectName, gc.getColumnName());
            }
        }
    }
    /* Verify that there are no check constraints using the column being renamed */
    ConstraintDescriptorList constraintDescriptorList = dd.getConstraintDescriptors(td);
    int size = constraintDescriptorList == null ? 0 : constraintDescriptorList.size();
    ConstraintDescriptor constraintDescriptor;
    ColumnDescriptorList checkConstraintCDL;
    int checkConstraintCDLSize;
    // go through all the constraints defined on the table
    for (int index = 0; index < size; index++) {
        constraintDescriptor = constraintDescriptorList.elementAt(index);
        // renamed is not used in it's sql
        if (constraintDescriptor.getConstraintType() == DataDictionary.CHECK_CONSTRAINT) {
            checkConstraintCDL = constraintDescriptor.getColumnDescriptors();
            checkConstraintCDLSize = checkConstraintCDL.size();
            for (int index2 = 0; index2 < checkConstraintCDLSize; index2++) if (checkConstraintCDL.elementAt(index2) == columnDescriptor)
                throw StandardException.newException(SQLState.LANG_RENAME_COLUMN_WILL_BREAK_CHECK_CONSTRAINT, oldObjectName, constraintDescriptor.getConstraintName());
        }
    }
}
Also used : ColumnDescriptorList(org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList) ColumnDescriptor(org.apache.derby.iapi.sql.dictionary.ColumnDescriptor) ConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor) ConstraintDescriptorList(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList)

Example 8 with ConstraintDescriptor

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

the class FromBaseTable method pushIndexName.

/* helper method used by generateMaxSpecialResultSet and
         * generateDistinctScan to return the name of the index if the 
         * conglomerate is an index. 
         * @param cd   Conglomerate for which we need to push the index name
         * @param mb   Associated MethodBuilder
         * @throws StandardException
         */
private void pushIndexName(ConglomerateDescriptor cd, MethodBuilder mb) throws StandardException {
    if (cd.isConstraint()) {
        DataDictionary dd = getDataDictionary();
        ConstraintDescriptor constraintDesc = dd.getConstraintDescriptor(tableDescriptor, cd.getUUID());
        mb.push(constraintDesc.getConstraintName());
    } else if (cd.isIndex()) {
        mb.push(cd.getConglomerateName());
    } else {
        // If the conglomerate is the base table itself, make sure we push
        // null. Before the fix for DERBY-578, we would push the base table
        // name and this was just plain wrong and would cause statistics
        // information to be incorrect.
        mb.pushNull("java.lang.String");
    }
}
Also used : ConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary)

Example 9 with ConstraintDescriptor

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

the class FromBaseTable method verifyProperties.

/**
 * @see org.apache.derby.iapi.sql.compile.Optimizable#verifyProperties
 * @exception StandardException		Thrown on error
 */
@Override
public void verifyProperties(DataDictionary dDictionary) throws StandardException {
    if (tableProperties == null) {
        return;
    }
    /* Check here for:
		 *		invalid properties key
		 *		index and constraint properties
		 *		non-existent index
		 *		non-existent constraint
		 *		invalid joinStrategy
		 *		invalid value for hashInitialCapacity
		 *		invalid value for hashLoadFactor
		 *		invalid value for hashMaxCapacity
		 */
    boolean indexSpecified = false;
    boolean constraintSpecified = false;
    ConstraintDescriptor consDesc = null;
    Enumeration<?> e = tableProperties.keys();
    StringUtil.SQLEqualsIgnoreCase(tableDescriptor.getSchemaName(), "SYS");
    while (e.hasMoreElements()) {
        String key = (String) e.nextElement();
        String value = (String) tableProperties.get(key);
        if (key.equals("index")) {
            // User only allowed to specify 1 of index and constraint, not both
            if (constraintSpecified) {
                throw StandardException.newException(SQLState.LANG_BOTH_FORCE_INDEX_AND_CONSTRAINT_SPECIFIED, getBaseTableName());
            }
            indexSpecified = true;
            /* Validate index name - NULL means table scan */
            if (!StringUtil.SQLToUpperCase(value).equals("NULL")) {
                ConglomerateDescriptor cd = null;
                ConglomerateDescriptor[] cds = tableDescriptor.getConglomerateDescriptors();
                for (int index = 0; index < cds.length; index++) {
                    cd = cds[index];
                    String conglomerateName = cd.getConglomerateName();
                    if (conglomerateName != null) {
                        if (conglomerateName.equals(value)) {
                            break;
                        }
                    }
                    // Not a match, clear cd
                    cd = null;
                }
                // Throw exception if user specified index not found
                if (cd == null) {
                    throw StandardException.newException(SQLState.LANG_INVALID_FORCED_INDEX1, value, getBaseTableName());
                }
                /* Query is dependent on the ConglomerateDescriptor */
                getCompilerContext().createDependency(cd);
            }
        } else if (key.equals("constraint")) {
            // User only allowed to specify 1 of index and constraint, not both
            if (indexSpecified) {
                throw StandardException.newException(SQLState.LANG_BOTH_FORCE_INDEX_AND_CONSTRAINT_SPECIFIED, getBaseTableName());
            }
            constraintSpecified = true;
            if (!StringUtil.SQLToUpperCase(value).equals("NULL")) {
                consDesc = dDictionary.getConstraintDescriptorByName(tableDescriptor, (SchemaDescriptor) null, value, false);
                /* Throw exception if user specified constraint not found
					 * or if it does not have a backing index.
					 */
                if ((consDesc == null) || !consDesc.hasBackingIndex()) {
                    throw StandardException.newException(SQLState.LANG_INVALID_FORCED_INDEX2, value, getBaseTableName());
                }
                /* Query is dependent on the ConstraintDescriptor */
                getCompilerContext().createDependency(consDesc);
            }
        } else if (key.equals("joinStrategy")) {
            userSpecifiedJoinStrategy = StringUtil.SQLToUpperCase(value);
        } else if (key.equals("hashInitialCapacity")) {
            initialCapacity = getIntProperty(value, key);
            // verify that the specified value is valid
            if (initialCapacity <= 0) {
                throw StandardException.newException(SQLState.LANG_INVALID_HASH_INITIAL_CAPACITY, String.valueOf(initialCapacity));
            }
        } else if (key.equals("hashLoadFactor")) {
            try {
                loadFactor = Float.parseFloat(value);
            } catch (NumberFormatException nfe) {
                throw StandardException.newException(SQLState.LANG_INVALID_NUMBER_FORMAT_FOR_OVERRIDE, value, key);
            }
            // verify that the specified value is valid
            if (loadFactor <= 0.0 || loadFactor > 1.0) {
                throw StandardException.newException(SQLState.LANG_INVALID_HASH_LOAD_FACTOR, value);
            }
        } else if (key.equals("hashMaxCapacity")) {
            maxCapacity = getIntProperty(value, key);
            // verify that the specified value is valid
            if (maxCapacity <= 0) {
                throw StandardException.newException(SQLState.LANG_INVALID_HASH_MAX_CAPACITY, String.valueOf(maxCapacity));
            }
        } else if (key.equals("bulkFetch")) {
            bulkFetch = getIntProperty(value, key);
            // verify that the specified value is valid
            if (bulkFetch <= 0) {
                throw StandardException.newException(SQLState.LANG_INVALID_BULK_FETCH_VALUE, String.valueOf(bulkFetch));
            }
            // no bulk fetch on updatable scans
            if (forUpdate()) {
                throw StandardException.newException(SQLState.LANG_INVALID_BULK_FETCH_UPDATEABLE);
            }
        } else if (key.equals("validateCheckConstraint")) {
        // the property "validateCheckConstraint" is read earlier
        // cf. isValidatingCheckConstraint
        } else {
            // No other "legal" values at this time
            throw StandardException.newException(SQLState.LANG_INVALID_FROM_TABLE_PROPERTY, key, "index, constraint, joinStrategy");
        }
    }
    /* If user specified a non-null constraint name(DERBY-1707), then  
		 * replace it in the properties list with the underlying index name to 
		 * simplify the code in the optimizer.
		 * NOTE: The code to get from the constraint name, for a constraint
		 * with a backing index, to the index name is convoluted.  Given
		 * the constraint name, we can get the conglomerate id from the
		 * ConstraintDescriptor.  We then use the conglomerate id to get
		 * the ConglomerateDescriptor from the DataDictionary and, finally,
		 * we get the index name (conglomerate name) from the ConglomerateDescriptor.
		 */
    if (constraintSpecified && consDesc != null) {
        ConglomerateDescriptor cd = dDictionary.getConglomerateDescriptor(consDesc.getConglomerateId());
        String indexName = cd.getConglomerateName();
        tableProperties.remove("constraint");
        tableProperties.put("index", indexName);
    }
}
Also used : ConstraintDescriptor(org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor) ConglomerateDescriptor(org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)

Example 10 with ConstraintDescriptor

use of org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor 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)

Aggregations

ConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor)34 ReferencedKeyConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor)16 ConstraintDescriptorList (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList)15 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)15 ConglomerateDescriptor (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)12 ForeignKeyConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ForeignKeyConstraintDescriptor)12 UUID (org.apache.derby.catalog.UUID)10 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)10 TransactionController (org.apache.derby.iapi.store.access.TransactionController)10 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)9 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)9 TableDescriptor (org.apache.derby.iapi.sql.dictionary.TableDescriptor)9 CheckConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.CheckConstraintDescriptor)8 DependencyManager (org.apache.derby.iapi.sql.depend.DependencyManager)7 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)7 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)7 ColumnDescriptorList (org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList)6 SubCheckConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.SubCheckConstraintDescriptor)5 SubConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.SubConstraintDescriptor)5 SubKeyConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.SubKeyConstraintDescriptor)5