minisql

package
v0.53.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 8, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DatabaseHeaderMagic identifies a MiniSQL database file.
	DatabaseHeaderMagic = "minisql\x00"
	// DatabaseFileFormatVersion identifies the current on-disk file header format.
	DatabaseFileFormatVersion = uint32(1)
)
View Source
const (
	// SchemaTableName is the internal table used to store schema metadata.
	SchemaTableName = "minisql_schema"
	// StatsTableName ...
	StatsTableName = "minisql_stats"
	// MaxColumns ...
	MaxColumns = 64
	// RootPageConfigSize is the number of bytes reserved for the root page config header.
	RootPageConfigSize = 100
)
View Source
const (
	// MaxInlineRowIDs ...
	MaxInlineRowIDs = 4
	// MaxOverflowRowIDsPerPage ...
	MaxOverflowRowIDsPerPage = 510 // (4096 - 1 - 8 ) / 8

)
View Source
const (
	// InternalNodeMaxCells is (4096 - 6 - 8) / 12.
	InternalNodeMaxCells = 340
	// RootInternalNodeMaxCells is (4096 - 6 - 8 - 100) / 12.
	RootInternalNodeMaxCells = 331
)

InternalNode capacity constants derived from page and header sizes. Page size: 4096, Header size: 6 (base) + 8 (internal), ICell size: 12.

View Source
const (
	// MaxInlineVarchar ...
	MaxInlineVarchar = 255 // Store up to 255 bytes inline
	// MaxOverflowPageData ...
	MaxOverflowPageData = 4096 - 1 - 8 // Page size - page type byte - OverflowPageHeader size
	// MaxOverflowTextSize limits the maximum size of a text value to 16 overflow pages.
	MaxOverflowTextSize = MaxOverflowPageData * 16
)
View Source
const (
	// PageSize ...
	PageSize = 4096 // 4 kilobytes

	// UsablePageSize returns the usable size of a page after accounting for headers
	// Page size minus base + internal/leaf header, minus key and null bitmask
	UsablePageSize = PageSize - 7 - 8 - 8 - 8
)
View Source
const (
	// PageTypeLeaf ...
	PageTypeLeaf byte = iota
	// PageTypeInternal identifies an internal (non-leaf) B+ tree node page.
	PageTypeInternal
	// PageTypeOverflow identifies a text overflow page.
	PageTypeOverflow
	// PageTypeIndex identifies an index B+ tree node page.
	PageTypeIndex
	// PageTypeFree identifies a free (unused) page available for reuse.
	PageTypeFree
	// PageTypeIndexOverflow identifies an index overflow page for large row ID lists.
	PageTypeIndexOverflow
)

PageType constants identify the type of data stored in a database page.

View Source
const (
	// WALMagic is the 8-byte magic string at the start of every WAL file.
	WALMagic = "miniwal\n"
	// WALVersion is the current on-disk WAL format version.
	WALVersion = uint32(1)
	// WALFileHeaderSize is the fixed byte size of the WAL file header.
	WALFileHeaderSize = 32
	// WALFrameHeaderSize is the fixed byte size of each WAL frame header.
	WALFrameHeaderSize = 24
)

WAL file-format constants.

View Source
const ICellSize = 12 // (8+4)

ICellSize is the serialised byte size of an ICell (8-byte key + 4-byte child pointer).

View Source
const MaxIndexKeySize = 255

MaxIndexKeySize is the maximum number of bytes allowed for a single index key.

View Source
const PageCacheSize = 2000

PageCacheSize is the default maximum number of pages to keep in memory.

View Source
const RightChildNotSet = math.MaxUint32

RightChildNotSet is the sentinel value indicating an internal node has no right child yet.

Variables

View Source
var ErrCheckpointBlockedByReaders = errors.New("checkpoint blocked: active snapshot readers")

ErrCheckpointBlockedByReaders is returned when a checkpoint cannot proceed because one or more read-only transactions hold snapshots that predate the current commitSeq. Callers should retry after the readers have finished.

View Source
var ErrDropTableReferencedByFK = errors.New("cannot drop table: it is still referenced by a foreign key constraint")

ErrDropTableReferencedByFK is the base error for dropping a table that is still referenced by a foreign key in another table.

View Source
var ErrDuplicateKey = errors.New("duplicate key")

ErrDuplicateKey ...

View Source
var ErrNoMoreRows = errors.New("no more rows")

ErrNoMoreRows ...

View Source
var ErrNotFound = errors.New("not found")

ErrNotFound ...

View Source
var ErrNotWALMode = errors.New("WAL mode is not enabled")

ErrNotWALMode is returned when a WAL-specific operation is called on a transaction manager that is not in WAL mode.

View Source
var ErrTxConflict = errors.New("transaction conflict detected")

ErrTxConflict is returned when an optimistic concurrency check fails at commit time.

View Source
var FunctionNow = Function{Name: nowFunctionName}

FunctionNow ...

View Source
var (

	// MainTableSQL is the DDL used to create the internal schema metadata table.
	MainTableSQL = fmt.Sprintf(`create table "%s" (
	type int4 not null,
	name varchar(255) not null,
	tbl_name varchar(255),
	root_page int4 not null,
	sql text
);`, SchemaTableName)
)
View Source
var (

	// StatsTableSQL is the DDL used to create the internal statistics table.
	StatsTableSQL = fmt.Sprintf(`create table "%s" (
	tbl varchar(255),
	idx varchar(255),
	stat text
);`, StatsTableName)
)

Functions

func AutoFKName added in v0.52.0

func AutoFKName(childTable, parentTable string, columns []string) string

AutoFKName builds a deterministic FK constraint name from the involved tables and columns.

func IsValidCondition

func IsValidCondition(c Condition) bool

IsValidCondition checks that all fields of the condition are set

func NewPager

func NewPager(file DBFile, pageSize, maxCachedPages int) (*pagerImpl, error)

NewPager opens the database file and initialises the pager. maxCachedPages sets the maximum number of pages to keep in cache (0 = use default).

func PrimaryKeyName

func PrimaryKeyName(tableName string) string

PrimaryKeyName ...

func RecoverFromWAL added in v0.12.0

func RecoverFromWAL(dbPath string, dbFile DBFile, pageSize uint32) (bool, error)

RecoverFromWAL checks for a WAL file at dbPath+"-wal" and, if found, replays all committed frames into dbFile. The WAL is truncated on success. Returns true when recovery was performed.

func UniqueIndexName

func UniqueIndexName(tableName string, columns ...string) string

UniqueIndexName ...

func UnmarshalDatabaseHeader

func UnmarshalDatabaseHeader(buf []byte, dbHeader *DatabaseHeader) error

UnmarshalDatabaseHeader deserialises a database header from the given byte slice.

func WithTransaction

func WithTransaction(ctx context.Context, tx *Transaction) context.Context

WithTransaction stores a transaction in the context and returns the new context.

Types

type AggregateExpr

type AggregateExpr struct {
	Column string
	Kind   AggregateKind
}

AggregateExpr describes a single aggregate function call in a SELECT list. Parallel to Fields: Fields[i] holds the synthetic output column name (e.g. "SUM(price)"), Aggregates[i] holds the kind and source column. A zero-value AggregateExpr (Kind == 0) means the corresponding field is not an aggregate. Aggregates is only populated when the query contains at least one aggregate function.

type AggregateKind

type AggregateKind int

AggregateKind identifies the type of aggregate function.

const (
	// AggregateCount ...
	AggregateCount AggregateKind = iota + 1 // COUNT(*)
	// AggregateSum ...
	AggregateSum // SUM(col)
	// AggregateAvg is the AVG aggregate function.
	AggregateAvg // AVG(col)
	// AggregateMin is the MIN aggregate function.
	AggregateMin // MIN(col)
	// AggregateMax is the MAX aggregate function.
	AggregateMax // MAX(col)
)

AggregateKind constants enumerate the supported aggregate functions.

func (AggregateKind) String

func (k AggregateKind) String() string

type ArithOp added in v0.4.0

type ArithOp int

ArithOp identifies the arithmetic operator in a binary Expr node.

const (
	ArithAdd ArithOp = iota + 1 // +
	ArithSub                    // -
	ArithMul                    // *
	ArithDiv                    // /
)

ArithOp constants.

func (ArithOp) String added in v0.4.0

func (op ArithOp) String() string

type BTreeIndex

type BTreeIndex interface {
	GetRootPageIdx() PageIndex
	FindRowIDs(ctx context.Context, key any) ([]RowID, error)
	SeekLastKey(ctx context.Context, pageIdx PageIndex) (any, error)
	Insert(ctx context.Context, key any, rowID RowID) error
	Delete(ctx context.Context, key any, rowID RowID) error
	ScanAll(ctx context.Context, reverse bool, callback indexScanner) error
	ScanRange(ctx context.Context, rangeCondition RangeCondition, reverse bool, callback indexScanner) error
	BFS(ctx context.Context, f indexCallback) error
}

BTreeIndex ...

type CTE added in v0.45.0

type CTE struct {
	Name string
	Body *Statement
}

CTE represents a single Common Table Expression.

type CaseWhen added in v0.8.0

type CaseWhen struct {
	Cond *ConditionNode // searched CASE: WHEN <condition>
	When *Expr          // simple CASE: WHEN <value> (compared to parent CaseInput)
	Then *Expr          // THEN <result>
}

CaseWhen holds one WHEN/THEN branch of a CASE expression. Exactly one of Cond (searched CASE) or When (simple CASE) is set.

type Cell

type Cell struct {
	Value       []byte
	NullBitmask uint64
	Key         RowID
	// contains filtered or unexported fields
}

Cell ...

func (*Cell) Marshal

func (c *Cell) Marshal(buf []byte)

Marshal ...

func (*Cell) Size

func (c *Cell) Size() uint64

Size ...

func (*Cell) Unmarshal

func (c *Cell) Unmarshal(columns []Column, buf []byte) (uint64, error)

Unmarshal ...

type Column

type Column struct {
	DefaultValue    OptionalValue
	CheckCond       *ConditionNode // parsed CHECK expression (nil if no CHECK constraint)
	Name            string
	Check           string // raw SQL text of CHECK expression, e.g. "age > 0"
	Kind            ColumnKind
	Size            uint32
	Nullable        bool
	DefaultValueNow bool
}

Column ...

type ColumnKind

type ColumnKind int

ColumnKind ...

const (
	// Boolean ...
	Boolean ColumnKind = iota + 1
	Int4
	Int8
	Real
	Double
	Varchar
	Text
	Timestamp
)

ColumnKind constants enumerate the supported column data types.

func (ColumnKind) IsInt

func (k ColumnKind) IsInt() bool

IsInt ...

func (ColumnKind) IsText

func (k ColumnKind) IsText() bool

IsText ...

func (ColumnKind) String

func (k ColumnKind) String() string

type CompositeKey

type CompositeKey struct {
	Columns []Column
	Values  []any
	// Store the binary representation for comparison (excludes length prefixes for varchars)
	Comparison []byte
}

CompositeKey holds the column definitions and values for a multi-column index key.

func NewCompositeKey

func NewCompositeKey(columns []Column, values ...any) CompositeKey

NewCompositeKey constructs a CompositeKey from the given columns and values.

func (*CompositeKey) Marshal

func (ck *CompositeKey) Marshal(buf []byte, i uint64) error

Marshal serialises the composite key into buf starting at offset i.

func (CompositeKey) Prefix

func (ck CompositeKey) Prefix(columns int) CompositeKey

Prefix returns a CompositeKey containing only the first n columns' comparison bytes.

func (CompositeKey) Size

func (ck CompositeKey) Size() uint64

Size returns the serialised byte size of the composite key.

func (*CompositeKey) Unmarshal

func (ck *CompositeKey) Unmarshal(buf []byte, i uint64) (uint64, error)

Unmarshal deserialises a composite key from buf starting at offset i, returning bytes consumed.

type Condition

type Condition struct {
	Operand1 Operand
	Operand2 Operand
	Operator Operator
}

Condition represents a single predicate: operand1 operator operand2.

func FieldIsBetween

func FieldIsBetween(field Field, low, high any) Condition

FieldIsBetween creates a field BETWEEN low AND high condition.

func FieldIsEqual

func FieldIsEqual(field Field, operandType OperandType, value any) Condition

FieldIsEqual creates a field = value condition.

func FieldIsGreater

func FieldIsGreater(field Field, operandType OperandType, value any) Condition

FieldIsGreater creates a field > value condition.

func FieldIsGreaterOrEqual

func FieldIsGreaterOrEqual(field Field, operandType OperandType, value any) Condition

FieldIsGreaterOrEqual creates a field >= value condition.

func FieldIsInAny

func FieldIsInAny(field Field, values ...any) Condition

FieldIsInAny creates a field IN (values...) condition.

func FieldIsLess

func FieldIsLess(field Field, operandType OperandType, value any) Condition

FieldIsLess creates a field < value condition.

func FieldIsLessOrEqual

