ModSQL
Class TableReader

java.lang.Object
  |
  +--ModSQL.TableReader
All Implemented Interfaces:
FunctionProvider

final class TableReader
extends Object
implements FunctionProvider

Keeps track of open tables, referenced columns, and current row being read from joined table.

This class implements the full outer-join of all of the tables involved in a query. The interface allows for the skipping of entire subtree's of tuples and the use of indexed tables to improve query efficiency.

Author:
chris.studholme@utoronto.ca

Inner Class Summary
(package private)  class TableReader.TableAccess
          Class to register access to particular tables and whether the tables can be accessed via an indexed column.
 
Field Summary
private  String[] aliases
          Aliases for open tables.
private  ArrayList columns
          Array of referenced columns.
private  int[] indexed_column
          If table_read entry is an index, this array holds the index of the indexed column (or -1 if table_read entry is not an index).
private  int last_read
          Index of last table to be read from.
private  TableReader parent
          Reference to parent TableReader (used in subqueries).
private  ArrayList parent_columns
          Columns from parent reader referenced in this query.
private  int[] read_sequence
          Sequence number for read tables (-1 for not read yet).
private  boolean row_available
          If last_read>=0, then this boolean indicates that rows have been read and are available for all open tables.
private  DatabaseTableBase[] table_read
          Actual table or index being read.
private  DatabaseTable[] tables
          Array of open tables.
 
Constructor Summary
TableReader(DatabaseTable[] tables, String[] aliases, TableReader parent)
          Constructor.
 
Method Summary
static int cardinality(BitSet bs)
          Implements java.util.BitSet.cardinality().
 void commitUpdates()
          Commit updated columns to database.
 void deleteRow()
          Delete current row.
 boolean finishTable()
          Closes least-significant table.
 int getColumnCount()
          Returns total number of referenced columns.
 Object[] getColumnValues()
          Get values for all referenced columns.
 Object[] getColumnValues(int ncolumns)
          Get all column values starting at column 0 and ending at column ncolumns-1.
 DatabaseTable getDatabaseTable(int table_index)
          Get reference to a particular table.
 TableReader getParent()
          Get parent TableReader, or null if none.
 String getTableAlias(int table_index)
          Get table alias (or null if none).
 boolean isIndexAvailable(int table, int column)
          Check if the specified column of the specified table is indexed.
 Function lookupFunction(String description)
          Lookup description in list of tables to find a matching column.
protected  void next()
          Advance to next row.
 void optimizeParameterOrder(Function function)
          Reorder parameters in function to optimize query efficiency.
 void optimizeParameterOrder(Function function, BitSet tables_read)
          Reorder parameters in function to optimize query efficiency.
 boolean parentReferenced()
          Are parent reader columns referenced here?
 void readAllColumns()
          Make sure all tables have been read from.
 void readAllParentColumns()
          Make sure all tables referenced from a parent reader have been read by attempting to fetch values for all referenced columns.
 void readAllTables()
          Make sure all tables have been read from.
 void readColumns(int ncolumns)
          Make sure tables have been read by attempting to fetch values for the first ncolumn referenced columns.
protected  Object readColumnValue(int table_index, int column_index)
          Read the value of the specified column in the specified table.
protected  Object readColumnValue(int table_index, int column_index, Object match_value)
          Read the value of the specified column in the specified table.
 void readParentColumns(int ncolumns)
          Make sure tables referenced from a parent reader have been read by attempting to fetch values for the first ncolumns referenced columns from the parent.
protected  void readTable(int table_index, int column_index)
          Start reading the specified table.
 void reset()
          Invalidate all column data and reset tables to before the first row.
 void setColumnValues(Object[] values)
          Load columns values into respective columns.
 void updateColumnValue(int table_index, int column_index, Object value)
          Update a column in the table.
 
Methods inherited from class java.lang.Object
, clone, equals, finalize, getClass, hashCode, notify, notifyAll, registerNatives, toString, wait, wait, wait
 

Field Detail

tables

private DatabaseTable[] tables
Array of open tables.

aliases

private String[] aliases
Aliases for open tables.

table_read

private DatabaseTableBase[] table_read
Actual table or index being read.

indexed_column

private int[] indexed_column
If table_read entry is an index, this array holds the index of the indexed column (or -1 if table_read entry is not an index).

