Class DatabaseConstraintEnforcer

  • All Implemented Interfaces:
    RowEventListener

    public class DatabaseConstraintEnforcer
    extends java.lang.Object
    implements RowEventListener

    This class enforces all database constraints on the database schema, including NOT NULL constraints, primary key/unique constraints, and foreign key constraints. It also performs the appropriate updates when the target of a foreign-key reference is updated or deleted.

    This class has some interesting design challenges to work around. It must sometimes update rows in other tables, and there may or may not be indexes on the columns being searched and/or updated. The easiest way to do this is to issue nested DML operations against the database. This has multiple benefits. First, the planner can take advantage of indexes if they are present. Second, the nested DML operations will invoke the row-event processing code, which ensures that any constraints on the modified tables will also have their constraints enforced.

    • Field Detail

      • logger

        private static org.apache.logging.log4j.Logger logger
        A logging object for reporting anything interesting that happens.
    • Constructor Detail

      • DatabaseConstraintEnforcer

        public DatabaseConstraintEnforcer​(NanoDBServer server)
    • Method Detail

      • makeErrorMessage

        private java.lang.String makeErrorMessage​(java.lang.String msg,
                                                  java.lang.String constraintName)
        A simple helper method to include the constraint name if we actually know it, or just use the error message if we don't have a named constraint.
      • beforeRowInserted

        public void beforeRowInserted​(TableInfo tableInfo,
                                      Tuple newTuple)
        Perform processing before a row is inserted into a table.
        Specified by:
        beforeRowInserted in interface RowEventListener
        Parameters:
        tableInfo - the table that the tuple will be inserted into.
        newTuple - the new tuple that will be inserted into the table.
      • afterRowInserted

        public void afterRowInserted​(TableInfo tblFileInfo,
                                     Tuple newTuple)
                              throws EventDispatchException
        Perform processing after a row is inserted into a table. For the database constraint enforcer, all the work is done in the before-insert handler.
        Specified by:
        afterRowInserted in interface RowEventListener
        Parameters:
        tblFileInfo - the table that the tuple was inserted into.
        newTuple - the new tuple that was inserted into the table.
        Throws:
        EventDispatchException
      • beforeRowUpdated

        public void beforeRowUpdated​(TableInfo tableInfo,
                                     Tuple oldTuple,
                                     Tuple newTuple)
        Perform processing before a row is updated in a table.
        Specified by:
        beforeRowUpdated in interface RowEventListener
        Parameters:
        tableInfo - the table that the tuple will be updated in.
        oldTuple - the old tuple in the table that is about to be updated.
        newTuple - the new version of the tuple.
      • afterRowUpdated

        public void afterRowUpdated​(TableInfo tableInfo,
                                    Tuple oldTuple,
                                    Tuple newTuple)
        Perform processing after a row is updated in a table.
        Specified by:
        afterRowUpdated in interface RowEventListener
        Parameters:
        tableInfo - the table that the tuple was updated in.
        oldTuple - the old version of the tuple before it was updated.
        newTuple - the new tuple in the table that was updated.
      • beforeRowDeleted

        public void beforeRowDeleted​(TableInfo tableInfo,
                                     Tuple oldTuple)
        Perform processing after a row has been deleted from a table.
        Specified by:
        beforeRowDeleted in interface RowEventListener
        Parameters:
        tableInfo - the table that the tuple will be deleted from.
        oldTuple - the old tuple in the table that is about to be deleted.
      • afterRowDeleted

        public void afterRowDeleted​(TableInfo tableInfo,
                                    Tuple oldTuple)
        Perform processing after a row has been deleted from a table.
        Specified by:
        afterRowDeleted in interface RowEventListener
        Parameters:
        tableInfo - the table that the tuple was deleted from.
        oldTuple - the old values that were in the tuple before it was deleted.
      • checkNotNullConstraints

        private void checkNotNullConstraints​(TableInfo tableInfo,
                                             Tuple tuple)
        This helper function verifies that a tuple being added to a table satisfies all the NOT NULL constraints on the table.
        Parameters:
        tableInfo - the table that the tuple is being added to
        tuple - the tuple being added to the table
        Throws:
        ConstraintViolationException - if the tuple has a NULL value for any not-null columns
      • hasCandidateKeyValue

        private boolean hasCandidateKeyValue​(TableInfo tableInfo,
                                             KeyColumnRefs candidateKey,
                                             Tuple tuple)
        Checks to see if a particular candidate-key value already appears in a table. The method tries to find an index on the specified columns of the table; if there is one, the index is used to look up a matching row. If no index exists, the method scans through the table looking for the specified row.
        Parameters:
        tableInfo - the table to check for the candidate-key value
        candidateKey - a description of the candidate key to examine
        tuple - the tuple containing the candidate-key values
        Returns:
        true if the candidate-key value appears in the table, false otherwise.
      • referencedTableHasValue

        private boolean referencedTableHasValue​(ForeignKeyColumnRefs foreignKey,
                                                Tuple tuple)
        This helper function enforces a foreign key constraint by checking the referenced table to ensure that the tuple being added has values that appear in the referenced table. This constraint enforcement is performed using an index on the referenced table; it is an error if there is no index to perform the check.
        Parameters:
        foreignKey - the foreign key constraint, which specifies both the referencing table's columns and the referenced table's columns
        tuple - the tuple being added to the referencing table
      • applyOnUpdateEffects

        private void applyOnUpdateEffects​(TableInfo tableInfo,
                                          java.lang.String referencingTableName,
                                          Tuple oldTuple,
                                          Tuple newTuple)
                                   throws java.io.IOException
        This function performs ON UPDATE tasks for each referencing table that is potentially affected by the update of a tuple in the referenced table.
        Throws:
        java.io.IOException
      • applyOnDeleteEffects

        private void applyOnDeleteEffects​(TableInfo tableInfo,
                                          java.lang.String referencingTableName,
                                          Tuple oldTuple)
                                   throws java.io.IOException
        This function checks the ON DELETE option for each child table affected by the deletion of tup due to a foreign key, and then executes that option.
        Throws:
        java.io.IOException
      • makeEqualityPredicate

        private Expression makeEqualityPredicate​(Schema schema,
                                                 int[] schemaIndexes,
                                                 Tuple tuple,
                                                 int[] tupleIndexes)
      • makeEqualityComparison

        private CompareOperator makeEqualityComparison​(Schema schema,
                                                       int iSchema,
                                                       Tuple tuple,
                                                       int iTuple)
      • makeExistsPredicate

        private Expression makeExistsPredicate​(TableInfo tableInfo,
                                               int[] schemaIndexes,
                                               Tuple tuple,
                                               int[] tupleIndexes)
      • makeUpdateCommand

        private UpdateCommand makeUpdateCommand​(TableInfo tableInfo,
                                                int[] schemaIndexes,
                                                Tuple oldTuple,
                                                Tuple newTuple,
                                                int[] tupleIndexes)
      • makeDeleteCommand

        private DeleteCommand makeDeleteCommand​(TableInfo tableInfo,
                                                int[] schemaIndexes,
                                                Tuple oldTuple,
                                                int[] tupleIndexes)