Catalog Manager — API Reference
All public functions in the Catalog Manager are documented below, grouped by subsystem. Functions are defined in src/backend/catalog/catalog.rs, constraints.rs, and indexes.rs.
Catalog Initialization
init_catalog
Description:
Dual-mode catalog initialisation, called at startup. Detects whether page-based catalog storage exists and bootstraps if necessary.
Function:
pub fn init_catalog(bm: &mut BufferManager)
Input:
bm— Mutable reference to the buffer manager.
Implementation:
- Create
database/global/anddatabase/base/directories if they do not exist. - If
database/global/catalog_pages/exists, report that the page backend is detected. - Otherwise, call
bootstrap_catalog(bm)to initialise the system from scratch.
bootstrap_catalog
Description:
Bootstrap the self-hosting catalog: creates system catalog .dat files, inserts built-in types, and writes the system database record.
Function:
pub fn bootstrap_catalog(bm: &mut BufferManager) -> Result<(), CatalogError>
Implementation:
- Ensure
database/global/anddatabase/base/directories exist. - Initialise the OID counter via
OidCounter::initialize(). - Create a new
CatalogPageManagerand initialise all six system catalog files. - Register all 10 built-in data types into
pg_type. - Insert the system database record (
db_oid=1,name="system") intopg_database.
init_catalog_page_storage
Description:
Create or verify the CatalogPageManager after bootstrap.
Function:
pub fn init_catalog_page_storage() -> Result<CatalogPageManager, CatalogError>
Output:
- Returns a fully initialised
CatalogPageManagerwith all file paths registered.
Load / Save
load_catalog
Description:
Load the Catalog from the active storage backend. Attempts page-based loading first; falls back to an empty catalog.
Function:
pub fn load_catalog(bm: &mut BufferManager) -> Catalog
Output:
- Returns a
Catalogstruct populated with all databases, tables, columns, constraints, and index OIDs from the page backend.
Implementation:
- If
catalog_pages/exists, load from pages viaload_catalog_from_pages(bm). - On failure, return
Catalog::new()(empty catalog).
The page-based loader:
- Initialises
OidCounterfrompg_oid_counter.dat. - Scans
pg_database→ populatescatalog.databases. - Scans
pg_table→ attached to parent databases bydb_oid. - Scans
pg_column→ attached to parent tables bytable_oid, sorted bycolumn_position. - Scans
pg_constraint→ attached to parent tables bytable_oid. - Scans
pg_index→ index OIDs attached to parent tables bytable_oid.
Type Helpers
register_builtin_types
Description:
Register all built-in data types in pg_type. Skips types that already exist.
Function:
pub fn register_builtin_types(
pm: &mut CatalogPageManager,
bm: &mut BufferManager,
) -> Result<(), CatalogError>
lookup_type_by_name
Description:
Resolve a type name to a DataType struct. Checks the built-in type list first, then scans pg_type.
Function:
pub fn lookup_type_by_name(
pm: &CatalogPageManager,
bm: &mut BufferManager,
type_name: &str,
) -> Result<DataType, CatalogError>
Output:
- Returns the matching
DataTypeon success, orCatalogError::TypeNotFoundon failure.
Database Operations
create_database
Description:
Create a new database with metadata (owner, encoding) and persist it to pg_database.
Function:
pub fn create_database(
catalog: &mut Catalog,
pm: &mut CatalogPageManager,
bm: &mut BufferManager,
db_name: &str,
owner: &str,
encoding: Encoding,
) -> Result<u32, CatalogError>
Input:
db_name— Name of the new database (must be non-empty and unique).owner— Owner string.encoding— Character encoding (Encoding::UTF8orEncoding::ASCII).
Output:
- Returns the allocated
db_oidon success.
Implementation:
- Validate that the name is non-empty and not already used.
- Allocate a new OID via
catalog.alloc_oid(). - Create the
database/base/{db_name}/directory. - Serialise and insert a record into
pg_database. - Add the
Databasestruct to the in-memory catalog. - Invalidate the database cache entry.
drop_database
Description:
Drop a database and all its tables.
Function:
pub fn drop_database(
catalog: &mut Catalog,
pm: &mut CatalogPageManager,
bm: &mut BufferManager,
db_name: &str,
) -> Result<(), CatalogError>
Implementation:
- Resolve
db_oidfrom the in-memory catalog. - Drop all tables belonging to this database via
drop_table(). - Find and delete the database record from
pg_database. - Remove the database directory from disk.
- Remove from in-memory catalog and invalidate cache.
show_databases
Description:
Display all databases from the page-based catalog with metadata.
Function:
pub fn show_databases(
catalog: &Catalog,
pm: &mut CatalogPageManager,
bm: &mut BufferManager,
)
Output:
- Prints a formatted table:
Database | Owner | Created At.
Table Operations
create_table
Description:
Create a new table with columns and constraints, persisting to pg_table and pg_column.
Function:
pub fn create_table(
catalog: &mut Catalog,
pm: &mut CatalogPageManager,
bm: &mut BufferManager,
db_name: &str,
table_name: &str,
col_defs: Vec<ColumnDefinition>,
constraint_defs: Vec<ConstraintDefinition>,
) -> Result<u32, CatalogError>
Input:
col_defs— Column definitions with type names, nullability, and defaults.constraint_defs— Constraint definitions (PK, FK, UNIQUE, NOT NULL).
Output:
- Returns the allocated
table_oidon success.
Implementation:
- Validate that the database exists and the table name is unique.
- Allocate
table_oidand OIDs for each column. - Resolve each column's type via
DataType::from_name(). - Serialise and insert column records into
pg_column. - Create the table data file (
{db_name}/{table_name}.dat) and initialise it. - Serialise and insert a record into
pg_table. - Add the
Tableto the in-memory catalog and invalidate cache. - Process each constraint definition (PK, FK, UNIQUE, NOT NULL) via the respective constraint functions.
drop_table
Description:
Drop a table and all dependent objects (indexes, constraints).
Function:
pub fn drop_table(
catalog: &mut Catalog,
pm: &mut CatalogPageManager,
bm: &mut BufferManager,
table_oid: u32,
) -> Result<(), CatalogError>
Implementation:
- Check for foreign key dependencies from other tables — return
ForeignKeyDependencyerror if found. - Drop all indexes on this table via
drop_index(). - Locate the table's database name and table name.
- Remove the table data file from disk.
- Delete the record from
pg_table. - Remove from in-memory catalog and invalidate all related cache entries.
alter_table_add_column
Description:
Add a new column to an existing table.
Function:
pub fn alter_table_add_column(
catalog: &mut Catalog,
pm: &mut CatalogPageManager,
bm: &mut BufferManager,
table_oid: u32,
col_def: ColumnDefinition,
) -> Result<u32, CatalogError>
Output:
- Returns the allocated
column_oidon success.
Constraints:
- If the column is
NOT NULL, a default value must be provided (otherwise returnsInvalidOperation). - Column name must not already exist in the table.
show_tables
Description:
Display all tables in a database from the page-based catalog with statistics.
Function:
pub fn show_tables(
catalog: &Catalog,
pm: &mut CatalogPageManager,
bm: &mut BufferManager,
db_name: &str,
)
Output:
- Prints a formatted table:
Table Name | Rows | Pages | Created At.
get_table_metadata
Description:
Retrieve complete table metadata including resolved columns, constraints, and indexes.
Function:
pub fn get_table_metadata(
catalog: &Catalog,
pm: &CatalogPageManager,
bm: &mut BufferManager,
db_name: &str,
table_name: &str,
) -> Result<TableMetadata, CatalogError>
Output:
- Returns a
TableMetadatastruct with fullColumn,Constraint, andIndexdata.
Constraint Management
add_primary_key_constraint
Description:
Add a primary key constraint to a table. Automatically creates a backing unique B-Tree index and sets referenced columns to NOT NULL.
Function:
pub fn add_primary_key_constraint(
catalog: &mut Catalog,
pm: &mut CatalogPageManager,
bm: &mut BufferManager,
table_oid: u32,
column_names: Vec<String>,
constraint_name: Option<String>,
) -> Result<u32, CatalogError>
Output:
- Returns the allocated
constraint_oid.
Errors:
AlreadyHasPrimaryKeyif the table already has a primary key.
add_foreign_key_constraint
Description:
Add a foreign key constraint referencing another table's primary key or unique columns.
Function:
pub fn add_foreign_key_constraint(
catalog: &mut Catalog,
pm: &mut CatalogPageManager,
bm: &mut BufferManager,
table_oid: u32,
column_names: Vec<String>,
referenced_table_oid: u32,
referenced_column_names: Vec<String>,
on_delete: ReferentialAction,
on_update: ReferentialAction,
constraint_name: Option<String>,
) -> Result<u32, CatalogError>
Validations:
- Column counts must match between referencing and referenced tables.
- Referenced columns must be covered by a
PRIMARY KEYorUNIQUEconstraint.
add_unique_constraint
Description:
Add a unique constraint to a table. Automatically creates a backing unique B-Tree index.
Function:
pub fn add_unique_constraint(
catalog: &mut Catalog,
pm: &mut CatalogPageManager,
bm: &mut BufferManager,
table_oid: u32,
column_names: Vec<String>,
constraint_name: Option<String>,
) -> Result<u32, CatalogError>
add_not_null_constraint
Description:
Add a NOT NULL constraint to a column (sets is_nullable = false).
Function:
pub fn add_not_null_constraint(
catalog: &mut Catalog,
pm: &mut CatalogPageManager,
bm: &mut BufferManager,
table_oid: u32,
column_oid: u32,
) -> Result<(), CatalogError>
validate_constraints
Description:
Validate all constraints for a tuple before insertion. Called during data loading (e.g., CSV import).
Function:
pub fn validate_constraints(
catalog: &Catalog,
pm: &CatalogPageManager,
bm: &mut BufferManager,
table_oid: u32,
tuple_values: &HashMap<u32, Option<Vec<u8>>>,
) -> Result<(), ConstraintViolation>
Validation logic:
- NOT NULL: Returns
NotNullViolationif any non-nullable column has aNonevalue. - PRIMARY KEY / UNIQUE: Checks the backing B-Tree index for duplicates via
index_lookup(). - FOREIGN KEY: Verifies referenced values exist in the referenced table's index.
get_constraints_for_table
Description:
Get all constraints for a table by scanning pg_constraint.
Function:
pub fn get_constraints_for_table(
catalog: &Catalog,
pm: &CatalogPageManager,
bm: &mut BufferManager,
table_oid: u32,
) -> Result<Vec<Constraint>, CatalogError>
Index Management
create_index
Description:
Create a B-Tree index on specified columns.
Function:
pub fn create_index(
catalog: &mut Catalog,
pm: &mut CatalogPageManager,
bm: &mut BufferManager,
table_oid: u32,
column_oids: Vec<u32>,
is_unique: bool,
is_primary: bool,
index_name: Option<String>,
) -> Result<u32, CatalogError>
Implementation:
- Resolve the database name for the table.
- Generate an index name if not provided (
idx_{table_oid}_{col_oids}). - Create the indexes directory and
.idxfile with an initialised B-Tree root page. - Allocate an
index_oidand persist the index record topg_index. - Add the index OID to the table's in-memory
indexeslist.
drop_index
Description:
Drop an index by its OID, removing the index file and catalog entry.
Function:
pub fn drop_index(
catalog: &mut Catalog,
pm: &mut CatalogPageManager,
bm: &mut BufferManager,
index_oid: u32,
) -> Result<(), CatalogError>
Validations:
- Cannot drop an index that is referenced by a PRIMARY KEY or UNIQUE constraint.
index_lookup
Description:
Search a B-Tree index for a key. Used internally by constraint validation.
Function:
pub fn index_lookup(
bm: &mut BufferManager,
db_name: &str,
index_name: &str,
key_bytes: &[u8],
) -> Result<bool, CatalogError>
insert_index_entry
Description:
Insert a key-value pair into a B-Tree index. Handles page splits and root promotion.
Function:
pub fn insert_index_entry(
bm: &mut BufferManager,
db_name: &str,
index_name: &str,
key_bytes: &[u8],
page_num: u32,
slot_id: u32,
) -> Result<(), CatalogError>
CatalogPageManager CRUD
The CatalogPageManager struct provides low-level CRUD operations on system catalog page files. All methods route I/O through the buffer manager.
insert_catalog_tuple
pub fn insert_catalog_tuple(
&mut self, bm: &mut BufferManager, catalog_name: &str, data: Vec<u8>,
) -> Result<(u32, u32), CatalogError>
Returns (page_num, slot_id) of the inserted tuple. Automatically creates a new page if the current last page lacks space.
read_catalog_tuple
pub fn read_catalog_tuple(
&self, bm: &mut BufferManager, catalog_name: &str, page_num: u32, slot_id: u32,
) -> Result<Vec<u8>, CatalogError>
update_catalog_tuple
pub fn update_catalog_tuple(
&mut self, bm: &mut BufferManager, catalog_name: &str,
page_num: u32, slot_id: u32, new_data: &[u8],
) -> Result<(u32, u32), CatalogError>
Uses a delete-then-reinsert strategy to handle variable-length tuples (see Implementation Notes §3). Returns the new (page_num, slot_id).
scan_catalog
pub fn scan_catalog(
&self, bm: &mut BufferManager, catalog_name: &str,
) -> Result<Vec<Vec<u8>>, CatalogError>
Returns all live tuples from the catalog (skips logically deleted slots with length == 0).
delete_catalog_tuple
pub fn delete_catalog_tuple(
&self, bm: &mut BufferManager, catalog_name: &str, page_num: u32, slot_id: u32,
) -> Result<(), CatalogError>
Performs a logical delete by zeroing the slot's length field. The space is not reclaimed immediately.
find_catalog_tuple
pub fn find_catalog_tuple<F>(
&self, bm: &mut BufferManager, catalog_name: &str, predicate: F,
) -> Result<Option<(u32, u32, Vec<u8>)>, CatalogError>
where F: Fn(&[u8]) -> bool
Scans the catalog and returns the first tuple matching the predicate, along with its (page_num, slot_id).
Note: Some APIs have undergone changes during development. See the Implementation Notes for details on deviations from the original design.