Skip to main content

Overview

This document describes the implementation of operator class (opclass) support in Springtail, enabling the system to handle GIN and GiST secondary indexes in addition to the existing B-tree indexes.
Status: This feature is currently in development on branch SPR-1090-gin-gist-base-3 and has not been merged to main.

Background

PostgreSQL uses operator classes to define the behavior of indexes for different data types. Each index type (B-tree, GIN, GiST) requires specific support functions identified by support numbers. For example:
  • GIN indexes use functions like extractValue, extractQuery, and consistent
  • GiST indexes use functions like consistent, union, compress, decompress, and penalty
Previously, Springtail only supported B-tree secondary indexes. This implementation extends the system to:
  1. Capture and store operator class metadata from PostgreSQL
  2. Route index operations to the appropriate opclass-specific functions
  3. Provide the foundation for building and maintaining GIN/GiST indexes

Goals

  • Store opclass (operator class name) for each index column and index_type (btree, gin, gist) for each index
  • Enable dynamic invocation of opclass support functions via OpClassHandler
  • Prepare the indexer infrastructure to handle non-B-tree index types

Implementation Details

1. New Data Structures

OpClassHandler (include/common/constants.hh)

This handler encapsulates a callback for invoking opclass-specific functions. The support_number parameter identifies which support function to call (e.g., GIST_CONSISTENT = 1, GIN_COMPARE = 1).

Index Type Constants

2. Schema Extensions

Replication Messages (include/pg_repl/pg_repl_msg.hh)

Extended PgMsgSchemaIndexColumn with:
Extended PgMsgIndex with:

Internal Schema (include/storage/schema.hh)

Extended Index::Column with:
Extended Index with:

System Tables (include/sys_tbl_mgr/system_tables.hh)

Indexes table - Added column: IndexNames table - Added column:

3. PostgreSQL Trigger Updates (scripts/triggers.sql)

Modified the index creation trigger to extract opclass and index type from PostgreSQL system catalogs:
This captures:
  • am.amname: The access method name (btree, gin, gist, brin)
  • opc.opcname: The operator class name for each index column

4. MutableBTree Extensions (include/storage/mutable_btree.hh)

Extended constructor to accept opclass handler and index type:
New member variables:

5. Table Manager Updates

MutableTable (include/sys_tbl_mgr/mutable_table.hh)

Extended create_index_root signature:

TableMgr (include/sys_tbl_mgr/table_mgr.hh)

Extended get_snapshot_table to accept OpClassHandler:

6. Indexer Changes (src/pg_log_mgr/indexer.cc)

The indexer now branches based on index type:
Similar branching exists for:
  • Index invalidation during updates
  • Index population during reconciliation

7. Protobuf Schema Updates (src/proto/sys_tbl_mgr.proto)


Data Flow

Index Creation


Path to completion

The core implementation is complete. The remaining blocker is a build failure in the unit test src/pg_fdw/test/where_test.cc. Issue: The test file imports both table and mutable_table headers simultaneously. These headers have conflicting dependencies—one pulls in custom Springtail extension-related imports while the other includes default PostgreSQL imports, causing symbol conflicts during compilation. Resolution: Avoid using mutable_table in the test. Instead, load the table data directly and use only the Table class for scan operations during testing.