func FieldIsLessOrEqual(field Field, operandType OperandType, value any) Condition

FieldIsLessOrEqual creates a field <= value condition.

func FieldIsLike

func FieldIsLike(field Field, operandType OperandType, value any) Condition

FieldIsLike creates a field LIKE value condition.

func FieldIsNotBetween

func FieldIsNotBetween(field Field, low, high any) Condition

FieldIsNotBetween creates a field NOT BETWEEN low AND high condition.

func FieldIsNotEqual

func FieldIsNotEqual(field Field, operandType OperandType, value any) Condition

FieldIsNotEqual creates a field != value condition.

func FieldIsNotInAny

func FieldIsNotInAny(field Field, values ...any) Condition

FieldIsNotInAny creates a field NOT IN (values...) condition.

func FieldIsNotLike

func FieldIsNotLike(field Field, operandType OperandType, value any) Condition

FieldIsNotLike creates a field NOT LIKE value condition.

func FieldIsNotNull

func FieldIsNotNull(field Field) Condition

FieldIsNotNull creates a field IS NOT NULL condition.

func FieldIsNull

func FieldIsNull(field Field) Condition

FieldIsNull creates a field IS NULL condition.

func (Condition) Operands

func (c Condition) Operands() []Operand

Operands returns both operands of the condition as a slice.

type ConditionNode

type ConditionNode struct {
	Leaf  *Condition
	Left  *ConditionNode
	Right *ConditionNode
	Op    LogicOp
}

ConditionNode is a node in a boolean expression tree for WHERE clauses. Leaf nodes (Leaf != nil) hold a single Condition. Branch nodes (Left != nil) join two sub-expressions with a logical operator.

func (*ConditionNode) Columns added in v0.8.0

func (n *ConditionNode) Columns() []string

Columns returns all column names referenced in the condition tree.

func (*ConditionNode) IsLeaf

func (n *ConditionNode) IsLeaf() bool

IsLeaf returns true if this is a leaf node.

func (*ConditionNode) String added in v0.8.0

func (n *ConditionNode) String() string

String returns a human-readable representation of the condition tree, used as a fallback column name for CASE expressions without AS aliases.

func (*ConditionNode) ToDNF

func (n *ConditionNode) ToDNF() OneOrMore

ToDNF converts the condition tree to Disjunctive Normal Form. The result is a OneOrMore where each Conditions group is a conjunction (conditions ANDed together) and the outer slice is a disjunction (groups ORed). This allows arbitrary WHERE nesting to be evaluated by existing row filtering code.

type Conditions

type Conditions []Condition

Conditions is a slice of Condition values joined by AND within a single OR group.

type ConflictAction

type ConflictAction int

ConflictAction describes what to do when an INSERT violates a uniqueness constraint.

const (
	// ConflictActionNone is the default: propagate the error.
	ConflictActionNone ConflictAction = iota
	// ConflictActionDoNothing silently skips the offending row.
	ConflictActionDoNothing
	// ConflictActionDoUpdate applies the SET assignments to the conflicting row.
	ConflictActionDoUpdate
)

type Cursor

type Cursor struct {
	Table      *Table
	PageIdx    PageIndex
	CellIdx    uint32
	EndOfTable bool
}

Cursor is a position within a table's B+ tree used to traverse or modify rows.

func (*Cursor) LeafNodeInsert

func (c *Cursor) LeafNodeInsert(ctx context.Context, key RowID, row Row) error

LeafNodeInsert inserts a row at the cursor's current position, splitting the leaf node if necessary.

func (*Cursor) LeafNodeSplitInsert

func (c *Cursor) LeafNodeSplitInsert(ctx context.Context, key RowID, row Row) error

LeafNodeSplitInsert creates a new leaf node, moves half the cells over, inserts the new value, and updates or creates a parent internal node.

type DBFile

type DBFile interface {
	io.ReadSeeker
	io.ReaderAt
	io.WriterAt
	io.Closer
	Sync() error
}

DBFile ...

type DDLChanges

type DDLChanges struct {
	CreateIndexes map[string]SecondaryIndex
	DropIndexes   map[string]SecondaryIndex
	CreateTables  []*Table
	DropTables    []string
}

DDLChanges accumulates schema modifications made within a single transaction.

func (DDLChanges) CreatedIndex

func (d DDLChanges) CreatedIndex(tableName string, index SecondaryIndex) DDLChanges

CreatedIndex records an index creation in the DDL change set.

func (DDLChanges) CreatedTable

func (d DDLChanges) CreatedTable(t *Table) DDLChanges

CreatedTable records a table creation in the DDL change set.

func (DDLChanges) DroppedIndex

func (d DDLChanges) DroppedIndex(tableName string, index SecondaryIndex) DDLChanges

DroppedIndex records an index drop in the DDL change set.

func (DDLChanges) DroppedTable

func (d DDLChanges) DroppedTable(tableName string) DDLChanges

DroppedTable records a table drop in the DDL change set.

func (DDLChanges) HasChanges

func (d DDLChanges) HasChanges() bool

HasChanges reports whether there are any uncommitted DDL changes.

type DDLSaver

type DDLSaver interface {
	SaveDDLChanges(ctx context.Context, changes DDLChanges)
}

DDLSaver ...

type Database

type Database struct {
	// contains filtered or unexported fields
}

Database is the top-level embedded SQL database instance.

func NewDatabase

func NewDatabase(ctx context.Context, logger *zap.Logger, dbFilePath string, parser Parser, factory PagerFactory, saver PageSaver, walCfg *WALConfig, opts ...DatabaseOption) (*Database, error)

NewDatabase creates a new database. walCfg wires in the Write-Ahead Log; pass nil for in-memory/test databases that do not require WAL (commits fall back to writing directly to the pager).

func (*Database) Analyze

func (d *Database) Analyze(ctx context.Context, target string) error

Analyze gathers statistics for all tables (or a specific target) and stores them in the stats table.

func (*Database) Checkpoint added in v0.12.0

func (d *Database) Checkpoint(_ context.Context) error

Checkpoint checkpoints the WAL into the database file and truncates the WAL. It is a no-op when no WAL is configured.

Checkpoint blocks new WAL writers until it completes. Readers are not blocked: they continue to use the (now being reset) WAL index, which is fine because the pager cache still holds the correct pages and the DB file is being written with the same data.

func (*Database) Close

func (d *Database) Close() error

Close flushes and closes the underlying page storage.

func (*Database) ExecuteStatement

func (d *Database) ExecuteStatement(ctx context.Context, stmt Statement) (StatementResult, error)

ExecuteStatement executes a single statement and returns the result

func (*Database) GetDDLSaver

func (d *Database) GetDDLSaver() DDLSaver

GetDDLSaver returns the DDLSaver interface backed by this database.

func (*Database) GetFileName

func (d *Database) GetFileName() string

GetFileName returns the database file name

func (*Database) GetSaver

func (d *Database) GetSaver() PageSaver

GetSaver returns the page saver for this database

func (*Database) GetTable

func (d *Database) GetTable(ctx context.Context, name string) (*Table, bool)

GetTable retrieves a table by name in a thread-safe manner. CTE virtual tables registered in the context shadow real tables of the same name.

func (*Database) GetTransactionManager

func (d *Database) GetTransactionManager() *TransactionManager

GetTransactionManager returns the transaction manager for this database

func (*Database) IntegrityCheck added in v0.5.0

func (d *Database) IntegrityCheck(ctx context.Context) (IntegrityReport, error)

IntegrityCheck performs a deeper structural walk of the database file.

In addition to QuickCheck, it traverses reachable table, index, and overflow pages from schema roots, reports orphan pages, and flags pages that appear in both live structures and the free list.

func (*Database) ListTableNames

func (d *Database) ListTableNames(ctx context.Context) []string

ListTableNames lists names of all tables in the database

func (*Database) PrepareStatement

func (d *Database) PrepareStatement(ctx context.Context, query string) (Statement, error)

PrepareStatement parses and caches a SQL statement, returning the parsed Statement.

func (*Database) PrepareStatements

func (d *Database) PrepareStatements(ctx context.Context, sql string) ([]Statement, error)

PrepareStatements parses SQL into a slice of Statement struct

func (*Database) QuickCheck added in v0.4.0

func (d *Database) QuickCheck(ctx context.Context) (IntegrityReport, error)

QuickCheck performs a cheap structural health check of the open database.

It validates header-linked free-list metadata and the decodability/shape of table and index root pages, but it does not walk full B-tree contents or cross-check tables against indexes.

func (*Database) Reopen

func (d *Database) Reopen(ctx context.Context, factory PagerFactory, saver PageSaver) error

Reopen replaces the pager and transaction manager with fresh instances backed by the given factory and saver.

func (*Database) SaveDDLChanges

func (d *Database) SaveDDLChanges(ctx context.Context, changes DDLChanges)

SaveDDLChanges applies committed DDL changes (table/index creates and drops) to the in-memory schema.

func (*Database) Vacuum

func (d *Database) Vacuum(ctx context.Context) error

Vacuum compacts the database file by copying all live data into a fresh file, then atomically replacing the original. The algorithm is:

  1. Create a temporary database file with its own pager.
  2. Acquire the exclusive database write lock, blocking all concurrent reads and writes for the duration.
  3. Recreate every table schema (tables first, indexes second) in the temp DB.
  4. Copy every row from the live DB into the temp DB.
  5. Flush and close both the temp DB and the live DB.
  6. Safe atomic file swap: a. Rename live → live.bak b. Rename temp → live (on failure, restore live from live.bak) c. Remove live.bak
  7. Reopen the database with a fresh pager and transaction manager.

Crash-safety: if the process crashes between steps 6a and 6b the original data is intact in live.bak. On restart the caller should check for a live.bak file and rename it back if the expected database file is missing.

VACUUM must not be called from inside an explicit user transaction; doing so returns an error.

type DatabaseHeader

type DatabaseHeader struct {
	FirstFreePage PageIndex // Points to first free page, 0 if none
	FreePageCount uint32    // Number of free pages available
}

DatabaseHeader stores the global database state persisted at the start of the first page.

func (*DatabaseHeader) Marshal

func (h *DatabaseHeader) Marshal() ([]byte, error)

Marshal serialises the database header to a byte slice.

func (*DatabaseHeader) Size

func (h *DatabaseHeader) Size() uint64

Size returns the fixed serialised byte size of the database header.

type DatabaseOption

type DatabaseOption func(*Database)

DatabaseOption is a functional option for configuring a Database.

func WithMaxCachedStatements

func WithMaxCachedStatements(maxStatements int) DatabaseOption

WithMaxCachedStatements configures the maximum number of prepared statements to keep in the LRU cache.

func WithParallelScanEnabled added in v0.51.0

func WithParallelScanEnabled() DatabaseOption

WithParallelScanEnabled turns on concurrent leaf-page scanning for all user tables.

type Direction

type Direction int

Direction ...

const (
	// Asc ...
	Asc Direction = iota + 1
	// Desc is the descending sort direction.
	Desc
)

Direction constants define the sort order for ORDER BY clauses.

func (Direction) String

func (d Direction) String() string

type ErrCheckConstraintViolation added in v0.41.0

type ErrCheckConstraintViolation struct {
	ColumnName string
	Expr       string
}

ErrCheckConstraintViolation is returned when an INSERT or UPDATE row fails a CHECK constraint.

func (ErrCheckConstraintViolation) Error added in v0.41.0

type ErrForeignKeyParentViolation added in v0.52.0

type ErrForeignKeyParentViolation struct {
	ParentTable   string
	ParentColumns []string
	ChildTable    string
	ChildColumns  []string
}

ErrForeignKeyParentViolation is returned when deleting or updating a parent row that is still referenced by one or more child rows.

func (ErrForeignKeyParentViolation) Error added in v0.52.0

type ErrForeignKeyViolation added in v0.52.0

type ErrForeignKeyViolation struct {
	ChildTable    string
	ChildColumns  []string
	ParentTable   string
	ParentColumns []string
}

ErrForeignKeyViolation is returned when a child row's FK value does not exist in the parent table.

func (ErrForeignKeyViolation) Error added in v0.52.0

func (e ErrForeignKeyViolation) Error() string

type ExcludedRef added in v0.2.0

type ExcludedRef struct {
	Column string
}

ExcludedRef represents a reference to EXCLUDED.column_name inside an ON CONFLICT DO UPDATE SET clause. At upsert time it resolves to the value that was proposed for insertion but rejected due to the conflict.

type Expr added in v0.4.0

type Expr struct {
	Literal        any
	Right          *Expr
	CaseElse       *Expr
	CaseInput      *Expr
	Left           *Expr
	CastExpr       *Expr
	FuncName       string
	Column         string
	Args           []*Expr
	CaseClauses    []CaseWhen
	CastTargetType ColumnKind
	Op             ArithOp
	IsNull         bool
}

