Documentation
¶
Index ¶
- Constants
- Variables
- func CleanupEmptyMaps(record *PersistentRecord)
- func ColumnKindToValueType(kind ColumnKind) forma.ValueType
- func ComputeTotalPages(total int64, limit int) int
- func IsMainTableColumn(name string) bool
- func ParseAttributesJSON(attrsJSON []byte, record *PersistentRecord) error
- type AtomicBatchPersistentRecordRepository
- type AttributeOrder
- type AttributeQuery
- type ColumnDescriptor
- type ColumnKind
- type ConsistencyMode
- type DataSourcePlan
- type DataTier
- type DuckDBRenderHints
- type EAVRecord
- type EntityAttribute
- func (ea *EntityAttribute) BigInt() (*int64, error)
- func (ea *EntityAttribute) Bool() (*bool, error)
- func (ea *EntityAttribute) Date() (*time.Time, error)
- func (ea *EntityAttribute) DateTime() (*time.Time, error)
- func (ea *EntityAttribute) Integer() (*int32, error)
- func (ea *EntityAttribute) Numeric() (*float64, error)
- func (ea *EntityAttribute) SmallInt() (*int16, error)
- func (ea *EntityAttribute) Text() (*string, error)
- func (ea *EntityAttribute) UUID() (*uuid.UUID, error)
- type ExecutionPlan
- type FederatedAttributeQuery
- type FederatedQueryEngine
- type FederatedQueryOptions
- type KeysetColumn
- type KeysetCursor
- type KeysetCursorMode
- type MergePlan
- type MergeStrategy
- type PartialScan
- type PersistentRecord
- type PersistentRecordKey
- type PersistentRecordPage
- type PersistentRecordQuery
- type PersistentRecordReader
- type PersistentRecordRepository
- type PersistentRecordTransformer
- type PersistentRecordWriter
- type RoutingDecision
- type StorageTables
Constants ¶
const DefaultPageSize = 50
DefaultPageSize is the fallback page size used when the caller supplies a non-positive limit.
const FederatedMaxRows = 10000
FederatedMaxRows is the default per-source fetch cap used by federated queries when no explicit MaxRows option is provided.
Variables ¶
var ( TextColumns = []string{"ltbase_created_by", "ltbase_deleted_by", "ltbase_updated_by", "text_01", "text_02", "text_03", "text_04", "text_05", "text_06", "text_07", "text_08", "text_09", "text_10"} SmallintColumns = []string{"smallint_01", "smallint_02", "smallint_03"} IntegerColumns = []string{"integer_01", "integer_02", "integer_03"} BigintColumns = []string{"bigint_01", "bigint_02", "bigint_03"} DoubleColumns = []string{"double_01", "double_02", "double_03"} UUIDColumns = []string{"uuid_01", "uuid_02"} )
Column slices define the physical hot-storage columns available in entity_main. These are declared once and treated as read-only after package init.
var ( AllowedTextColumns = makeColumnSet(TextColumns) AllowedSmallintColumns = makeColumnSet(SmallintColumns) AllowedIntegerColumns = makeColumnSet(IntegerColumns) AllowedBigintColumns = makeColumnSet(BigintColumns) AllowedDoubleColumns = makeColumnSet(DoubleColumns) AllowedUUIDColumns = makeColumnSet(UUIDColumns) )
allowedXxxColumns are fast O(1) lookup sets built from the column slices above.
var EntityMainColumnDescriptors = buildEntityMainColumnDescriptors()
EntityMainColumnDescriptors is the ordered list of all columns (system + EAV) used to scan rows from entity_main. It is built once at package load time via a package-level var initializer, avoiding an init() side-effect.
var EntityMainProjection = func() string { names := make([]string, 0, len(EntityMainColumnDescriptors)) for _, d := range EntityMainColumnDescriptors { names = append(names, d.Name) } return strings.Join(names, ", ") }()
EntityMainProjection is the comma-separated column list used in SELECT statements against entity_main. Built once at package load time.
var SystemColumnDescriptors = []ColumnDescriptor{ {Name: "ltbase_schema_id", Kind: ColumnKindSmallint}, {Name: "ltbase_row_id", Kind: ColumnKindUUID}, {Name: "ltbase_created_at", Kind: ColumnKindBigint}, {Name: "ltbase_updated_at", Kind: ColumnKindBigint}, {Name: "ltbase_deleted_at", Kind: ColumnKindBigint}, }
SystemColumnDescriptors contains the five fixed metadata columns that appear before the EAV columns in every entity_main SELECT projection. They are not present in the allowedXxx sets, so GetMainColumnDescriptor checks this list separately.
Functions ¶
func CleanupEmptyMaps ¶
func CleanupEmptyMaps(record *PersistentRecord)
CleanupEmptyMaps removes empty maps from the record to avoid nil-map checks
func ColumnKindToValueType ¶
func ColumnKindToValueType(kind ColumnKind) forma.ValueType
ColumnKindToValueType maps a physical column kind to the forma value type used when a raw main-table column is referenced without schema metadata.
func ComputeTotalPages ¶
ComputeTotalPages returns the page count for total records at the given limit.
func IsMainTableColumn ¶
IsMainTableColumn reports whether name is a recognised entity_main column. Uses O(1) map lookups — no linear scan.
func ParseAttributesJSON ¶
func ParseAttributesJSON(attrsJSON []byte, record *PersistentRecord) error
ParseAttributesJSON parses JSON-aggregated EAV attributes into the record
Types ¶
type AtomicBatchPersistentRecordRepository ¶
type AtomicBatchPersistentRecordRepository interface {
BatchInsertPersistentRecords(ctx context.Context, tables StorageTables, records []*PersistentRecord) error
BatchUpdatePersistentRecords(ctx context.Context, tables StorageTables, records []*PersistentRecord) error
BatchDeletePersistentRecords(ctx context.Context, tables StorageTables, keys []PersistentRecordKey) error
}
type AttributeOrder ¶
type AttributeOrder struct {
AttrID int16
ValueType forma.ValueType
SortOrder forma.SortOrder
StorageLocation forma.AttributeStorageLocation
ColumnName string
AttrName string
}
AttributeOrder specifies how to sort by a particular attribute.
func (*AttributeOrder) AttrIDInt ¶
func (ao *AttributeOrder) AttrIDInt() int
func (*AttributeOrder) Desc ¶
func (ao *AttributeOrder) Desc() bool
func (*AttributeOrder) IsMainColumn ¶
func (ao *AttributeOrder) IsMainColumn() bool
func (*AttributeOrder) MainColumnName ¶
func (ao *AttributeOrder) MainColumnName() string
func (*AttributeOrder) ValueColumn ¶
func (ao *AttributeOrder) ValueColumn() string
type AttributeQuery ¶
type ColumnDescriptor ¶
type ColumnDescriptor struct {
Name string
Kind ColumnKind
}
func GetMainColumnDescriptor ¶
func GetMainColumnDescriptor(name string) *ColumnDescriptor
GetMainColumnDescriptor returns the descriptor for a named entity_main column, or nil if the name is not recognised. Checks the system-column map first, then falls back to the ordered EAV descriptor list (linear but called infrequently).
type ColumnKind ¶
type ColumnKind int
const ( ColumnKindText ColumnKind = iota ColumnKindSmallint ColumnKindInteger ColumnKindBigint ColumnKindDouble ColumnKindUUID )
type ConsistencyMode ¶
type ConsistencyMode string
const ( ConsistencyModeStrict ConsistencyMode = "strict" ConsistencyModeEventual ConsistencyMode = "eventual" )
type DataSourcePlan ¶
type DataSourcePlan struct {
Tier DataTier
Engine string
SQL string
// Params holds the string forms of the bind parameters for SQL, in
// order. Populated only when FederatedQueryOptions.IncludeExecutionPlan
// is set, so diagnostic artifacts can replay the exact query (#173).
Params []string
RowEstimate int64
PredicatePushdown bool
ActualRows int64
DurationMs int64
Reason string
}
type DuckDBRenderHints ¶
type EAVRecord ¶
type EAVRecord struct {
SchemaID int16
RowID uuid.UUID
AttrID int16
ArrayIndices string
ValueText *string
ValueNumeric *float64
// ValueInt64 is an exact int64 sidecar for bigint and epoch-ms date
// values. It is in-memory only: eav_data persistence and the EAV read
// paths keep the float64 ValueNumeric contract (2^53 ceiling), while
// main-column routing (storeInMainColumn) and read-back prefer
// ValueInt64 so column-bound bigint/unix_ms values carry the full
// int64 range without a float64 hop (#205).
ValueInt64 *int64
}
EAVRecord represents one attribute row in EAV storage.
type EntityAttribute ¶
type EntityAttribute struct {
SchemaID int16
RowID uuid.UUID
AttrID int16
ArrayIndices string
ValueType forma.ValueType
Value any
}
func (*EntityAttribute) BigInt ¶
func (ea *EntityAttribute) BigInt() (*int64, error)
func (*EntityAttribute) Bool ¶
func (ea *EntityAttribute) Bool() (*bool, error)
func (*EntityAttribute) Integer ¶
func (ea *EntityAttribute) Integer() (*int32, error)
func (*EntityAttribute) Numeric ¶
func (ea *EntityAttribute) Numeric() (*float64, error)
func (*EntityAttribute) SmallInt ¶
func (ea *EntityAttribute) SmallInt() (*int16, error)
func (*EntityAttribute) Text ¶
func (ea *EntityAttribute) Text() (*string, error)
type ExecutionPlan ¶
type ExecutionPlan struct {
Routing RoutingDecision
Sources []DataSourcePlan
Merge MergePlan
Timings map[string]int64
Notes []string
}
type FederatedAttributeQuery ¶
type FederatedAttributeQuery struct {
AttributeQuery
PreferredTiers []DataTier
PreferHot bool
UseMainAsAnchor bool
DuckDBHints *DuckDBRenderHints
KeysetCursor *KeysetCursor
}
type FederatedQueryEngine ¶
type FederatedQueryEngine interface {
Query(ctx context.Context, tables StorageTables, fq *FederatedAttributeQuery, opts *FederatedQueryOptions) (*PersistentRecordPage, error)
}
type FederatedQueryOptions ¶
type FederatedQueryOptions struct {
MaxRows int
Parallelism int
AllowPartialDegradedMode bool
KeysetEnabled bool
IncludeExecutionPlan bool
ExecutionPlan *ExecutionPlan
ConsistencyMode ConsistencyMode
// PartialScan is an engine out-parameter like ExecutionPlan, but NOT
// gated on IncludeExecutionPlan: the #348 public partial marker must
// reach callers that never asked for a plan. The last executed DuckDB
// pass overwrites it, so it describes the pass that produced the page,
// and Query resets it at entry, so after any call — including a
// postgres-only answer that never runs a pass — it describes that call
// even when one options value is reused across queries.
// Being an out-parameter, it has nowhere to land when the caller passes
// nil options: such a call drops the marker, so a caller that needs it
// must pass a non-nil *FederatedQueryOptions.
PartialScan *PartialScan
}
type KeysetColumn ¶
type KeysetCursor ¶
type KeysetCursor struct {
Columns []KeysetColumn
Values []interface{}
Mode KeysetCursorMode
}
type KeysetCursorMode ¶
type KeysetCursorMode string
const ( KeysetCursorModeAfter KeysetCursorMode = "after" KeysetCursorModeBefore KeysetCursorMode = "before" )
type MergePlan ¶
type MergePlan struct {
Strategy MergeStrategy
PreferHot bool
DedupKeys []string
DurationMs int64
Notes []string
}
type MergeStrategy ¶
type MergeStrategy string
const MergeStrategyLastWriteWins MergeStrategy = "last-write-wins"
type PartialScan ¶
type PartialScan struct {
ExcludedObjects []string
}
PartialScan reports that the DuckDB pass that answered this query ran over a deliberately reduced object set: verification-confirmed corrupt parquet objects (#251) were excluded and the page came from the readable remainder plus the hot tier. Internal form — ExcludedObjects carries full storage keys for embedders and operators; the public projection (forma.QueryResult.Partial) surfaces only the reason and the count (#348, #301/#306 boundary).
type PersistentRecord ¶
type PersistentRecord struct {
SchemaID int16
RowID uuid.UUID
TextItems map[string]string
Int16Items map[string]int16
Int32Items map[string]int32
Int64Items map[string]int64
Float64Items map[string]float64
UUIDItems map[string]uuid.UUID
CreatedAt int64
UpdatedAt int64
DeletedAt *int64
OtherAttributes []EAVRecord
}
PersistentRecord represents a persisted entity row plus EAV attributes.
type PersistentRecordKey ¶
type PersistentRecordPage ¶
type PersistentRecordPage struct {
Records []*PersistentRecord
TotalRecords int64
TotalPages int
CurrentPage int
ExecutionPlan *ExecutionPlan
Partial *PartialScan
}
type PersistentRecordQuery ¶
type PersistentRecordQuery struct {
Tables StorageTables
SchemaID int16
Condition forma.Condition
AttributeOrders []AttributeOrder
Limit int
Offset int
}
type PersistentRecordReader ¶
type PersistentRecordReader interface {
GetPersistentRecord(ctx context.Context, tables StorageTables, schemaID int16, rowID uuid.UUID) (*PersistentRecord, error)
QueryPersistentRecords(ctx context.Context, query *PersistentRecordQuery) (*PersistentRecordPage, error)
// QueryPersistentRecordsByAttrValues fetches full records whose attribute
// equals any of the given values via one set-based lookup (#268). It exists
// for internal batch lookups (relation enrichment); it must never expand to
// an OR-of-N condition per value.
QueryPersistentRecordsByAttrValues(ctx context.Context, tables StorageTables, schemaID int16, attr string, values []string, limit int) (*PersistentRecordPage, error)
}
type PersistentRecordRepository ¶
type PersistentRecordRepository interface {
PersistentRecordWriter
PersistentRecordReader
}
type PersistentRecordWriter ¶
type PersistentRecordWriter interface {
InsertPersistentRecord(ctx context.Context, tables StorageTables, record *PersistentRecord) error
UpdatePersistentRecord(ctx context.Context, tables StorageTables, record *PersistentRecord) error
DeletePersistentRecord(ctx context.Context, tables StorageTables, schemaID int16, rowID uuid.UUID) error
}