read_sequence

private int[] read_sequence
Sequence number for read tables (-1 for not read yet).

last_read

private int last_read
Index of last table to be read from.

row_available

private boolean row_available
If last_read>=0, then this boolean indicates that rows have been read and are available for all open tables. If last_read<0, this boolean indicates if we are before the first first row (true) or after the last row of the table (false).

columns

private ArrayList columns
Array of referenced columns.

parent

private TableReader parent
Reference to parent TableReader (used in subqueries).

parent_columns

private ArrayList parent_columns
Columns from parent reader referenced in this query.
Constructor Detail

TableReader

public TableReader(DatabaseTable[] tables,
                   String[] aliases,
                   TableReader parent)
Constructor.
Parameters:
tables - array of open database tables
aliases - aliases of the database tables
parent - parent reader of subquery (null if none)
Method Detail

getParent

public TableReader getParent()
Get parent TableReader, or null if none.
Returns:
parent reader or null this is the root

parentReferenced

public boolean parentReferenced()
Are parent reader columns referenced here?
Returns:
true if we reference columns in the parent reader

getDatabaseTable

public DatabaseTable getDatabaseTable(int table_index)
Get reference to a particular table.
Returns:
a particular table

getTableAlias

public String getTableAlias(int table_index)
Get table alias (or null if none).
Returns:
alias for table

getColumnCount

public int getColumnCount()
Returns total number of referenced columns.
Returns:
number of columns referenced

lookupFunction

public Function lookupFunction(String description)
                        throws SQLException

Lookup description in list of tables to find a matching column. The description can be in any one of the following forms: 'alias.column_name', 'table_name.column_name', or 'column_name'.