Expr is an arithmetic expression tree node. Exactly one interpretation is active (checked in priority order):

  • CaseClauses != nil: a CASE WHEN expression
  • FuncName != "": a built-in function call (Args holds the arguments)
  • CastExpr != nil: a CAST(expr AS type) expression
  • IsNull: an explicit NULL literal
  • Column != "": a column reference (read value from the row)
  • Literal != nil: a scalar literal (int64, float64, bool, TextPointer)
  • Left != nil && Op != 0: a binary arithmetic operation

func (*Expr) Columns added in v0.4.0

func (e *Expr) Columns() []string

Columns returns all column names referenced by this expression.

func (*Expr) Eval added in v0.4.0

func (e *Expr) Eval(row Row) (any, error)

Eval evaluates the expression against a row, returning a numeric result. NULL propagates: any NULL operand produces a nil result. Returns int64 when both operands are int64 (except division, which always returns float64). Returns float64 when either operand is float64.

func (*Expr) String added in v0.4.0

func (e *Expr) String() string

String returns a human-readable representation suitable for use as a default column name.

type FKAction added in v0.52.0

type FKAction int

FKAction defines the referential action for ON DELETE / ON UPDATE.

const (
	// FKActionRestrict rejects the operation if it would break the FK constraint.
	FKActionRestrict FKAction = iota + 1
	// FKActionNoAction is the same as RESTRICT in this implementation (no deferred checks).
	FKActionNoAction
	// FKActionSetNull sets the FK column(s) to NULL when the referenced row is deleted/updated.
	FKActionSetNull
	// FKActionCascade propagates the delete/update to child rows.
	FKActionCascade
)

func (FKAction) String added in v0.52.0

func (a FKAction) String() string

type Field

type Field struct {
	Expr        *Expr
	AliasPrefix string
	Name        string
	Alias       string
}

Field ...

func (Field) OutputName added in v0.4.0

func (f Field) OutputName() string

OutputName returns the name to use for this field in result column metadata. For computed expressions it returns the Alias (if set) or the expression string.

func (Field) String

func (f Field) String() string

type Flusher

type Flusher interface {
	TotalPages() uint32
	Flush(context.Context, PageIndex) error
	FlushBatch(context.Context, []PageIndex) error
	Close() error
}

Flusher ...

type ForeignKey added in v0.52.0

type ForeignKey struct {
	Name          string
	Columns       []string // local (child) columns
	TargetTable   string   // referenced (parent) table
	TargetColumns []string // referenced columns in parent table
	OnDelete      FKAction // default FKActionRestrict
	OnUpdate      FKAction // default FKActionRestrict
}

ForeignKey describes a FOREIGN KEY constraint on one or more child table columns.

type FreePage

type FreePage struct {
	NextFreePage PageIndex // Points to next free page, 0 if last

}

FreePage reuses the existing page structure for tracking free (unused) pages.

func (*FreePage) Marshal

func (n *FreePage) Marshal(buf []byte) error

Marshal ...

func (*FreePage) Unmarshal

func (n *FreePage) Unmarshal(buf []byte) error

Unmarshal ...

type Function

type Function struct {
	Name string
}

Function ...

type Header struct {
	IsInternal bool
	IsRoot     bool
	Parent     PageIndex
}

Header ...

func (*Header) Marshal

func (h *Header) Marshal(buf []byte)

Marshal ...

func (*Header) Size

func (h *Header) Size() uint64

Size ...

func (*Header) Unmarshal

func (h *Header) Unmarshal(buf []byte) (uint64, error)

Unmarshal ...

type Histogram added in v0.50.0

type Histogram struct {
	Bounds []float64
}

Histogram is an equi-depth histogram for a numeric index column. Bounds contains numBuckets+1 boundary values: Bounds[0] is the minimum observed value, Bounds[N] is the maximum. Each of the N buckets between consecutive boundaries holds approximately the same number of entries.

type ICell

type ICell struct {
	Key   RowID
	Child PageIndex
}

ICell ...

func (*ICell) Marshal

func (c *ICell) Marshal(buf []byte)

Marshal ...

func (*ICell) Size

func (c *ICell) Size() uint64

Size ...

func (*ICell) Unmarshal

func (c *ICell) Unmarshal(buf []byte) (uint64, error)

Unmarshal ...

type Index

type Index[T IndexKey] struct {
	Name    string
	Columns []Column
	// contains filtered or unexported fields
}

Index ...

func NewNonUniqueIndex

func NewNonUniqueIndex[T IndexKey](logger *zap.Logger, txManager *TransactionManager, name string, columns []Column, pager TxPager, rootPageIdx PageIndex) (*Index[T], error)

NewNonUniqueIndex ...

func NewUniqueIndex

func NewUniqueIndex[T IndexKey](logger *zap.Logger, txManager *TransactionManager, name string, columns []Column, pager TxPager, rootPageIdx PageIndex) (*Index[T], error)

NewUniqueIndex ...

func (*Index[T]) BFS

func (ui *Index[T]) BFS(ctx context.Context, f indexCallback) error

BFS ...

func (*Index[T]) Delete

func (ui *Index[T]) Delete(ctx context.Context, keyAny any, rowID RowID) error

Delete ...

func (*Index[T]) FindRowIDs

func (ui *Index[T]) FindRowIDs(ctx context.Context, keyAny any) ([]RowID, error)

FindRowIDs ...

func (*Index[T]) GetRootPageIdx

func (ui *Index[T]) GetRootPageIdx() PageIndex

GetRootPageIdx ...

func (*Index[T]) Insert

func (ui *Index[T]) Insert(ctx context.Context, keyAny any, rowID RowID) error

Insert ...

func (*Index[T]) ScanAll

func (ui *Index[T]) ScanAll(ctx context.Context, reverse bool, callback indexScanner) error

ScanAll iterates over all keys in the index in order using in-order traversal

func (*Index[T]) ScanRange

func (ui *Index[T]) ScanRange(ctx context.Context, rangeCondition RangeCondition, reverse bool, callback indexScanner) error

ScanRange scans keys within the specified range using in-order traversal with range checks.

func (*Index[T]) Seek

func (ui *Index[T]) Seek(ctx context.Context, page *Page, keyAny any) (IndexCursor[T], bool, error)

Seek ...

func (*Index[T]) SeekLastKey

func (ui *Index[T]) SeekLastKey(ctx context.Context, pageIdx PageIndex) (any, error)

SeekLastKey returns the largest key in the index, used for autoincrement primary keys.

func (*Index[T]) SeekWithPrefix

func (ui *Index[T]) SeekWithPrefix(ctx context.Context, page *Page, prefixAny any, prefixColumns int) (IndexCursor[T], bool, error)

SeekWithPrefix ...

type IndexCell

type IndexCell[T IndexKey] struct {
	Key          T
	RowIDs       []RowID
	UniqueRowID  RowID
	InlineRowIDs uint32
	Overflow     PageIndex
	Child        PageIndex
	// contains filtered or unexported fields
}

IndexCell holds a single key entry within an index node, along with its associated row IDs and child pointer.

func NewIndexCell

func NewIndexCell[T IndexKey](unique bool) IndexCell[T]

NewIndexCell ...

func (*IndexCell[T]) Clone

func (c *IndexCell[T]) Clone() IndexCell[T]

Clone ...

func (*IndexCell[T]) Marshal

func (c *IndexCell[T]) Marshal(buf []byte) error

Marshal ...

func (*IndexCell[T]) RemoveRowID

func (c *IndexCell[T]) RemoveRowID(id RowID) int

RemoveRowID ...

func (*IndexCell[T]) ReplaceRowID

func (c *IndexCell[T]) ReplaceRowID(id, newID RowID) int

ReplaceRowID ...

func (*IndexCell[T]) Size

func (c *IndexCell[T]) Size() uint64

Size ...

func (*IndexCell[T]) Unmarshal

func (c *IndexCell[T]) Unmarshal(columns []Column, buf []byte) (uint64, error)

Unmarshal ...

type IndexCursor

type IndexCursor[T IndexKey] struct {
	Index   *Index[T]
	PageIdx PageIndex
	CellIdx uint32
}

IndexCursor holds a position within an index, grouping page and cell index. TODO - currently this struct has no methods; consider merging into Index or adding useful methods.

type IndexInfo

type IndexInfo struct {
	Name    string
	Columns []Column
}

IndexInfo ...

type IndexKey

type IndexKey interface {
	int8 | int32 | int64 | float32 | float64 | string | CompositeKey
}

IndexKey ...

type IndexNode

type IndexNode[T IndexKey] struct {
	Cells  []IndexCell[T]
	Header IndexNodeHeader
	// contains filtered or unexported fields
}

IndexNode is a B+ tree node used by the index, containing a header and a slice of index cells.

func NewIndexNode

func NewIndexNode[T IndexKey](unique bool, cells ...IndexCell[T]) *IndexNode[T]

NewIndexNode creates a new IndexNode with the given uniqueness flag and optional initial cells.

func NewRootIndexNode

func NewRootIndexNode[T IndexKey](unique bool, cells ...IndexCell[T]) *IndexNode[T]

NewRootIndexNode ...

func (*IndexNode[T]) AppendCells

func (n *IndexNode[T]) AppendCells(cells ...IndexCell[T])

AppendCells ...

func (*IndexNode[T]) AtLeastHalfFull

func (n *IndexNode[T]) AtLeastHalfFull() bool

AtLeastHalfFull ...

func (*IndexNode[T]) AvailableSpace

func (n *IndexNode[T]) AvailableSpace() uint64

AvailableSpace returns the number of free bytes in this node (O(1) via cached freeBytes).

func (*IndexNode[T]) Child

func (n *IndexNode[T]) Child(childIdx uint32) (PageIndex, error)

Child returns a node index of nth child of the node marked by its index (0 for the leftmost child, index equal to number of keys means the rightmost child).

func (*IndexNode[T]) Children

func (n *IndexNode[T]) Children() []PageIndex

Children ...

func (*IndexNode[T]) Clone

func (n *IndexNode[T]) Clone() *IndexNode[T]

Clone ...

func (*IndexNode[T]) DeleteKeyAndRightChild

func (n *IndexNode[T]) DeleteKeyAndRightChild(idx uint32) error

DeleteKeyAndRightChild removes the key at idx plus the right child pointer from the index node.

func (*IndexNode[T]) FirstCell

func (n *IndexNode[T]) FirstCell() IndexCell[T]

FirstCell ...

func (*IndexNode[T]) GetRightChildByIndex

func (n *IndexNode[T]) GetRightChildByIndex(idx uint32) PageIndex

GetRightChildByIndex ...

func (*IndexNode[T]) HasSpaceForKey

func (n *IndexNode[T]) HasSpaceForKey(key T) bool

HasSpaceForKey ...

func (*IndexNode[T]) Keys

func (n *IndexNode[T]) Keys() []T

Keys ...

func (*IndexNode[T]) LastCell

func (n *IndexNode[T]) LastCell() IndexCell[T]

LastCell ...

func (*IndexNode[T]) Marshal

func (n *IndexNode[T]) Marshal(buf []byte) error

Marshal ...

func (*IndexNode[T]) MaxSpace

func (n *IndexNode[T]) MaxSpace() uint64

MaxSpace ...

func (*IndexNode[T]) PrependCell

func (n *IndexNode[T]) PrependCell(cell IndexCell[T])

PrependCell ...

func (*IndexNode[T]) RemoveFirstCell

func (n *IndexNode[T]) RemoveFirstCell()

RemoveFirstCell ...

func (*IndexNode[T]) RemoveLastCell

func (n *IndexNode[T]) RemoveLastCell() IndexCell[T]

RemoveLastCell ...

func (*IndexNode[T]) RowIDs

func (n *IndexNode[T]) RowIDs() []RowID

RowIDs returns inlined row IDs; there could be more row IDs in overflow pages, so keep that in mind when working with non-unique indexes.

func (*IndexNode[T]) SetChild

func (n *IndexNode[T]) SetChild(idx uint32, childPage PageIndex) error

SetChild ...

func (*IndexNode[T]) Size

func (n *IndexNode[T]) Size() uint64

Size ...

func (*IndexNode[T]) SplitInHalves

func (n *IndexNode[T]) SplitInHalves(unique bool) (uint32, uint32)

SplitInHalves ...

func (*IndexNode[T]) TakenSpace

func (n *IndexNode[T]) TakenSpace() uint64

TakenSpace ...

func (*IndexNode[T]) Unmarshal

func (n *IndexNode[T]) Unmarshal(columns []Column, buf []byte) (uint64, error)

Unmarshal ...

type IndexNodeHeader

type IndexNodeHeader struct {
	IsRoot     bool
	IsLeaf     bool
	Parent     PageIndex
	Keys       uint32
	RightChild PageIndex
}

IndexNodeHeader ...

func (*IndexNodeHeader) Marshal

func (h *IndexNodeHeader) Marshal(buf []byte)

Marshal ...

func (*IndexNodeHeader) Size

func (h *IndexNodeHeader) Size() (s uint64)

Size ...

func (*IndexNodeHeader) Unmarshal

