The code files that we have given you for the DBMS programming assignment can be grouped into several collections of related files. Some files appear in more than one collection. Below, we discuss each collection in turn.
More detail can be found in the API documentation for the framework.
Files that define and implement the parser
sym.javaParser.javaLexer.javaYou do not need to understand the code in these files, and you will not be modifying them.
Files related to WHERE clause evaluation
ConditionalExpression.javaAndExpression.javaOrExpression.javaNotExpression.javaTrueExpression.javaComparison.javaCompareTerm.javaYou will not be modifying these files, and you don’t need to
understand all of the details of the code that they
contain. However, you may want to browse through the files to get
some sense of how WHERE clause evaluation is carried out.
In a parsed SQL command, a WHERE clause is essentially a tree data
structure. For example, the WHERE clause
WHERE age < 30 AND (zip = '02138' OR zip = '02140')
would form a tree that looks like this:
A WHERE clause is represented by a reference to the object that
serves as the root of the WHERE clause tree. This object is an
instance of one of the subclasses of the abstract class
ConditionalExpression. To evaluate the clause, we simply invoke
the root object’s isTrue() method, which returns true if the
expression is true for the current values of the columns involved,
and false otherwise. The leaf nodes of the tree are terms that
are being compared. These terms are either columns or literal
values. The CompareTerm class is used for literal values. The
Column class is used for columns; it is a subclass of
CompareTerm.
We have given you almost all of the code needed for evaluating
WHERE clauses. The one exception is the code you will write to
retrieve the value of a column from the tuple that is currently
being considered for selection. However, this value-retrieval code
will be implemented in other files.
Files for classes of objects generated by the parser
SQLStatement.java (and its subclasses; more on them later)Table.javaColumn.javaColumnOptions.javaLimit.javaThe SQL parser takes the SQL command entered by the user (a string of characters) and breaks it up into a set of tokens. Each token represents one element of the command — a table name, a column name, a column value, etc.
In our framework, these tokens are represented by objects, and the
tokens for a given command are managed by an object that
represents the command as a whole. For example, if the user enters
a SELECT command, the parser will generate an object of type
SelectStatement, and we will use that object to access the
objects that represent the individual tokens of that command
(e.g., the names of the table or tables on which the SELECT
command is operating).
The objects that represent the command as a whole are instances of
one of the subclasses of the abstract class SQLStatement. These
subclasses will be described in the next section. The classes used
for the tokens include the classes mentioned above (Table,
Column, ColumnOptions, Limit), the classes for conditional
expressions mentioned in the previous section, and several
built-in Java classes (String, Integer, Double). All
SQLStatement subclasses have methods that allow you to get
information about the tokens of a particular type (e.g.,
getTable(), getColumn(), numTables(), numColumns(),
etc.). These accessor methods are defined in the SQLStatement
class itself, and the subclasses inherit them.
Files for classes of objects that represent SQL commands
BeginStatement.java (for BEGIN TRANSACTION)CommitStatement.java (for COMMIT TRANSACTION)CreateStatement.javaDeleteStatement.javaDropStatement.javaInsertStatement.javaRollbackStatement.java (for ROLLBACK TRANSACTION)SelectStatement.javaUpdateStatement.javaThese files contain the class definitions for the subclasses of the
abstract class SQLStatement that was mentioned above. Each subclass
represents one type of SQL command.
The SQLStatement superclass includes an abstract method called
execute(). Each subclass has its own version of that method,
that performs the operations needed to carry out that command. We
have given you the execute() method for CREATE TABLE and DROP
TABLE commands. You will complete the execute() methods of some
of the other types of SQL commands.
Files for classes of objects that are used to access and manipulate the contents of a table
Table.javaColumn.javaInsertRow.javaTableIterator.javaRowOutput.javaRowInput.javaThe Table and Column classes are used for two different
purposes. First, they are used to represent tokens generated by
the parser, in which case they primarily serve as identifiers that
specify the name of the table or column (see section 3
above). Second, they are used to represent the stored
representations of actual tables and columns in the relational
database. If the parser generates an instance of one of these
classes, it may be necessary to fill in some of the fields of the
object before it can used to actually represent a stored table or
column. You should not need to add to or modify these two classes,
but it is important that you understand the methods that they
contain. You should at least read the comments that precede
each method, and you may also want to look over the bodies of the
methods to get some idea of how they work.
InsertRow objects are used to marshall the values in a row that
is being inserted, turning them into a single key/data pair.
You will implement the key method in this class. In doing so,
you will use objects of type RowOutput to prepare the byte arrays
for the key/value pair that you ask Berkeley DB to store.
TableIterator objects are used to iterate over some or all of
the tuples in a table. You will implement some of the methods in
this class. In doing so, you will use objects of type RowInput
to extract values from the byte arrays that form the basis of the
key/value pairs that you obtain from Berkeley DB.
You should not need to add to or modify the
RowOutput or RowInput classes, but it is important that you
understand the methods that they contain! In the case of
RowOutput, you should also review the methods that it inherits
from the DataOutputStream class.
Files that implement the DBMS infrastructure
DBMS.javaCatalog.javaTable.javaDBMS.java contains the main() method for the application. It
also has methods/functions for initializing and shutting down the
DBMS, including code for configuring and opening the Berkeley DB
environment used for the underlying BDB databases.
Catalog.java contains the code implementing the DBMS catalog, which
stores the per-table metadata associated with each table in the DBMS.
Table.java includes support for an in-memory table cache,
which keeps track of all tables whose underlying Berkeley DB
databases have already been opened. When a table is opened, the
corresponding Table object is stored in this cache for possible
future use. The table cache is implemented using an instance of
Java’s HashTable class.
You should not need to modify these files, but it is important that you understand the methods that they contain. You should at least read the comments that precede each method, and you may also want to look over the bodies of the methods to get some idea of how they work.
Note: To allow access to the DBMS and Catalog methods from
all other classes, we make all of these methods static, so that
the class name can be used to invoke them (e.g.,
Catalog.putMetadata(tablename);).
Last updated on October 1, 2025.