If a suitable column is found, it is added to the list of referenced columns (if it's not already there).

If a suitable column was not found and this TableReader has a parent, the parent is searched for a matching column.

Specified by:
lookupFunction in interface FunctionProvider
Parameters:
description - description of column to look for
Returns:
Function representing column
Throws:
SQLException - if the column was not found

isIndexAvailable

public boolean isIndexAvailable(int table,
                                int column)
                         throws SQLException
Check if the specified column of the specified table is indexed.
Parameters:
table - index of table
column - index of column within table
Returns:
true if an index is available on the specified column
Throws:
SQLException - if thrown by a database module

optimizeParameterOrder

public void optimizeParameterOrder(Function function)
                            throws SQLException
Reorder parameters in function to optimize query efficiency. This method is the same as optimizeParameterOrder() below, but with an empty bitmap for tables_read.
Parameters:
function - the function to optimize by reordering terms
Throws:
SQLException - if an error occurs

optimizeParameterOrder

public void optimizeParameterOrder(Function function,
                                   BitSet tables_read)
                            throws SQLException
Reorder parameters in function to optimize query efficiency. This method essentially decides the join order of the tables.
Parameters:
function - the function to optimize by reordering terms
tables_read - bitmap indicating which tables have been read from
Throws:
SQLException - if an error occurs

getColumnValues

public Object[] getColumnValues(int ncolumns)
                         throws SQLException,
                                EndOfTable
Get all column values starting at column 0 and ending at column ncolumns-1. These value are useful for reloading into row using setColumnValues().
Parameters:
ncolumns - total number of column values to fetch
Returns:
array of column values
Throws:
SQLException - if an error occurs
EndOfTable - if the end of a table has been encountered

getColumnValues

public Object[] getColumnValues()
                         throws SQLException,
                                EndOfTable
Get values for all referenced columns. This method is the same as getColumnValues() above, but with ncolumns set to fetch values for all columns.
Returns:
array of column values
Throws:
SQLException - if an error occurs
EndOfTable - if the end of a table has been encountered

setColumnValues

public void setColumnValues(Object[] values)
                     throws SQLException
Load columns values into respective columns. This method can be used to reload a row of data fetched earlier using getColumnValues(). If the length of values is less than the number of columns, the remaining columns will be in an indeterminant state.
Parameters:
values - values for each referenced column
Throws:
SQLException - if an error occurs

reset

public void reset()
Invalidate all column data and reset tables to before the first row. Clients should call next() before evaluating the first row.

next

protected void next()
             throws SQLException,
                    EndOfTable
Advance to next row. The tables are initially positioned before the first row so this method should be called before the first row is evaluated.
Throws:
SQLException - if an error occurs
EndOfTable - if the end of a table has been encountered

finishTable

public boolean finishTable()
                    throws SQLException
Closes least-significant table. This should be done in response to EndOfTable throwable. Call this method before calling nextRow() to advance to the next row.
Returns:
true if all tables have been closed
Throws:
SQLException - if an error occurs

readTable

protected void readTable(int table_index,
                         int column_index)
                  throws SQLException,
                         EndOfTable
Start reading the specified table. If the table has never been read before (ie. is not open), it may be opened via an index on the specified column. If the row from the previous table is not valid, it will be read before the new table is opened.
Parameters:
table_index - index of next table to read
column_index - index of column being referenced (-1 for none)
Throws:
SQLException - if an error occurs
EndOfTable - if the end of a table has been encountered

readAllTables

public void readAllTables()
                   throws SQLException,
                          EndOfTable
Make sure all tables have been read from.
Throws:
SQLException - if an error occurs
EndOfTable - if the end of a table has been encountered

readParentColumns

public void readParentColumns(int ncolumns)
                       throws SQLException,
                              EndOfTable
Make sure tables referenced from a parent reader have been read by attempting to fetch values for the first ncolumns referenced columns from the parent.
Parameters:
ncolumns - number of parent columns to check
Throws:
SQLException - if an error occurs
EndOfTable - if the end of a table has been encountered

readAllParentColumns

public void readAllParentColumns()
                          throws SQLException,
                                 EndOfTable
Make sure all tables referenced from a parent reader have been read by attempting to fetch values for all referenced columns. This method is the same as readParentColumns() above, but with ncolumns set to check all referenced columns.
Throws:
SQLException - if an error occurs
EndOfTable - if the end of a table has been encountered

readColumns

public void readColumns(int ncolumns)
                 throws SQLException,
                        EndOfTable
Make sure tables have been read by attempting to fetch values for the first ncolumn referenced columns.
Parameters:
ncolumns - number of columns to check
Throws:
SQLException - if an error occurs
EndOfTable - if the end of a table has been encountered

readAllColumns

public void readAllColumns()
                    throws SQLException,
                           EndOfTable
Make sure all tables have been read from. This method is the same as readColumns() above, but with ncolumns set to ensure that all tables with at least one referenced column are checked.
Throws:
SQLException - if an error occurs
EndOfTable - if the end of a table has been encountered

readColumnValue

protected Object readColumnValue(int table_index,
                                 int column_index)
                          throws SQLException,
                                 EndOfTable
Read the value of the specified column in the specified table.
Parameters:
table_index - index of table
column_index - index of column within table
Returns:
column value
Throws:
SQLException - if an error occurs
EndOfTable - if the end of a table has been encountered

readColumnValue

protected Object readColumnValue(int table_index,
                                 int column_index,
                                 Object match_value)
                          throws SQLException,
                                 EndOfTable

Read the value of the specified column in the specified table. If it is necessary to advance to the next row of the table, search for a row with match_value in the specified column. This method is not obligated to return match_value. It may just advance to the next row as the above implementation of readColumnValue() does.

Note that the type of object passed in match_value must exactly match the column type as indicated by getSQLType().

Parameters:
table_index - index of table
column_index - index of column within table
match_value - object value to look for
Returns:
column value
Throws:
SQLException - if an error occurs
EndOfTable - if the end of a table has been encountered

updateColumnValue

public void updateColumnValue(int table_index,
                              int column_index,
                              Object value)
                       throws SQLException
Update a column in the table.
Parameters:
table_index - index of table
column_index - index of column within table
value - new value for column
Throws:
SQLException - if an error occurs

commitUpdates

public void commitUpdates()
                   throws SQLException
Commit updated columns to database.
Throws:
SQLException - if an error occurs

deleteRow

public void deleteRow()
               throws SQLException
Delete current row.
Throws:
SQLException - if an error occurs

cardinality

public static int cardinality(BitSet bs)
Implements java.util.BitSet.cardinality(). This method is needed because the cardinality() method in BitSet is not available in before v1.4 JDK.
Parameters:
bs - bits to count
Returns:
number of 1 bits in BitSet