func (h *IndexNodeHeader) Unmarshal(buf []byte) (uint64, error)

Unmarshal ...

type IndexOverflowPage

type IndexOverflowPage struct {
	RowIDs []RowID
	Header IndexOverflowPageHeader
}

IndexOverflowPage ...

func (*IndexOverflowPage) LastRowID

func (h *IndexOverflowPage) LastRowID() RowID

LastRowID ...

func (*IndexOverflowPage) Marshal

func (h *IndexOverflowPage) Marshal(buf []byte) error

Marshal ...

func (*IndexOverflowPage) RemoveLastRowID

func (h *IndexOverflowPage) RemoveLastRowID() RowID

RemoveLastRowID ...

func (*IndexOverflowPage) Size

func (h *IndexOverflowPage) Size() uint64

Size ...

func (*IndexOverflowPage) Unmarshal

func (h *IndexOverflowPage) Unmarshal(buf []byte) error

Unmarshal ...

type IndexOverflowPageHeader

type IndexOverflowPageHeader struct {
	NextPage  PageIndex // 0 if last page
	ItemCount uint32    // how many row IDs are stored in this page
}

IndexOverflowPageHeader ...

func (*IndexOverflowPageHeader) Size

func (h *IndexOverflowPageHeader) Size() uint64

Size ...

type IndexStats

type IndexStats struct {
	NDistinct []int64
	NEntry    int64
	Hist      *Histogram // nil when not collected or column type is non-numeric
}

IndexStats holds parsed statistics for an index

func (IndexStats) EstimateRangeRows

func (s IndexStats) EstimateRangeRows(rangeCondition RangeCondition, columnIndex int) int64

EstimateRangeRows estimates the number of rows that will match a range condition. Returns the estimated row count, or -1 if estimation isn't possible. Uses histogram data when available, otherwise assumes uniform distribution.

func (IndexStats) Selectivity

func (s IndexStats) Selectivity() float64

Selectivity returns the selectivity of the index (0.0 to 1.0) Higher selectivity means more distinct values relative to total entries For composite indexes, uses the final column prefix

type IntegrityIssue added in v0.4.0

type IntegrityIssue struct {
	Code    string
	Message string
	Page    *PageIndex
	Object  string
}

IntegrityIssue represents a single integrity problem discovered by a check.

type IntegrityReport added in v0.4.0

type IntegrityReport struct {
	Issues            []IntegrityIssue
	CheckedRootPages  int
	CheckedFreePages  int
	CheckedLivePages  int
	TotalPages        uint32
	FreeListPageCount uint32
}

IntegrityReport summarises the result of an integrity check.

func (IntegrityReport) Ok added in v0.4.0

func (r IntegrityReport) Ok() bool

Ok returns true when the integrity check found no issues.

type InternalNode

type InternalNode struct {
	Header InternalNodeHeader
	ICells [InternalNodeMaxCells]ICell
}

InternalNode ...

func NewInternalNode

func NewInternalNode() *InternalNode

NewInternalNode ...

func (*InternalNode) AppendCells

func (n *InternalNode) AppendCells(cells ...ICell)

AppendCells ...

func (*InternalNode) AtLeastHalfFull

func (n *InternalNode) AtLeastHalfFull(maxIcells int) bool

AtLeastHalfFull ...

func (*InternalNode) Child

func (n *InternalNode) Child(childIdx uint32) (PageIndex, error)

Child returns a node index of nth child of the node marked by its index (0 for the leftmost child, index equal to number of keys means the rightmost child).

func (*InternalNode) Children

func (n *InternalNode) Children() []PageIndex

Children ...

func (*InternalNode) Clone

func (n *InternalNode) Clone() *InternalNode

Clone ...

func (*InternalNode) DeleteKeyAndRightChild

func (n *InternalNode) DeleteKeyAndRightChild(idx uint32) error

DeleteKeyAndRightChild removes the key at idx plus the right child pointer from the internal node.

func (*InternalNode) FirstCell

func (n *InternalNode) FirstCell() ICell

FirstCell ...

func (*InternalNode) GetRightChildByIndex

func (n *InternalNode) GetRightChildByIndex(idx uint32) PageIndex

GetRightChildByIndex ...

func (*InternalNode) IndexOfChild

func (n *InternalNode) IndexOfChild(key RowID) uint32

IndexOfChild returns the index of the child which should contain the given key. For example, if node has 2 keys, this could return 0 for the leftmost child, 1 for the middle child or 2 for the rightmost child. The returned value is not a node index!

func (*InternalNode) IndexOfPage

func (n *InternalNode) IndexOfPage(pageIdx PageIndex) (uint32, error)

IndexOfPage returns index of child which contains page number

func (*InternalNode) Keys

func (n *InternalNode) Keys() []RowID

Keys ...

func (*InternalNode) LastCell

func (n *InternalNode) LastCell() ICell

LastCell ...

func (*InternalNode) Marshal

func (n *InternalNode) Marshal(buf []byte) error

Marshal ...

func (*InternalNode) MoreThanHalfFull

func (n *InternalNode) MoreThanHalfFull(maxIcells int) bool

MoreThanHalfFull ...

func (*InternalNode) PrependCell

func (n *InternalNode) PrependCell(cell ICell)

PrependCell ...

func (*InternalNode) RemoveFirstCell

func (n *InternalNode) RemoveFirstCell()

RemoveFirstCell ...

func (*InternalNode) RemoveLastCell

func (n *InternalNode) RemoveLastCell()

RemoveLastCell ...

func (*InternalNode) SetChild

func (n *InternalNode) SetChild(idx uint32, childPage PageIndex) error

SetChild ...

func (*InternalNode) Size

func (n *InternalNode) Size() uint64

Size ...

func (*InternalNode) Unmarshal

func (n *InternalNode) Unmarshal(buf []byte) (uint64, error)

Unmarshal ...

type InternalNodeHeader

type InternalNodeHeader struct {
	Header
	KeysNum    uint32
	RightChild PageIndex
}

InternalNodeHeader ...

func (*InternalNodeHeader) Marshal

func (h *InternalNodeHeader) Marshal(buf []byte)

Marshal ...

func (*InternalNodeHeader) Size

func (h *InternalNodeHeader) Size() (s uint64)

Size ...

func (*InternalNodeHeader) Unmarshal

func (h *InternalNodeHeader) Unmarshal(buf []byte) (uint64, error)

Unmarshal ...

type Interval added in v0.11.0

type Interval struct {
	Months int32 // total months component (years×12 + months)
	Micros int64 // fixed-duration component in microseconds
}

Interval represents a SQL interval with two components:

  • Months: calendar months (years×12 + months); variable-length because a month contains a different number of days depending on which month it is.
  • Micros: fixed-duration part in microseconds (weeks×7×86400×1e6 + days×86400×1e6 + …).

Separating months from the fixed-duration component mirrors PostgreSQL's internal representation: INTERVAL '1 month' cannot be expressed as a fixed number of microseconds, so it must be handled via calendar arithmetic.

func ParseIntervalString added in v0.11.0

func ParseIntervalString(s string) (Interval, error)

ParseIntervalString parses an interval specification string such as "3 days", "1 year 2 months", "-4 hours 30 minutes".

Supported units (case-insensitive, singular or plural):

year, month, week, day, hour, minute, second, microsecond

Weeks are converted to days (1 week = 7 days) and stored in Micros. Negative values are supported per-component: "-1 day 2 hours".

func (Interval) String added in v0.11.0

func (iv Interval) String() string

String returns a human-readable SQL representation, e.g. "INTERVAL '3 days 4 hours'".

type Iterator

type Iterator struct {
	// contains filtered or unexported fields
}

Iterator ...

func NewIterator

func NewIterator(rowFunc func(ctx context.Context) (Row, error)) Iterator

NewIterator ...

func NewSingleRowIterator

func NewSingleRowIterator(row Row) Iterator

NewSingleRowIterator ...

func NewSliceIterator added in v0.17.0

func NewSliceIterator(rows []Row) Iterator

NewSliceIterator returns an Iterator that yields rows from rows in order.

func (*Iterator) Close

func (i *Iterator) Close() error

Close ...

func (*Iterator) Err

func (i *Iterator) Err() error

Err ...

func (*Iterator) Next

func (i *Iterator) Next(ctx context.Context) bool

Next ...

func (*Iterator) Row

func (i *Iterator) Row() Row

Row ...

type Join

type Join struct {
	TableName  string
	TableAlias string
	Conditions Conditions
	Joins      []Join
	Type       JoinType
}

Join ...

func (Join) FromTableAlias

func (j Join) FromTableAlias() string

FromTableAlias ...

type JoinAlgorithm added in v0.47.0

type JoinAlgorithm int

JoinAlgorithm selects the execution strategy for a single join.

const (
	// JoinAlgorithmNestedLoop uses the existing nested-loop strategy: either an
	// index point-lookup on the inner table (when an index exists) or a full
	// sequential scan of the inner table for every outer row.
	JoinAlgorithmNestedLoop JoinAlgorithm = iota
	// JoinAlgorithmHash builds an in-memory hash table from the inner (build)
	// side once, then probes it for every outer row.  O(N+M) instead of O(N×M).
	// Only chosen when no index exists on the inner join column.
	JoinAlgorithmHash
)

type JoinColumnPair

type JoinColumnPair struct {
	BaseTableColumn Field
	JoinTableColumn Field
}

JoinColumnPair represents a pair of columns used in a JOIN ON condition

type JoinPlan

type JoinPlan struct {
	OuterJoinColumn string
	InnerJoinColumn string
	Conditions      Conditions
	JoinColumnPairs []JoinColumnPair
	Type            JoinType
	LeftScanIndex   int
	RightScanIndex  int
	Algorithm       JoinAlgorithm
}

JoinPlan represents a join operation between two scans

type JoinType

type JoinType int

JoinType ...

const (
	// Inner ...
	Inner JoinType = iota + 1
	// Left is a LEFT JOIN.
	Left
	// Right is a RIGHT JOIN.
	Right
)

JoinType constants enumerate the supported JOIN varieties.

type LRUCache

type LRUCache[T any] interface {
	Get(T) (any, bool)
	GetAndPromote(T) (any, bool)
	Put(T, any, bool)
	EvictIfNeeded() (T, bool)
}

LRUCache ...

type LeafNode

type LeafNode struct {
	Cells  []Cell
	Header LeafNodeHeader
}

LeafNode ...

func NewLeafNode

func NewLeafNode(cells ...Cell) *LeafNode

NewLeafNode ...

func (*LeafNode) AppendCells

func (n *LeafNode) AppendCells(cells ...Cell)

AppendCells ...

func (*LeafNode) AtLeastHalfFull

func (n *LeafNode) AtLeastHalfFull() bool

AtLeastHalfFull ...

func (*LeafNode) AvailableSpace

func (n *LeafNode) AvailableSpace() uint64

AvailableSpace ...

func (*LeafNode) CanBorrowFirst

func (n *LeafNode) CanBorrowFirst() bool

CanBorrowFirst ...

func (*LeafNode) CanBorrowLast

func (n *LeafNode) CanBorrowLast() bool

CanBorrowLast ...

func (*LeafNode) CanMergeWith

func (n *LeafNode) CanMergeWith(n2 *LeafNode) bool

CanMergeWith ...

func (*LeafNode) Clone

func (n *LeafNode) Clone() *LeafNode

Clone cretes a shallow copy of the leaf node, sharing value slices until they are about to be modified at which point PrepareModifyCell should be called to clone the value slice for that cell.

func (*LeafNode) DeepClone

func (n *LeafNode) DeepClone() *LeafNode

DeepClone ...

func (*LeafNode) Delete

func (n *LeafNode) Delete(key RowID) (Cell, bool)

Delete ...

func (*LeafNode) FirstCell

func (n *LeafNode) FirstCell() Cell

FirstCell ...

func (*LeafNode) HasSpaceForRow

func (n *LeafNode) HasSpaceForRow(row Row) bool

HasSpaceForRow ...

func (*LeafNode) Keys

func (n *LeafNode) Keys() []RowID

Keys ...

func (*LeafNode) LastCell

func (n *LeafNode) LastCell() Cell

LastCell ...

func (*LeafNode) Marshal

func (n *LeafNode) Marshal(buf []byte) error

Marshal ...

func (*LeafNode) MaxSpace

func (n *LeafNode) MaxSpace() uint64

MaxSpace ...

func (*LeafNode) PrepareModifyCell

func (n *LeafNode) PrepareModifyCell(idx uint32)

PrepareModifyCell ensures the cell at idx is copy-on-write safe before modification.

func (*LeafNode) PrependCell

func (n *LeafNode) PrependCell(cell Cell)

PrependCell ...

func (*LeafNode) RemoveFirstCell

func (n *LeafNode) RemoveFirstCell()

RemoveFirstCell ...

func (*LeafNode) RemoveLastCell

func (n *LeafNode) RemoveLastCell()

RemoveLastCell ...

func (*LeafNode) Size

