Class Schema

  • All Implemented Interfaces:
    java.io.Serializable, java.lang.Iterable<ColumnInfo>

    public class Schema
    extends java.lang.Object
    implements java.io.Serializable, java.lang.Iterable<ColumnInfo>

    A schema is an ordered collection of column names and associated types.

    Many different entities in the database code can have schema associated with them. Both tables and tuples have schemas, for obvious reasons. SELECT and FROM clauses also have schemas, used by the database engine to verify the semantics of database queries. Finally, relational algebra plan nodes also have schemas, which specify the kinds of tuples that they generate.

    See Also:
    Serialized Form
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      private static class  Schema.IndexedColumnInfo
      This helper class is used for the internal hashed column structure, so that we can do fast lookups based on table names and column names.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private java.util.ArrayList<KeyColumnRefs> candidateKeys
      A collection of all candidate-key objects specifying the sets of columns that comprise candidate keys on this table.
      private java.util.HashMap<java.lang.String,​java.util.ArrayList<Schema.IndexedColumnInfo>> colsHashedByColumn
      A mapping that provides fast lookups for columns based only on column name.
      private java.util.HashMap<java.lang.String,​java.util.HashMap<java.lang.String,​Schema.IndexedColumnInfo>> colsHashedByTable
      A mapping that provides fast lookups for columns based on table name and column name.
      private java.util.ArrayList<ColumnInfo> columnInfos
      The collection of the column-info objects describing the columns in the schema.
      private java.util.ArrayList<ForeignKeyColumnRefs> foreignKeys
      A collection of foreign-key objects specifying other tables that this table references.
      private java.util.HashMap<java.lang.String,​IndexColumnRefs> indexes
      This collection provides easy access to all the indexes defined on this table, including those for candidate keys and the primary key.
      private java.util.HashSet<java.lang.Integer> notNullCols
      A set recording the indexes of the columns have NOT NULL constraints on them.
      private java.util.HashSet<java.lang.String> referencingTables
      A set of the tables that reference this table.
    • Constructor Summary

      Constructors 
      Constructor Description
      Schema()
      Construct an empty schema.
      Schema​(ColumnInfo... colInfos)
      Construct a schema containing the specified array of column-info objects.
      Schema​(Schema... schemas)
      Create a schema that is the concatenation of one or more other schemas.
      Schema​(java.lang.Iterable<ColumnInfo> colInfos)
      Construct a schema whose columns are taken from the specified iterable.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void addCandidateKey​(KeyColumnRefs ck)
      Adds another candidate key to the schema.
      int addColumnInfo​(ColumnInfo colInfo)
      Add a column to the schema.
      void addForeignKey​(ForeignKeyColumnRefs fk)  
      void addIndex​(IndexColumnRefs index)  
      boolean addNotNull​(int colIndex)
      Adds a column with given index to list of NOT NULL constrained columns.
      boolean addReferencingTable​(java.lang.String referencingTableName)
      Adds the specified table to the set of tables that reference this table.
      void append​(Schema s)
      Append another schema to this schema.
      java.util.SortedMap<java.lang.Integer,​ColumnInfo> findColumns​(ColumnName colName)
      Given a (possibly wildcard) column-name, this method returns the collection of all columns that match the specified column name.
      java.util.List<KeyColumnRefs> getAllKeysOnColumns​(int[] colIndexes)
      Returns all candidate-keys from this schema that have the specified set of columns.
      java.util.List<KeyColumnRefs> getAllKeysOnColumns​(ColumnRefs colRefs)
      Returns all candidate-keys from this schema that have the specified set of columns.
      java.util.List<KeyColumnRefs> getCandidateKeys()
      Returns an unmodifiable list of candidate keys present on the schema.
      int getColumnIndex​(ColumnName colName)
      Finds the index of the specified column in this schema, or returns -1 if the schema contains no column of the specified name.
      int getColumnIndex​(ColumnInfo colInfo)
      Finds the index of the specified column in this schema, or returns -1 if the schema contains no column of the specified name.
      int getColumnIndex​(java.lang.String colName)
      Finds the index of the specified column in this schema, or returns -1 if the schema contains no column of the specified name.
      int getColumnIndex​(java.lang.String tblName, java.lang.String colName)
      Finds the index of the specified column in this schema, or returns -1 if the schema contains no column of the specified name.
      int[] getColumnIndexes​(java.util.List<java.lang.String> columnNames)
      Given a list of column names, this method returns an array containing the indexes of the specified columns.
      ColumnInfo getColumnInfo​(int i)
      Returns the ColumnInfo object describing the column at the specified index.
      ColumnInfo getColumnInfo​(java.lang.String colName)
      Presuming that exactly one column has the specified name, this method returns the column information for that column name.
      java.util.List<ColumnInfo> getColumnInfos()
      Returns an unmodifiable list of all the columns in the schema
      java.util.ArrayList<ColumnInfo> getColumnInfos​(int[] colIndexes)
      Constructs and returns a list of ColumnInfo objects for the columns at the specified indexes.
      java.util.Set<java.lang.String> getColumnNames()
      Returns a set containing all column names that appear in this schema.
      java.util.Set<java.lang.String> getCommonColumnNames​(Schema s)
      Returns the names of columns that are common between this schema and the specified schema.
      java.util.Set<java.lang.String> getCommonTableNames​(Schema s)
      This helper method returns the names of all tables that appear in both this schema and the specified schema.
      java.util.List<ForeignKeyColumnRefs> getForeignKeys()  
      IndexColumnRefs getIndex​(java.lang.String indexName)  
      java.util.Collection<IndexColumnRefs> getIndexes()  
      java.util.Set<java.lang.String> getIndexNames()  
      KeyColumnRefs getKeyOnColumns​(int[] colIndexes)
      Returns any candidate-key from this schema that has the specified set of columns.
      KeyColumnRefs getKeyOnColumns​(ColumnRefs colRefs)
      Returns any candidate-key from this schema that has the specified set of columns.
      java.util.Set<java.lang.Integer> getNotNull()
      Returns a set of columns that have a NOT NULL constraint, specified by the indexes of the columns in the table schema.
      KeyColumnRefs getPrimaryKey()
      Returns the primary key on this table, or null if there is no primary key.
      java.util.Set<java.lang.String> getReferencingTables()  
      java.util.Set<java.lang.String> getTableNames()
      Returns a set containing all table names that appear in this schema.
      boolean hasKeyOnColumns​(int[] colIndexes)
      Returns true if this schema has a candidate key on the set of columns specified in the argument.
      boolean hasKeyOnColumns​(ColumnRefs colRefs)
      Returns true if this schema has a candidate key on the set of columns specified in the argument.
      boolean hasMultipleColumnsWithSameName()
      This helper method returns true if this schema contains any columns with the same column name but different table names.
      boolean isNullable​(int colIndex)  
      java.util.Iterator<ColumnInfo> iterator()
      Provides support for iteration over the columns in the schema.
      int numCandidateKeys()
      Returns a count of how many candidate keys are present on the schema.
      int numColumns()
      Returns the number of columns in the schema.
      int numColumnsWithName​(java.lang.String colName)
      Returns the number of columns that have the specified column name.
      int numForeignKeys()  
      boolean removeNotNull​(int colIndex)
      Removes a column with given index from the list of NOT NULL constrained columns.
      void removeReferencingTable​(java.lang.String referencingTableName)  
      void setTableName​(java.lang.String tableName)
      This method iterates through all columns in the schema, setting them to all have the specified table name.
      java.lang.String toString()  
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
      • Methods inherited from interface java.lang.Iterable

        forEach, spliterator
    • Field Detail

      • columnInfos

        private java.util.ArrayList<ColumnInfo> columnInfos
        The collection of the column-info objects describing the columns in the schema.
      • colsHashedByTable

        private java.util.HashMap<java.lang.String,​java.util.HashMap<java.lang.String,​Schema.IndexedColumnInfo>> colsHashedByTable
        A mapping that provides fast lookups for columns based on table name and column name. The outer hash-map has table names for keys; "no table" is indicated with a null key, which HashMap supports. The inner hash-map has column names for keys, and maps to column information objects.
      • colsHashedByColumn

        private java.util.HashMap<java.lang.String,​java.util.ArrayList<Schema.IndexedColumnInfo>> colsHashedByColumn
        A mapping that provides fast lookups for columns based only on column name. Because multiple columns could have the same column name (but different table names) in a single schema, the values in the mapping are lists.
      • notNullCols

        private java.util.HashSet<java.lang.Integer> notNullCols
        A set recording the indexes of the columns have NOT NULL constraints on them.
      • candidateKeys

        private java.util.ArrayList<KeyColumnRefs> candidateKeys
        A collection of all candidate-key objects specifying the sets of columns that comprise candidate keys on this table. One of these keys may be specified as the primary key.
      • foreignKeys

        private java.util.ArrayList<ForeignKeyColumnRefs> foreignKeys
        A collection of foreign-key objects specifying other tables that this table references.
      • referencingTables

        private java.util.HashSet<java.lang.String> referencingTables
        A set of the tables that reference this table.
      • indexes

        private java.util.HashMap<java.lang.String,​IndexColumnRefs> indexes
        This collection provides easy access to all the indexes defined on this table, including those for candidate keys and the primary key.
    • Constructor Detail

      • Schema

        public Schema()
        Construct an empty schema.
      • Schema

        public Schema​(java.lang.Iterable<ColumnInfo> colInfos)
               throws SchemaNameException
        Construct a schema whose columns are taken from the specified iterable. Note that this does not work with arrays of column-info objects.
        Throws:
        SchemaNameException
      • Schema

        public Schema​(Schema... schemas)

        Create a schema that is the concatenation of one or more other schemas. Schemas are copied in the order they are given. If a column name appears multiple times in the input, an exception will be generated.

        Keys will not be copied by this constructor.

        Parameters:
        schemas - one or more schema objects to copy into this schema
    • Method Detail

      • numColumns

        public int numColumns()
        Returns the number of columns in the schema.
        Returns:
        the number of columns in the schema.
      • getColumnInfo

        public ColumnInfo getColumnInfo​(int i)
        Returns the ColumnInfo object describing the column at the specified index. Column indexes are numbered from 0.
        Parameters:
        i - the index to retrieve the column-info for
        Returns:
        the ColumnInfo object describing the name and type of the column
      • getColumnInfos

        public java.util.List<ColumnInfo> getColumnInfos()
        Returns an unmodifiable list of all the columns in the schema
        Returns:
        an unmodifiable list of all the columns in the schema
      • getColumnInfos

        public java.util.ArrayList<ColumnInfo> getColumnInfos​(int[] colIndexes)
        Constructs and returns a list of ColumnInfo objects for the columns at the specified indexes. This method can be useful with ColumnRefs objects,to retrieve the columns referenced by a key.
        Parameters:
        colIndexes - an array of zero-based column indexes to retrieve
        Returns:
        a list of ColumnInfo objects for the specified columns
      • iterator

        public java.util.Iterator<ColumnInfo> iterator()
        Provides support for iteration over the columns in the schema.
        Specified by:
        iterator in interface java.lang.Iterable<ColumnInfo>
        Returns:
        an iterator over the columns in this schema.
      • addColumnInfo

        public int addColumnInfo​(ColumnInfo colInfo)
        Add a column to the schema.
        Parameters:
        colInfo - the name and type of the column being added to the schema
        Returns:
        the zero-based index of the column in the schema
        Throws:
        java.lang.IllegalArgumentException - if colInfo is null
      • append

        public void append​(Schema s)
                    throws SchemaNameException
        Append another schema to this schema.
        Throws:
        SchemaNameException - if any of the input column-info objects overlap the names of columns already in the schema.
      • getTableNames

        public java.util.Set<java.lang.String> getTableNames()
        Returns a set containing all table names that appear in this schema. Note that this may include null if there are columns with no table name specified!
      • getCommonTableNames

        public java.util.Set<java.lang.String> getCommonTableNames​(Schema s)
        This helper method returns the names of all tables that appear in both this schema and the specified schema. Note that not all columns of a given table must be present for the table to be included in the result; there just has to be at least one column from the table in both schemas for it to be included in the result.
        Parameters:
        s - the other schema to compare this schema to
        Returns:
        a set containing the names of all tables that appear in both schemas
      • getColumnNames

        public java.util.Set<java.lang.String> getColumnNames()
        Returns a set containing all column names that appear in this schema. Note that a column-name may be used by multiple columns, if it is associated with multiple table names in this schema.
        Returns:
        a set containing all column names that appear in this schema.
      • getCommonColumnNames

        public java.util.Set<java.lang.String> getCommonColumnNames​(Schema s)
        Returns the names of columns that are common between this schema and the specified schema. This kind of operation is mainly used for resolving NATURAL joins.
        Parameters:
        s - the schema to compare to this schema
        Returns:
        a set of the common column names
      • numColumnsWithName

        public int numColumnsWithName​(java.lang.String colName)
        Returns the number of columns that have the specified column name. Note that multiple columns can have the same column name but different table names.
        Parameters:
        colName - the column name to return the count for
        Returns:
        the number of columns with the specified column name
      • hasMultipleColumnsWithSameName

        public boolean hasMultipleColumnsWithSameName()
        This helper method returns true if this schema contains any columns with the same column name but different table names. If so, the schema is not valid for use on one side of a NATURAL join.
        Returns:
        true if the schema has multiple columns with the same column name but different table names, or false otherwise.
      • getColumnInfo

        public ColumnInfo getColumnInfo​(java.lang.String colName)
        Presuming that exactly one column has the specified name, this method returns the column information for that column name.
        Parameters:
        colName - the name of the column to retrieve the information for
        Returns:
        the column information for the specified column
        Throws:
        SchemaNameException - if the specified column name doesn't appear in this schema, or if it appears multiple times
      • setTableName

        public void setTableName​(java.lang.String tableName)
                          throws SchemaNameException
        This method iterates through all columns in the schema, setting them to all have the specified table name. An exception will be thrown if the result would be an invalid schema with duplicate column names; in this case, the schema object will remain unchanged.
        Throws:
        SchemaNameException - if the schema contains columns with the same column name but different table names. In this case, resetting the table name will produce an invalid schema with ambiguous column names.
        Design Note:
        (donnie) At present, this method does this by replacing each ColumnInfo object with a new object with updated information. This is because ColumnInfo is immutable.
      • getColumnIndex

        public int getColumnIndex​(ColumnName colName)
        Finds the index of the specified column in this schema, or returns -1 if the schema contains no column of the specified name. The column-name object is not required to specify a table name; however, if the table name is unspecified and the column name is ambiguous then an exception will be thrown.
        Parameters:
        colName - column-name object to use for looking up the column in the schema
        Returns:
        the zero-based index of the column, or -1 if the schema does not contain a column of the specified name.
        Throws:
        java.lang.IllegalArgumentException - if colName is null
        SchemaNameException - if colName doesn't specify a table name, and multiple columns have the specified column name
      • getColumnIndex

        public int getColumnIndex​(ColumnInfo colInfo)
        Finds the index of the specified column in this schema, or returns -1 if the schema contains no column of the specified name. The column-info object is not required to specify a table name; however, if the table name is unspecified and the column name is ambiguous then an exception will be thrown.
        Parameters:
        colInfo - column-info object to use for looking up the column in the schema
        Returns:
        the zero-based index of the column, or -1 if the schema does not contain a column of the specified name.
        Throws:
        java.lang.IllegalArgumentException - if colInfo is null
        SchemaNameException - if colInfo doesn't specify a table name, and multiple columns have the specified column name
      • getColumnIndex

        public int getColumnIndex​(java.lang.String colName)
        Finds the index of the specified column in this schema, or returns -1 if the schema contains no column of the specified name. The table name is unspecified; if the column name is ambiguous then an exception will be thrown.
        Parameters:
        colName - the column name to look up
        Returns:
        the zero-based index of the column, or -1 if the schema does not contain a column of the specified name.
        Throws:
        java.lang.IllegalArgumentException - if colName is null
        SchemaNameException - if multiple columns have the specified column name
      • getColumnIndex

        public int getColumnIndex​(java.lang.String tblName,
                                  java.lang.String colName)
        Finds the index of the specified column in this schema, or returns -1 if the schema contains no column of the specified name. The table name may be specified or it may be null; if null and the column name is ambiguous then an exception will be thrown.
        Parameters:
        tblName - the table name, or null if the table name is not known or unspecified
        colName - the column name to look up
        Returns:
        the zero-based index of the column, or -1 if the schema does not contain a column of the specified name.
        Throws:
        java.lang.IllegalArgumentException - if colName is null
        SchemaNameException - if tblName is null and multiple columns have the specified column name
      • getColumnIndexes

        public int[] getColumnIndexes​(java.util.List<java.lang.String> columnNames)
        Given a list of column names, this method returns an array containing the indexes of the specified columns.
        Parameters:
        columnNames - a list of column names in the schema
        Returns:
        an array containing the indexes of the columns specified in the input
        Throws:
        SchemaNameException - if a column name is specified multiple times in the input list, or if a column name doesn't appear in the schema
      • findColumns

        public java.util.SortedMap<java.lang.Integer,​ColumnInfo> findColumns​(ColumnName colName)
        Given a (possibly wildcard) column-name, this method returns the collection of all columns that match the specified column name. The collection is a mapping from integer indexes (the keys) to ColumnInfo objects from the schema.

        Any valid column-name object will work, so all of these options are available:

        • No table, only a column name - to resolve an unqualified column name, e.g. in an expression or predicate
        • A table and column name - to check whether the schema contains such a column
        • A wildcard without a table name - to retrieve all columns in the schema
        • A wildcard with a table name - to retrieve all columns associated with a particular table name
      • addNotNull

        public boolean addNotNull​(int colIndex)
        Adds a column with given index to list of NOT NULL constrained columns.
        Parameters:
        colIndex - the integer index of the column to NOT NULL constrain.
        Returns:
        true if the column previous was NULLable, or false if the column already had a NOT NULL constraint on it before this call.
      • removeNotNull

        public boolean removeNotNull​(int colIndex)
        Removes a column with given index from the list of NOT NULL constrained columns.
        Parameters:
        colIndex - the integer index of the column to remove the NOT NULL constraint from.
      • isNullable

        public boolean isNullable​(int colIndex)
      • getNotNull

        public java.util.Set<java.lang.Integer> getNotNull()
        Returns a set of columns that have a NOT NULL constraint, specified by the indexes of the columns in the table schema.
        Returns:
        set of integers - indexes of columns with NOT NULL constraint
      • getPrimaryKey

        public KeyColumnRefs getPrimaryKey()
        Returns the primary key on this table, or null if there is no primary key.
        Returns:
        the primary key on this table, or null if there is no primary key.
      • addCandidateKey

        public void addCandidateKey​(KeyColumnRefs ck)
        Adds another candidate key to the schema.
        Parameters:
        ck - the candidate key to add to the schema.
        Throws:
        java.lang.IllegalArgumentException - if ck is null, or if ck is a primary key and the schema already contains a primary key.
      • numCandidateKeys

        public int numCandidateKeys()
        Returns a count of how many candidate keys are present on the schema.
        Returns:
        a count of how many candidate keys are present on the schema.
      • getCandidateKeys

        public java.util.List<KeyColumnRefs> getCandidateKeys()
        Returns an unmodifiable list of candidate keys present on the schema.
        Returns:
        an unmodifiable list of candidate keys present on the schema.
      • hasKeyOnColumns

        public boolean hasKeyOnColumns​(int[] colIndexes)
        Returns true if this schema has a candidate key on the set of columns specified in the argument. The columns are specified by an array of zero-based indexes.
        Parameters:
        colIndexes - the set of columns to check against this table to see if it's a candidate key
        Returns:
        true if this table has a candidate key on the specified columns; false otherwise
      • hasKeyOnColumns

        public boolean hasKeyOnColumns​(ColumnRefs colRefs)
        Returns true if this schema has a candidate key on the set of columns specified in the argument. The columns are specified by a ColumnRefs object.
        Parameters:
        colRefs - the set of columns to check against this table to see if it's a candidate key
        Returns:
        true if this table has a candidate key on the specified columns; false otherwise
      • getKeyOnColumns

        public KeyColumnRefs getKeyOnColumns​(int[] colIndexes)
        Returns any candidate-key from this schema that has the specified set of columns. Note that the key's columns may be in a different order than those specified in the argument.
        Parameters:
        colIndexes - the set of columns to check against this table to see if it's a candidate key
        Returns:
        a candidate key on the specified columns, or null if the schema contains no key on the specified columns
      • getKeyOnColumns

        public KeyColumnRefs getKeyOnColumns​(ColumnRefs colRefs)
        Returns any candidate-key from this schema that has the specified set of columns. Note that the key's columns may be in a different order than those specified in the argument.
        Parameters:
        colRefs - the set of columns to check against this table to see if it's a candidate key
        Returns:
        a candidate key on the specified columns, or null if the schema contains no key on the specified columns
      • getAllKeysOnColumns

        public java.util.List<KeyColumnRefs> getAllKeysOnColumns​(int[] colIndexes)
        Returns all candidate-keys from this schema that have the specified set of columns. Note that keys may specify columns in a different order than those specified in the argument. If there are no keys on the specified columns, this method will return an empty list.
        Parameters:
        colIndexes - the set of columns to check against this table to see if it's a candidate key
        Returns:
        a list of candidate keys on the specified columns
      • getAllKeysOnColumns

        public java.util.List<KeyColumnRefs> getAllKeysOnColumns​(ColumnRefs colRefs)
        Returns all candidate-keys from this schema that have the specified set of columns. Note that keys may specify columns in a different order than those specified in the argument. If there are no keys on the specified columns, this method will return an empty list.
        Parameters:
        colRefs - the set of columns to check against this table to see if it's a candidate key
        Returns:
        a list of candidate keys on the specified columns
      • addReferencingTable

        public boolean addReferencingTable​(java.lang.String referencingTableName)
        Adds the specified table to the set of tables that reference this table.
        Parameters:
        referencingTableName - the name of the table that references this table
        Returns:
        true if the table wasn't previously in this table's set of referencing tables, or false if the table was already in the set of referencing tables
      • removeReferencingTable

        public void removeReferencingTable​(java.lang.String referencingTableName)
      • numForeignKeys

        public int numForeignKeys()
      • getReferencingTables

        public java.util.Set<java.lang.String> getReferencingTables()
      • getIndex

        public IndexColumnRefs getIndex​(java.lang.String indexName)
      • getIndexNames

        public java.util.Set<java.lang.String> getIndexNames()
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object