func (n *LeafNode) Size() uint64

Size ...

func (*LeafNode) TakenSpace

func (n *LeafNode) TakenSpace() uint64

TakenSpace ...

func (*LeafNode) Unmarshal

func (n *LeafNode) Unmarshal(columns []Column, buf []byte) (uint64, error)

Unmarshal ...

type LeafNodeHeader

type LeafNodeHeader struct {
	Header
	Cells    uint32
	NextLeaf PageIndex
}

LeafNodeHeader ...

func (*LeafNodeHeader) Marshal

func (h *LeafNodeHeader) Marshal(buf []byte)

Marshal ...

func (*LeafNodeHeader) Size

func (h *LeafNodeHeader) Size() uint64

Size ...

func (*LeafNodeHeader) Unmarshal

func (h *LeafNodeHeader) Unmarshal(buf []byte) (uint64, error)

Unmarshal ...

type LogicOp

type LogicOp int

LogicOp represents a boolean logic operator (AND or OR) used in a ConditionNode.

const (
	// LogicOpAnd represents the SQL AND logical operator.
	LogicOpAnd LogicOp = iota + 1
	// LogicOpOr represents the SQL OR logical operator.
	LogicOpOr
)

type OneOrMore

type OneOrMore []Conditions

OneOrMore contains a slice of multiple groups of singular condition, each group joined by OR boolean operator. Every singular condition in each group is joined by AND with other conditions in the same slice.

func NewOneOrMore

func NewOneOrMore(conditionGroups ...Conditions) OneOrMore

NewOneOrMore creates a new OneOrMore from the given condition groups.

func (OneOrMore) Append

func (o OneOrMore) Append(cond Condition) OneOrMore

Append adds a condition to the last group, creating a new group if empty.

func (OneOrMore) LastCondition

func (o OneOrMore) LastCondition() (Condition, bool)

LastCondition returns the last condition in the last group, if any.

func (OneOrMore) UpdateLast

func (o OneOrMore) UpdateLast(cond Condition)

UpdateLast replaces the last condition in the last group.

type Operand

type Operand struct {
	Value any
	Type  OperandType
}

Operand holds a typed value on one side of a condition expression.

func (Operand) IsField

func (o Operand) IsField() bool

IsField determines whether the operand is a literal or a field name

type OperandType

type OperandType int

OperandType classifies the value on either side of a condition operator.

const (
	// OperandField means the operand is a table column name.
	OperandField OperandType = iota + 1
	OperandPlaceholder
	OperandNull
	OperandQuotedString
	OperandBoolean
	OperandInteger
	OperandFloat
	OperandList
	// OperandSubquery holds a *Statement SELECT that is evaluated before the
	// outer scan begins and replaced with a concrete scalar or list value.
	OperandSubquery
)

OperandType constants define the kinds of operand values.

type Operator

type Operator int

Operator represents a SQL comparison operator used in WHERE conditions.

const (
	// Eq -> "="
	Eq Operator = iota + 1
	// Ne -> "!="
	Ne
	// Gt -> ">"
	Gt
	// Lt -> "<"
	Lt
	// Gte -> ">="
	Gte
	// Lte -> "<="
	Lte
	// In -> "IN (...)"
	In
	// NotIn -> "NOT IN (...)"
	NotIn
	// Like -> "LIKE"
	Like
	// NotLike -> "NOT LIKE"
	NotLike
	// Between -> "BETWEEN ... AND ..."
	Between
	// NotBetween -> "NOT BETWEEN ... AND ..."
	NotBetween
)

func (Operator) String

func (o Operator) String() string

type OptionalValue

type OptionalValue struct {
	Value any
	Valid bool
}

OptionalValue ...

type OrderBy

type OrderBy struct {
	Field     Field
	Direction Direction
}

OrderBy ...

type OverflowPage

type OverflowPage struct {
	Data   []byte
	Header OverflowPageHeader
}

OverflowPage ...

func (*OverflowPage) Marshal

func (h *OverflowPage) Marshal(buf []byte) error

Marshal ...

func (*OverflowPage) Size

func (h *OverflowPage) Size() uint64

Size ...

func (*OverflowPage) Unmarshal

func (h *OverflowPage) Unmarshal(buf []byte) error

Unmarshal ...

type OverflowPageHeader

type OverflowPageHeader struct {
	NextPage PageIndex // 0 if last page
	DataSize uint32    // Actual data size in this page
}

OverflowPageHeader ...

func (*OverflowPageHeader) Size

func (h *OverflowPageHeader) Size() uint64

Size ...

type Page

type Page struct {
	IndexNode         any
	OverflowPage      *OverflowPage
	FreePage          *FreePage
	InternalNode      *InternalNode
	LeafNode          *LeafNode
	IndexOverflowNode *IndexOverflowPage
	Index             PageIndex
}

Page ...

func (*Page) Clear

func (p *Page) Clear()

Clear resets all node pointers on the page, preparing it for reuse.

func (*Page) Clone

func (p *Page) Clone() *Page

Clone creates a deep copy of the page.

type PageIndex

type PageIndex uint32

PageIndex ...

type PageSaver

type PageSaver interface {
	SavePage(context.Context, PageIndex, *Page)
	SaveHeader(context.Context, DatabaseHeader)
	SetWALIndex(*WALIndex)
	Flusher
}

PageSaver ...

type PageUnmarshaler

type PageUnmarshaler func(totalPages uint32, pageIdx PageIndex, buf []byte) (*Page, error)

PageUnmarshaler ...

type Pager

type Pager interface {
	GetPage(context.Context, PageIndex) (*Page, error)
	GetHeader(context.Context) DatabaseHeader
	TotalPages() uint32
}

Pager ...

type PagerFactory

type PagerFactory interface {
	ForTable([]Column) Pager
	ForIndex(columns []Column, unique bool) Pager
}

PagerFactory ...

type Parser

type Parser interface {
	Parse(context.Context, string) ([]Statement, error)
}

Parser ...

type Placeholder

type Placeholder struct{}

Placeholder ...

type PrimaryKey

type PrimaryKey struct {
	Index BTreeIndex
	IndexInfo
	Autoincrement bool
}

PrimaryKey ...

func NewPrimaryKey

func NewPrimaryKey(indexName string, columns []Column, autoincrement bool) PrimaryKey

NewPrimaryKey ...

type QueryPlan

type QueryPlan struct {
	Scans []Scan
	Joins []JoinPlan // JOIN operations to perform

	// Ordering
	OrderBy      []OrderBy
	SortInMemory bool
	SortReverse  bool
}

QueryPlan determines how to execute a query

func (QueryPlan) Execute

func (p QueryPlan) Execute(ctx context.Context, provider TableProvider, selectedFields []Field, out func(Row) error) error

Execute runs the query plan, calling out for every row produced. out receives each row synchronously on the caller's goroutine; no internal goroutines or channels are created. JOIN queries are the exception: they still drive executeNestedLoopJoin in a helper goroutine internally so that the nested-loop logic can use a channel, but the rows are forwarded to out before Execute returns.

type RangeBound

type RangeBound struct {
	Value     any
	Inclusive bool // true for >= or <=, false for > or <
}

RangeBound ...

type RangeCondition

type RangeCondition struct {
	Lower *RangeBound // nil = unbounded
	Upper *RangeBound // nil = unbounded
}

RangeCondition ...

type Row

type Row struct {
	Columns []Column
	Values  []OptionalValue
	Key     RowID
}

Row ...

func NewRow

func NewRow(columns []Column) Row

NewRow ...

func NewRowWithValues

func NewRowWithValues(columns []Column, values []OptionalValue) Row

NewRowWithValues ...

func (Row) CheckConditions

func (r Row) CheckConditions(condGroup Conditions) (bool, error)

CheckConditions ...

func (Row) CheckOneOrMore

func (r Row) CheckOneOrMore(conditions OneOrMore) (bool, error)

CheckOneOrMore checks whether row satisfies one or more sets of conditions (cond1 AND cond2) OR (cond3 and cond4) ... etc

func (Row) CheckOneOrMoreWithColumnIndexes added in v0.23.0

func (r Row) CheckOneOrMoreWithColumnIndexes(conditions OneOrMore, columnIndexes map[string]int) (bool, error)

CheckOneOrMoreWithColumnIndexes is like CheckOneOrMore but uses pre-resolved column indexes for field lookups to avoid repeated linear scans by name.

func (Row) Clone

func (r Row) Clone() Row

Clone ...

func (Row) GetColumn

func (r Row) GetColumn(name string) (Column, int)

GetColumn returns the column and its index for the given name via linear scan.

func (Row) GetValue

func (r Row) GetValue(name string) (OptionalValue, bool)

GetValue returns the value for the given column name via linear scan.

func (Row) GetValuesForColumns

func (r Row) GetValuesForColumns(columns []Column) ([]OptionalValue, bool)

GetValuesForColumns ...

func (Row) Marshal

func (r Row) Marshal() ([]byte, error)

Marshal ...

func (Row) NullBitmask

func (r Row) NullBitmask() uint64

NullBitmask returns a bitmask representing which columns are NULL

func (Row) OnlyFields

func (r Row) OnlyFields(fields ...Field) Row

OnlyFields returns a new Row containing only the specified fields. The result is accessed positionally (Values[i]) by all downstream consumers (Rows.Next, rowDistinctKey, selectGroupBy, deduplicateRows). Name-based lookups via GetColumn/GetValue fall back to a linear scan if needed.

func (Row) SetValue

func (r Row) SetValue(name string, value OptionalValue) (Row, bool)

SetValue returns true if value has changed

func (Row) Size

func (r Row) Size() uint64

Size calculates a size of a row record excluding null bitmask and row ID

func (Row) Unmarshal

func (r Row) Unmarshal(cell Cell, selectedFields ...Field) (Row, error)

Unmarshal decodes cell into a Row. For columns not in selectedFields, an empty OptionalValue is inserted to maintain index alignment.

func (Row) UnmarshalWithMask added in v0.23.0

func (r Row) UnmarshalWithMask(cell Cell, selectedMask []bool) (Row, error)

UnmarshalWithMask decodes cell into a Row using a precomputed column-selection mask. selectedMask must have len == len(r.Columns). A nil/empty mask means "no fields selected" (keys only; values remain zero-value placeholders).

type RowID

type RowID uint64

RowID ...

type Scan

type Scan struct {
	RangeCondition RangeCondition
	TableName      string
	TableAlias     string
	IndexName      string
	IndexColumns   []Column
	IndexKeys      []any
	Filters        OneOrMore
	// SubScans holds the child index scans for ScanTypeIndexIntersect.
	// Each child is executed to collect RowIDs; surviving rows are fetched after intersection.
	SubScans      []Scan
	Type          ScanType
	CoveringIndex bool
}

Scan ...

type ScanType

type ScanType int

ScanType ...

const (
	// ScanTypeSequential is a full table scan.
	ScanTypeSequential ScanType = iota + 1
	// ScanTypeIndexAll is a full index scan.
	ScanTypeIndexAll
	// ScanTypeIndexPoint is an index lookup for specific key(s).
	ScanTypeIndexPoint
	// ScanTypeIndexRange is an index range scan.
	ScanTypeIndexRange
	// ScanTypeIndexFirst seeks to the first (smallest) key in the index — used for MIN optimisation.
	ScanTypeIndexFirst
	// ScanTypeIndexLast seeks to the last (largest) key in the index — used for MAX optimisation.
	ScanTypeIndexLast
	// ScanTypeIndexIntersect runs each sub-scan to collect RowID sets, intersects them in
	// memory, then fetches only the surviving rows.  Used for AND conditions where two or
	// more independent indexes are available.
	ScanTypeIndexIntersect
)

ScanType constants define the available index and table scan strategies.

func (ScanType) String

func (st ScanType) String() string

type Schema

type Schema struct {
	Name      string
	TableName string
	DDL       string
	Type      SchemaType
	RootPage  PageIndex
}

Schema represents a single row in the internal schema metadata table.

type SchemaType

type SchemaType int

SchemaType identifies the kind of object recorded in the schema table.

const (
	// SchemaTable identifies a user table entry in the schema.
	SchemaTable SchemaType = iota + 1
	SchemaPrimaryKey
	SchemaUniqueIndex
	SchemaSecondaryIndex
	// SchemaForeignKey identifies a foreign key constraint stored as a separate
	// schema row (Name = FK name, TableName = child table, DDL = serialised FK).
	SchemaForeignKey
)

SchemaType constants identify the kind of object recorded in the schema table.

type SecondaryIndex

type SecondaryIndex struct {
	Index BTreeIndex
	IndexInfo
}

SecondaryIndex ...

type Statement

type Statement struct {
	PrimaryKey        PrimaryKey
	Aliases           map[string]string
	Functions         map[string]Function
	Updates           map[string]OptionalValue
	Offset            OptionalValue
	Limit             OptionalValue
	TableName         string
	TableAlias        string
	IndexName         string
	Target            string
	PragmaName        string
	PragmaValue       string
	Fields            []Field
	Inserts           [][]OptionalValue
	Aggregates        []AggregateExpr
	GroupBy           []Field
	Having            OneOrMore
	Unions            []UnionClause
	Joins             []Join
	OrderBy           []OrderBy
	UniqueIndexes     []UniqueIndex
	ForeignKeys       []ForeignKey
	Columns           []Column
	Conditions        OneOrMore
	ReturningFields   []Field
	ExplainStatement  *Statement
	FromSubquery      *Statement // non-nil when FROM clause is a derived table
	FromSubqueryAlias string     // alias for the derived table (e.g. "t" in FROM (...) t)
	CTEs              []CTE      // non-nil for WITH … SELECT statements
	Kind              StatementKind
	ConflictAction    ConflictAction
	IfNotExists       bool
	ExplainAnalyze    bool
	Distinct          bool
}

Statement ...

func (Statement) AddJoin

func (s Statement) AddJoin(joinType JoinType, fromTableAlias, toTable, toTableAlias string, conditions Conditions) (Statement, error)

AddJoin ...

func (Statement) BindArguments

func (s Statement) BindArguments(args ...any) (Statement, error)

BindArguments ...

func (Statement) Clone

func (s Statement) Clone() Statement

Clone ...

func (Statement) ColumnByName

func (s Statement) ColumnByName(name string) (Column, bool)

ColumnByName ...

func (Statement) ColumnIdx

func (s Statement) ColumnIdx(name string) int

ColumnIdx ...

func (Statement) DDL

func (s Statement) DDL() string

DDL ...

func (Statement) HasField

func (s Statement) HasField(name string) bool

HasField ...

func (Statement) InsertValuesForColumns

func (s Statement) InsertValuesForColumns(insertIdx int, columns ...Column) []OptionalValue

InsertValuesForColumns ...

func (Statement) IsDDL

func (s Statement) IsDDL() bool

IsDDL ...

func (Statement) IsSelectAggregate

func (s Statement) IsSelectAggregate() bool

IsSelectAggregate returns true when the SELECT list contains at least one aggregate function (SUM, AVG, MIN, MAX). COUNT(*) alone uses the legacy IsSelectCountAll path and does NOT set this flag.

func (Statement) IsSelectAll

func (s Statement) IsSelectAll() bool

IsSelectAll ...

func (Statement) IsSelectCountAll

func (s Statement) IsSelectCountAll() bool

IsSelectCountAll ...

func (Statement) IsSelectGroupBy

func (s Statement) IsSelectGroupBy() bool

IsSelectGroupBy returns true when the SELECT has a GROUP BY clause.

func (Statement) NumPlaceholders

func (s Statement) NumPlaceholders() int

NumPlaceholders returns the number of placeholder parameters (?) in the statement.

func (Statement) Prepare

func (s Statement) Prepare(now Time) (Statement, error)

Prepare performs any necessary preparation on the statement before validation/execution.

func (Statement) ReadOnly

func (s Statement) ReadOnly() bool

ReadOnly ...

func (Statement) Validate

func (s Statement) Validate(table *Table) error

Validate ...

type StatementKind

type StatementKind int

StatementKind ...

const (
	// CreateTable ...
	CreateTable StatementKind = iota + 1
	DropTable
	CreateIndex
	DropIndex
	Insert
	Select
	Update
	Delete
	BeginTransaction
	CommitTransaction
	RollbackTransaction
	Analyze
	Vacuum
	Pragma
	Explain
)

StatementKind constants enumerate the supported SQL statement types.

func (StatementKind) String

func (s StatementKind) String() string

type StatementResult

type StatementResult struct {
	Rows         Iterator
	Columns      []Column
	RowsAffected int
	LastInsertId int64
}

StatementResult ...

type Stats

type Stats struct {
	TableName string
	IndexName string
	StatValue string
}

Stats holds a single row from the internal statistics table.

type SynchronousMode added in v0.32.0

type SynchronousMode int32

SynchronousMode controls when the WAL file is fsynced to disk.

The values mirror SQLite's PRAGMA synchronous settings for WAL mode:

  • SynchronousOff (0): no fsyncs at all — maximum performance, no durability guarantee.
  • SynchronousNormal (1): fsync only at checkpoint, not on every commit — SQLite WAL default.
  • SynchronousFull (2): fsync on every WAL commit — maximum durability.
const (
	// SynchronousOff skips all fsyncs. Fastest, but data loss is possible on crash.
	SynchronousOff SynchronousMode = 0
	// SynchronousNormal fsyncs only at checkpoint (SQLite WAL default).
	SynchronousNormal SynchronousMode = 1
	// SynchronousFull fsyncs after every WAL commit for maximum durability.
	SynchronousFull SynchronousMode = 2
)

type Table

type Table struct {
	PrimaryKey PrimaryKey

	UniqueIndexes    map[string]UniqueIndex
	SecondaryIndexes map[string]SecondaryIndex

	// ForeignKeys holds all outgoing FK constraints defined on this table.
	ForeignKeys []ForeignKey

	Name    string
	Columns []Column
	// contains filtered or unexported fields
}

Table ...

func NewTable

func NewTable(logger *zap.Logger, pager TxPager, txManager *TransactionManager, name string, columns []Column, rootPageIdx PageIndex, provider TableProvider, opts ...TableOption) *Table

NewTable ...

func (*Table) BFS

func (t *Table) BFS(ctx context.Context, f callback) error

BFS ...

func (*Table) ColumnByName

func (t *Table) ColumnByName(name string) (Column, bool)

ColumnByName ...

func (*Table) Delete

func (t *Table) Delete(ctx context.Context, stmt Statement) (StatementResult, error)

Delete ...

func (*Table) DeleteKey

func (t *Table) DeleteKey(ctx context.Context, pageIdx PageIndex, key RowID) error

DeleteKey deletes a key from the table, when this is called, you should already have located the leaf that contains the key and pass its page and cell index here. The deletion process starts at the leaf and then recursively bubbles up the tree.

func (*Table) GetMaxKey

func (t *Table) GetMaxKey(ctx context.Context, page *Page) (RowID, error)

GetMaxKey ...

func (*Table) GetRootPageIdx

func (t *Table) GetRootPageIdx() PageIndex

GetRootPageIdx ...

func (*Table) HasIndexOnColumn

func (t *Table) HasIndexOnColumn(name string) bool

HasIndexOnColumn ...

func (*Table) HasIndexOnColumns

func (t *Table) HasIndexOnColumns(columns []Column) bool

HasIndexOnColumns ...

func (*Table) HasNoIndex

func (t *Table) HasNoIndex() bool

HasNoIndex ...

func (*Table) HasPrimaryKey

func (t *Table) HasPrimaryKey() bool

HasPrimaryKey ...

func (*Table) IndexByName

func (t *Table) IndexByName(name string) (BTreeIndex, bool)

IndexByName ...

func (*Table) IndexColumnsByIndexName

func (t *Table) IndexColumnsByIndexName(name string) ([]Column, bool)

IndexColumnsByIndexName ...

func (*Table) IndexInfoByColumnName

func (t *Table) IndexInfoByColumnName(name string) (IndexInfo, bool)

IndexInfoByColumnName ...

func (*Table) IndexInfoByColumns

func (t *Table) IndexInfoByColumns(columns []Column) (IndexInfo, bool)

IndexInfoByColumns looks up an index whose columns (in order) exactly match the given slice.

func (*Table) Insert

func (t *Table) Insert(ctx context.Context, stmt Statement) (StatementResult, error)

Insert ...

func (*Table) InternalNodeInsert

func (t *Table) InternalNodeInsert(ctx context.Context, parentPageIdx, childPageIdx PageIndex) error

InternalNodeInsert adds a new child/key pair to the parent internal node corresponding to the given child page.

func (*Table) InternalNodeSplitInsert

func (t *Table) InternalNodeSplitInsert(ctx context.Context, pageIdx, childPageIdx PageIndex) error

InternalNodeSplitInsert splits an internal node and inserts the child. It creates a sibling to hold (n-1)/2 keys, updates the parent's max key, inserts the sibling into the parent (possibly triggering further splits), and creates a new root if the original node was the root.

func (*Table) PlanQuery

func (t *Table) PlanQuery(ctx context.Context, stmt Statement) (QueryPlan, error)

PlanQuery creates a query plan based on the statement and table schema. This is in no way a sophisticated query planner, but a simple heuristic-based approach to determine whether an index scan can be used based on the WHERE conditions.

Consider a table with the following schema: CREATE TABLE users (

id INTEGER PRIMARY KEY,
email TEXT UNIQUE,
non_indexed_col TEXT,
created TIMESTAMP DEFAULT NOW()

); CREATE INDEX "idx_created" ON "users" (created);

If we select without a WHERE clause, we default to a sequential scan: SELECT * from users;

If a WHERE clause cannot be fully satisfied by an index or combination of indexes, we fall back to a sequential scan.

Remember that if you have multiple conditions separated by OR, if a single one does not use an index, we have to do a sequential scan anyway. Also remember that non equality conditions using != or NOT IN or conditions comparing to NULL cannot use indexes.

SEQUENTIAL SCANS: ----------------- SELECT * from users WHERE non_indexed_col = 'baz'; SELECT * from users WHERE id = 1 OR non_indexed_col = 'baz'; SELECT * FROM users WHERE id = 1 OR id IS NULL; SELECT * FROM users WHERE pk NOT IN (1,2,3);

INDEX POINT SCANS: ------------------ When there are only equality conditions on indexed columns (primary key or unique indexes), we can do index point scans:

SELECT * from users WHERE id = 1; - single point scan on PK index SELECT * from users WHERE id IN (1, 2, 3); - single point scan on PK index SELECT * from users WHERE email = 'foo@example.com'; - single point scan on unique index SELECT * FROM users WHERE id = 1 OR id id = 2 OR email = 'foo@example.com'; - multiple point scans

RANGE SCANS: ------------ For >, >=, <, <= conditions on indexed columns, we can do range scans:

SELECT * FROM users WHERE id > 10 AND id < 20 AND non_indexed_col = 'baz'; - range scan on PK index

For OR conditions, we can do multiple range scans if each condition group has a range condition. For example, following query can be executed as two range scans, one on PK column and one on secondary index:

SELECT * FROM users WHERE (id >= 10 AND id <= 20) OR created >= '2024-01-01';

When combining range scans with ordering, we currently fall back to in-memory sort:

SELECT * FROM users WHERE id >= 10 AND id <= 20 ORDER BY created DESC;

ORDER BY: --------- SELECT * from users ORDER BY id DESC; - use PK index for ordering SELECT * from users ORDER BY created DESC; - use index on created for ordering SELECT * from users ORDER BY non_indexed_col; - order in memory

func (*Table) RemoveSecondaryIndex

func (t *Table) RemoveSecondaryIndex(name string)

RemoveSecondaryIndex ...

func (*Table) Seek

func (t *Table) Seek(ctx context.Context, key RowID) (*Cursor, error)

Seek the cursor for a key, if it does not exist then return the cursor for the page and cell where it should be inserted

func (*Table) SeekFirst

func (t *Table) SeekFirst(ctx context.Context) (*Cursor, error)

SeekFirst returns a cursor pointing at the first row in the table.

func (*Table) SeekLast

func (t *Table) SeekLast(ctx context.Context, pageIdx PageIndex) (*Cursor, error)

SeekLast returns cursor pointing at the last row in the table

func (*Table) SeekNextRowID

func (t *Table) SeekNextRowID(ctx context.Context, pageIdx PageIndex) (*Cursor, RowID, error)

SeekNextRowID returns cursor pointing at the position after the last row ID plus a new row ID to insert

func (*Table) Select

func (t *Table) Select(ctx context.Context, stmt Statement) (StatementResult, error)

Select ...

func (*Table) SetSecondaryIndex

func (t *Table) SetSecondaryIndex(name string, columns []Column, index BTreeIndex)

SetSecondaryIndex ...

func (*Table) Update

func (t *Table) Update(ctx context.Context, stmt Statement) (StatementResult, error)

Update executes an UPDATE statement on the table and returns the result.

type TableOption

type TableOption func(*Table)

TableOption ...

func WithChildFKChecker added in v0.52.0

func WithChildFKChecker(fn func(context.Context, Row) error) TableOption

WithChildFKChecker wires up a callback that checks outgoing FK constraints. Called by *Database; must only be invoked while d.dbLock is held (write).

func WithForeignKeys added in v0.52.0

func WithForeignKeys(fks []ForeignKey) TableOption

WithForeignKeys sets the outgoing FK constraints on the table.

func WithParallelScan added in v0.51.0

func WithParallelScan(enabled bool) TableOption

WithParallelScan enables or disables concurrent leaf-page scanning for this table.

func WithParentFKChecker added in v0.52.0

func WithParentFKChecker(fn func(context.Context, Row) error) TableOption

WithParentFKChecker wires up a callback that enforces inbound FK constraints on DELETE. Called by *Database; must only be invoked while d.dbLock is held (write).

func WithParentFKUpdateEnforcer added in v0.53.0

func WithParentFKUpdateEnforcer(fn func(context.Context, Row, Row) error) TableOption

WithParentFKUpdateEnforcer wires up a callback that enforces inbound FK constraints on UPDATE. Called by *Database; must only be invoked while d.dbLock is held (write).

func WithPrimaryKey

func WithPrimaryKey(pk PrimaryKey) TableOption

WithPrimaryKey ...

func WithReferencedColumns added in v0.52.0

func WithReferencedColumns(cols map[string]bool) TableOption

WithReferencedColumns marks which columns of this table are FK targets in other tables.

func WithRowCountGetter added in v0.29.0

func WithRowCountGetter(fn func() int64) TableOption

WithRowCountGetter sets an O(1) row-count accessor on the table. When set, COUNT(*) with no WHERE clause returns the value directly instead of performing a leaf-page walk.

func WithSecondaryIndex

func WithSecondaryIndex(index SecondaryIndex) TableOption

WithSecondaryIndex ...

func WithUniqueIndex

func WithUniqueIndex(index UniqueIndex) TableOption

WithUniqueIndex ...

type TableProvider

type TableProvider interface {
	GetTable(ctx context.Context, name string) (*Table, bool)
}

TableProvider provides thread-safe access to tables

type TextPointer

type TextPointer struct {
	Data      []byte
	Length    uint32
	FirstPage PageIndex
}

TextPointer is stored in the main row; text of length <= MaxInlineVarchar is stored inline, otherwise it points to an overflow page.

func NewTextPointer

func NewTextPointer(data []byte) TextPointer

NewTextPointer ...

func (TextPointer) IsEqual

func (tp TextPointer) IsEqual(tp2 TextPointer) bool

IsEqual ...

func (TextPointer) IsInline

func (tp TextPointer) IsInline() bool

IsInline ...

func (*TextPointer) Marshal

func (tp *TextPointer) Marshal(buf []byte, i uint64) error

Marshal ...

func (TextPointer) NumberOfPages

func (tp TextPointer) NumberOfPages() uint32

NumberOfPages ...

func (TextPointer) Size

func (tp TextPointer) Size() uint64

Size ...

func (TextPointer) String

func (tp TextPointer) String() string

func (*TextPointer) Unmarshal

func (tp *TextPointer) Unmarshal(buf []byte, i uint64) error

Unmarshal ...

type Time

type Time struct {
	Year         int32 // astonomical year numbering, e.g. 1 BC = year 0, 2 BC = -1, etc.
	Month        int8
	Day          int8
	Hour         int8
	Minutes      int8
	Seconds      int8
	Microseconds int32
}

Time is a custom type implementing a PostgreSQL-like TIMESTAMP type without timezone. low value 4713 BC high value 294276 AD

func FromMicroseconds

func FromMicroseconds(microseconds int64) Time

FromMicroseconds constructs a Time from microseconds since 2000-01-01 00:00:00 UTC.

func MustParseTimestamp

func MustParseTimestamp(timestampStr string) Time

MustParseTimestamp parses a timestamp string and panics on error.

func ParseTimestamp

func ParseTimestamp(timestampStr string) (Time, error)

ParseTimestamp parses a PostgreSQL-style timestamp string into a Time value.

func (Time) AddInterval added in v0.11.0

func (t Time) AddInterval(iv Interval, sign int32) Time

AddInterval adds (sign=+1) or subtracts (sign=-1) iv from t.

Month arithmetic is calendar-aware: adding 1 month to Jan 31 yields the last day of February (28 or 29 depending on the year). The day component of the interval uses fixed 86 400-second days, consistent with PostgreSQL.

func (Time) GoTime

func (t Time) GoTime() time.Time

GoTime converts the custom Time value to a standard library time.Time.

func (Time) String

func (t Time) String() string

func (Time) TotalMicroseconds

func (t Time) TotalMicroseconds() int64

TotalMicroseconds returns the microsecond count since 2000-01-01 00:00:00 UTC. Negative values represent dates before 2000-01-01 00:00:00 UTC.

type TimestampMicros added in v0.39.0

type TimestampMicros int64

TimestampMicros is the in-memory representation of a TIMESTAMP column value. It stores microseconds since 2000-01-01 00:00:00 UTC as a named int64 so that it is distinguishable from numeric int64 values in type switches, while still fitting inline in an any interface word — no heap allocation.

func MustParseTimestampMicros added in v0.39.0

func MustParseTimestampMicros(timestampStr string) TimestampMicros

MustParseTimestampMicros parses a timestamp string into a TimestampMicros and panics on error.

type Transaction

type Transaction struct {
	DDLChanges    DDLChanges
	StartTime     time.Time
	ReadSet       map[PageIndex]uint64
	WriteSet      map[PageIndex]WriteInfo
	DBHeaderRead  *uint64
	DBHeaderWrite *DatabaseHeader

	ID          TransactionID
	Status      TransactionStatus
	SnapshotSeq uint64

	ReadOnly bool
	// contains filtered or unexported fields
}

Transaction tracks the read and write sets for optimistic concurrency control.

func MustTxFromContext

func MustTxFromContext(ctx context.Context) *Transaction

MustTxFromContext retrieves the current transaction from the context and panics if none is present.

func TxFromContext

func TxFromContext(ctx context.Context) *Transaction

TxFromContext retrieves the current transaction from the context, or nil if none.

func (*Transaction) Abort

func (tx *Transaction) Abort()

Abort sets status to TxAborted and discards all in-memory changes.

func (*Transaction) AddRowCountDelta added in v0.29.0

func (tx *Transaction) AddRowCountDelta(table string, delta int64)

AddRowCountDelta records a net row-count change for the named table. It is a no-op for read-only transactions.

func (*Transaction) Commit

func (tx *Transaction) Commit()

Commit marks the transaction as committed.

func (*Transaction) GetDBHeaderReadVersion

func (tx *Transaction) GetDBHeaderReadVersion() (uint64, bool)

GetDBHeaderReadVersion returns the version of the database header as it was read, if any.

func (*Transaction) GetModifiedDBHeader

func (tx *Transaction) GetModifiedDBHeader() (*DatabaseHeader, bool)

GetModifiedDBHeader returns the in-memory modified database header, if any.

func (*Transaction) GetModifiedPage

func (tx *Transaction) GetModifiedPage(pageIdx PageIndex) (*Page, bool)

GetModifiedPage returns the in-memory modified copy of the page at pageIdx, if any.

func (*Transaction) GetReadVersion added in v0.26.0

func (tx *Transaction) GetReadVersion(pageIdx PageIndex) (uint64, bool)

GetReadVersion returns the version recorded when the given page was read, if any.

func (*Transaction) GetReadVersions

func (tx *Transaction) GetReadVersions() map[PageIndex]uint64

GetReadVersions returns a copy of the page read-version map.

func (*Transaction) GetWriteVersions

func (tx *Transaction) GetWriteVersions() map[PageIndex]WriteInfo

GetWriteVersions returns the transaction's write set.

func (*Transaction) RowCountDeltas added in v0.29.0

func (tx *Transaction) RowCountDeltas() map[string]int64

RowCountDeltas returns the accumulated row-count deltas. The returned map must not be modified by the caller.

func (*Transaction) TrackDBHeaderRead

func (tx *Transaction) TrackDBHeaderRead(version uint64)

TrackDBHeaderRead records the version of the database header when it was read. It is a no-op for read-only transactions.

func (*Transaction) TrackDBHeaderWrite

func (tx *Transaction) TrackDBHeaderWrite(header DatabaseHeader)

TrackDBHeaderWrite records a modified database header in the transaction write set.

func (*Transaction) TrackRead

func (tx *Transaction) TrackRead(pageIdx PageIndex, version uint64)

TrackRead records that the given page was read at the given version. It is a no-op for read-only transactions.

func (*Transaction) TrackWrite

func (tx *Transaction) TrackWrite(pageIdx PageIndex, page, originalPage *Page, table, index string)

TrackWrite records a modified page in the transaction write set. originalPage is the page as it was before modification; it is stored for MVCC snapshot reads and must not be nil for pages that existed prior to this transaction (use nil for newly-allocated pages).

type TransactionID

type TransactionID uint64

TransactionID is the unique identifier for a transaction.

type TransactionManager

type TransactionManager struct {
	// contains filtered or unexported fields
}

TransactionManager coordinates optimistic concurrency control for the database.

func NewTransactionManager

func NewTransactionManager(logger *zap.Logger, dbFilePath string, factory TxPagerFactory, saver PageSaver, ddlSaver DDLSaver) *TransactionManager

NewTransactionManager creates and returns a new TransactionManager.

func (*TransactionManager) BeginReadOnlyTransaction added in v0.17.0

func (tm *TransactionManager) BeginReadOnlyTransaction(ctx context.Context) *Transaction

BeginReadOnlyTransaction starts a read-only transaction with snapshot isolation. The transaction sees a consistent snapshot of the database as of the moment it begins: any write committed after this call is invisible to it. TrackRead calls are no-ops; conflict validation is skipped at commit time. Read-only transactions never return ErrTxConflict.

SnapshotSeq is captured inside tm.mu so it is atomic with the transaction registration — preventing a race where a write commits between the map insert and the seq capture.

func (*TransactionManager) BeginTransaction

func (tm *TransactionManager) BeginTransaction(ctx context.Context) *Transaction

BeginTransaction starts a new transaction and registers it with the manager.

func (*TransactionManager) CheckpointWAL added in v0.12.0

func (tm *TransactionManager) CheckpointWAL(dbFile DBFile) error

CheckpointWAL checkpoints the WAL into dbFile, then truncates it.

Checkpoint sequence (all under walWriteMu so no concurrent writers can interleave):

  1. Write every unique page in the WAL to its correct offset in dbFile.
  2. fsync dbFile.
  3. Truncate the WAL file and write fresh salts (invalidates stale frames).
  4. Reset the in-memory WAL index (under tm.mu).

Returns ErrNotWALMode if no WAL is configured. Returns ErrCheckpointBlockedByReaders if any read-only snapshot transaction is currently active. Callers should retry after the readers have finished.

func (*TransactionManager) CommitTransaction

func (tm *TransactionManager) CommitTransaction(ctx context.Context, tx *Transaction) error

CommitTransaction validates the write set for conflicts and, if clean, persists all changes. When a WAL is configured it uses the WAL commit path; otherwise it writes directly to the pager (used by unit tests that do not set up a WAL file).

func (*TransactionManager) ExecuteInTransaction

func (tm *TransactionManager) ExecuteInTransaction(ctx context.Context, fn func(ctx context.Context) error) error

ExecuteInTransaction runs fn within a transaction, committing on success or rolling back on failure.

func (*TransactionManager) ExecuteReadOnlyTransaction added in v0.17.0

func (tm *TransactionManager) ExecuteReadOnlyTransaction(ctx context.Context, fn func(ctx context.Context) error) error

ExecuteReadOnlyTransaction runs fn within a read-only transaction. Read tracking is disabled so no ReadSet is built and conflict validation is skipped at commit time. fn must not perform any writes.

func (*TransactionManager) GlobalDBHeaderVersion

func (tm *TransactionManager) GlobalDBHeaderVersion(ctx context.Context) uint64

GlobalDBHeaderVersion returns the current committed version of the database header.

func (*TransactionManager) GlobalPageVersion

func (tm *TransactionManager) GlobalPageVersion(ctx context.Context, pageIdx PageIndex) uint64

GlobalPageVersion returns the current committed version of the given page.

func (*TransactionManager) PageLastCommittedSeq added in v0.26.0

func (tm *TransactionManager) PageLastCommittedSeq(pageIdx PageIndex) uint64

PageLastCommittedSeq returns the commitSeq at which pageIdx was last updated in the shared page cache. Used by ReadPage to decide whether the cached version is safe to serve to a snapshot reader.

func (*TransactionManager) PageVersionAtSnapshot added in v0.26.0

func (tm *TransactionManager) PageVersionAtSnapshot(pageIdx PageIndex, snapshotSeq uint64) (*Page, bool)

PageVersionAtSnapshot returns the *Page that was current for the given snapshotSeq by binary-searching the version history. ok is false when no suitable entry exists (page either predates any WAL write or was newly allocated after the snapshot).

func (*TransactionManager) RollbackTransaction

func (tm *TransactionManager) RollbackTransaction(ctx context.Context, tx *Transaction)

RollbackTransaction aborts the transaction and discards all in-memory changes.

func (*TransactionManager) SetCheckpointFunc added in v0.12.0

func (tm *TransactionManager) SetCheckpointFunc(fn func() error)

SetCheckpointFunc registers a callback that is invoked by runAutoCheckpoint when the WAL frame count exceeds checkpointThreshold. Typically set to Database.Checkpoint so the auto-checkpoint path mirrors the manual one.

func (*TransactionManager) SetRowCountApplier added in v0.29.0

func (tm *TransactionManager) SetRowCountApplier(fn func(map[string]int64))

SetRowCountApplier registers a callback that is invoked after each successful write commit with the net row-count deltas for the transaction. The Database uses this to keep in-memory row counts up to date so that COUNT(*) queries can be answered in O(1) without a leaf-page walk.

type TransactionStatus

type TransactionStatus int

TransactionStatus represents the lifecycle state of a transaction.

const (
	// TxActive means the transaction is in progress and has not yet been committed or aborted.
	TxActive TransactionStatus = iota + 1
	// TxCommitted means the transaction has been successfully committed.
	TxCommitted
	// TxAborted means the transaction has been rolled back or aborted.
	TxAborted
)

TransactionStatus constants describe the lifecycle state of a transaction.

type TransactionalPager

type TransactionalPager struct {
	Pager
	// contains filtered or unexported fields
}

TransactionalPager wraps a base Pager and routes reads and writes through the current transaction.

func NewTransactionalPager

func NewTransactionalPager(basePager Pager, txManager *TransactionManager, table, index string) *TransactionalPager

NewTransactionalPager creates a TransactionalPager for the given table and index names.

func (*TransactionalPager) AddFreePage

func (tp *TransactionalPager) AddFreePage(ctx context.Context, pageIdx PageIndex) error

AddFreePage marks pageIdx as a free page and prepends it to the free list.

func (*TransactionalPager) GetFreePage

func (tp *TransactionalPager) GetFreePage(ctx context.Context) (*Page, error)

GetFreePage returns a free page from the free list, or allocates a new one.

func (*TransactionalPager) GetOverflowPage

func (tp *TransactionalPager) GetOverflowPage(ctx context.Context, pageIdx PageIndex) (*Page, error)

GetOverflowPage returns a writable copy of the overflow page at pageIdx.

func (*TransactionalPager) ModifyPage

func (tp *TransactionalPager) ModifyPage(ctx context.Context, pageIdx PageIndex) (*Page, error)

ModifyPage returns a writable copy of the page at pageIdx, creating one if it doesn't exist in the write set.

func (*TransactionalPager) ReadPage

func (tp *TransactionalPager) ReadPage(ctx context.Context, pageIdx PageIndex) (*Page, error)

ReadPage returns the page at pageIdx, returning the in-progress write copy if it exists.

For read-only (snapshot) transactions the method enforces snapshot isolation:

  • If the page was last committed at or before tx.SnapshotSeq, the shared page cache is safe to use — no concurrent write has touched it since the snapshot started.
  • Otherwise the method retrieves the historical version from the TransactionManager's page-version history (saved at commit time by the writer that superseded the page).
  • If no historical version is found (the page was newly allocated after the snapshot), the cached version is returned as a safe fallback; this should not occur during normal B+ tree traversal because pre-snapshot pointer chains never reference post-snapshot pages.

type TxPager

type TxPager interface {
	ReadPage(context.Context, PageIndex) (*Page, error)
	ModifyPage(context.Context, PageIndex) (*Page, error)
	GetFreePage(context.Context) (*Page, error)
	AddFreePage(context.Context, PageIndex) error
	GetOverflowPage(context.Context, PageIndex) (*Page, error)
}

TxPager ...

type TxPagerFactory

type TxPagerFactory func(ctx context.Context, tableName, indexName string) (Pager, error)

TxPagerFactory ...

type UnionClause added in v0.9.0

type UnionClause struct {
	Stmt Statement
	All  bool
}

UnionClause represents a UNION or UNION ALL branch appended to a SELECT statement.

type UniqueIndex

type UniqueIndex struct {
	Index BTreeIndex
	IndexInfo
}

UniqueIndex ...

type WAL added in v0.12.0

type WAL struct {
	// contains filtered or unexported fields
}

WAL is a write-ahead log providing crash-safe durability for the database.

On each commit the transaction manager serialises all modified pages as WAL frames and calls AppendTransaction. A final "commit frame" (CommitSize > 0) marks the transaction as durable. Readers check the WAL index (see WALIndex) before reading the main DB file so they always see the latest committed version of any page.

Periodically, or on clean open, committed frames are copied back to the main DB file via Checkpoint and the WAL is truncated.

Write buffering: when flushThreshold > 0 frames from multiple transactions are accumulated in pendingBuf and written to the file in a single WriteAt once pendingLen >= flushThreshold. This reduces syscall overhead for high-frequency single-row-per-transaction workloads. flushThreshold == 0 (the default) flushes after every AppendTransaction, preserving the previous behaviour. SynchronousFull always flushes immediately regardless of the threshold.

func CreateWAL added in v0.12.0

func CreateWAL(dbPath string, pageSize uint32) (*WAL, error)

CreateWAL creates a new WAL file (truncating any existing file at that path).

func OpenWAL added in v0.12.0

func OpenWAL(dbPath string, pageSize uint32) (*WAL, error)

OpenWAL opens an existing WAL file for reading and appending. Returns (nil, nil) when the WAL file does not exist (clean state).

func OpenWALAndRebuildIndex added in v0.12.0

func OpenWALAndRebuildIndex(dbPath string, pageSize uint32, walIndex *WALIndex) (wal *WAL, recovered bool, err error)

OpenWALAndRebuildIndex is the startup routine for WAL mode.

It checks for an existing WAL file at dbPath+"-wal":

  • If the file exists, it opens it for appending, reads all committed frames, and rebuilds walIndex from those frames. This is the crash- recovery path: committed writes that had not yet been checkpointed to the main DB file are reinstated in the in-memory index so reads see the correct data immediately.

  • If no WAL file exists, a fresh WAL file is created.

The caller owns the returned *WAL and must call WAL.Close() when done. walIndex is populated in-place; it must be non-nil. recovered is true when an existing WAL file with committed frames was found.

func (*WAL) AppendTransaction added in v0.12.0

func (w *WAL) AppendTransaction(pages []WALPage) error

AppendTransaction serialises all modified pages as WAL frames into the write buffer and, when the buffer reaches the flush threshold (or when SynchronousFull mode is active), writes it to the OS page cache in a single WriteAt call. The last frame is marked as a commit frame (CommitSize = len(pages)). pages must be non-empty; each Data slice must be exactly pageSize bytes.

func (*WAL) Checkpoint added in v0.12.0

func (w *WAL) Checkpoint(dbFile DBFile) error

Checkpoint copies all committed WAL pages to the database file. It writes the latest version of each page (last write wins when a page appears in multiple transactions) and then fsyncs the database file. Callers should call Truncate after a successful checkpoint.

func (*WAL) Close added in v0.12.0

func (w *WAL) Close() error

Close flushes any pending frames, fsyncs (unless SynchronousOff), and closes the WAL file. On clean shutdown this guarantees all committed transactions are durable before the file handle is released.

func (*WAL) Delete added in v0.12.0

func (w *WAL) Delete() error

Delete closes and removes the WAL file. Used when transitioning back to a clean (no-WAL) state, e.g. after a full checkpoint on clean shutdown.

func (*WAL) Flush added in v0.34.0

func (w *WAL) Flush() error

Flush writes any buffered WAL frames to the OS page cache. It is a no-op when there is nothing pending. Called automatically by Checkpoint, Truncate, and Close; callers that need strict write-order guarantees can call it explicitly.

func (*WAL) FrameCount added in v0.12.0

func (w *WAL) FrameCount() int64

FrameCount returns the total number of frame slots since the last Truncate, including frames that are buffered but not yet flushed to the file.

func (*WAL) ReadAllFrames added in v0.12.0

func (w *WAL) ReadAllFrames() ([]WALReadFrame, error)

ReadAllFrames scans the WAL file from the beginning and returns every frame that belongs to a committed transaction. Frames whose salts or CRCs do not match are treated as the end of the valid region; any pending (uncommitted) frames before the scan stops are silently discarded.

func (*WAL) SetSynchronous added in v0.32.0

func (w *WAL) SetSynchronous(mode SynchronousMode)

SetSynchronous changes the synchronous mode. The new value takes effect on the next WAL commit (AppendTransaction call).

func (*WAL) SetWriteBufferSize added in v0.34.0

func (w *WAL) SetWriteBufferSize(n int)

SetWriteBufferSize sets the target size for write batching. When > 0, AppendTransaction accumulates serialised frames up to this many bytes before issuing a WriteAt to the OS. 0 (the default) disables buffering and flushes after every AppendTransaction, matching the previous behaviour. SynchronousFull always flushes immediately regardless of this setting.

func (*WAL) Synchronous added in v0.32.0

func (w *WAL) Synchronous() SynchronousMode

Synchronous returns the current synchronous mode.

func (*WAL) Truncate added in v0.12.0

func (w *WAL) Truncate() error

Truncate resets the WAL to an empty state after a successful checkpoint. The file header is rewritten with fresh salts so that any unreachable frames left behind by a partial truncation are automatically invalidated.

type WALConfig added in v0.12.0

type WALConfig struct {
	WAL                 *WAL
	Index               *WALIndex
	DBFile              DBFile
	CheckpointThreshold int
	WALWriteBufferSize  int // bytes to buffer before flushing; 0 = flush every commit
	Synchronous         SynchronousMode
}

WALConfig bundles the Write-Ahead Log objects that NewDatabase needs. Pass nil when creating in-memory/test databases that do not require WAL.

type WALIndex added in v0.12.0

type WALIndex struct {
	// contains filtered or unexported fields
}

WALIndex is an in-memory map from page index to the latest raw page bytes that have been committed to the WAL but not yet checkpointed to the main DB file. It is the authoritative source for the current page content during the window between a WAL commit and the next checkpoint.

All methods are safe for concurrent use.

Lifecycle:

  1. Created empty at database open via NewWALIndex.
  2. Populated from the WAL file via Rebuild when a non-empty WAL is found.
  3. Updated after each successful AppendTransaction via Update.
  4. Reset after a successful Checkpoint + Truncate via Reset.

The pager (Phase 4) calls Lookup before reading the DB file so readers always see the latest committed version of every page.

func NewWALIndex added in v0.12.0

func NewWALIndex() *WALIndex

NewWALIndex creates an empty WALIndex.

func (*WALIndex) Has added in v0.12.0

func (wi *WALIndex) Has(pageIdx PageIndex) bool

Has reports whether pageIdx has a committed WAL entry in the index.

func (*WALIndex) Lookup added in v0.12.0

func (wi *WALIndex) Lookup(pageIdx PageIndex) ([]byte, bool)

Lookup returns the raw page bytes for pageIdx if the page has a committed WAL entry that has not yet been checkpointed. The returned slice is a direct reference into the index — callers must treat it as read-only and must not hold it across a Reset call (which replaces the map) if mutations are possible. In practice the pager unmarshals the bytes immediately and does not retain the slice, making this safe.

func (*WALIndex) MaxPageIndex added in v0.12.0

func (wi *WALIndex) MaxPageIndex() PageIndex

MaxPageIndex returns the largest page index stored in the WAL index, or 0 if the index is empty. Used by the pager to initialise totalPages when the DB file is empty (WAL-only mode) so that new-page allocation never clobbers existing WAL pages.

func (*WALIndex) Rebuild added in v0.12.0

func (wi *WALIndex) Rebuild(frames []WALReadFrame)

Rebuild replaces the index contents with the latest committed frame for each page found in frames. frames is expected to be the result of WAL.ReadAllFrames: all entries are already validated and belong to committed transactions. When the same page appears multiple times, the last occurrence wins (matching WAL semantics — later frames are more recent).

Rebuild takes ownership of each f.Data slice — callers must not use the slices after this call returns.

func (*WALIndex) Reset added in v0.12.0

func (wi *WALIndex) Reset()

Reset discards all entries. Called after a successful checkpoint + WAL truncation to reflect that the WAL no longer contains any data that is not already in the main DB file.

func (*WALIndex) Size added in v0.12.0

func (wi *WALIndex) Size() int

Size returns the number of unique page indices currently in the index.

func (*WALIndex) Update added in v0.12.0

func (wi *WALIndex) Update(pageIdx PageIndex, data []byte) []byte

Update records the latest raw page bytes for pageIdx and returns the previous buffer (if any) so the caller can recycle it. Update takes ownership of data — the caller must not read or write the slice after this call. If a prior entry exists for pageIdx it is overwritten (later write wins).

type WALPage added in v0.12.0

type WALPage struct {
	Data  []byte
	Index PageIndex
}

WALPage holds the page index and raw serialised content for one page to be appended to the WAL.

type WALReadFrame added in v0.12.0

type WALReadFrame struct {
	Data      []byte
	PageIndex PageIndex
}

WALReadFrame is a single validated, committed frame returned by ReadAllFrames.

type WriteInfo

type WriteInfo struct {
	*Page
	OriginalPage *Page
	Table        string
	Index        string
}

WriteInfo holds a modified page together with the table and index names it belongs to.

type WritePage

type WritePage struct {
	Page  *Page
	Table string
}

WritePage associates a page with the table it belongs to.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL