sdata

package
v3.36.2 Latest Latest
Warning

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

Go to latest
Published: Aug 25, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

README

sdata

sdata is the schema metadata and relational join graph foundation of GraphJin.

Module path:

github.com/aegion-dynamic/graphjin-slim/core/v3/sdata

Overview

sdata structures raw database inspection data (DBInfo) into a bidirectional relationship graph (DBSchema). It models tables, columns, primary keys, foreign keys, array relationships, polymorphic relations, and multi-hop join paths.

Key Capabilities

  • Bidirectional Relationship Graph: Automatically identifies one-to-one, one-to-many, and many-to-many join paths across database tables.
  • Shortest Path Resolution (path.go): Finds optimal join sequences between disconnected or multi-hop tables (including through-tables).
  • Snapshot & Serialization (snapshot.go): Serializes and deserializes schema metadata for fast startup caching.
  • Table & Column Aliases: Resolves table aliases, camelCase-to-snake_case mappings, and custom relationship overrides.

Key Types & Functions

type DBSchema struct { ... }
type DBTable struct { ... }
type DBColumn struct { ... }
type DBRel struct { ... }

func NewDBSchema(dbinfo *DBInfo, aliases map[string][]string) (*DBSchema, error)
func (s *DBSchema) Find(schema, table string) (DBTable, error)
func (s *DBSchema) FindRel(fromSchema, fromTable, toSchema, toTable string) (DBRel, error)
func (s *DBSchema) FindPath(fromTable, toTable DBTable, through string) ([]DBRel, error)

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrFromEdgeNotFound   = errors.New("from edge not found")
	ErrToEdgeNotFound     = errors.New("to edge not found")
	ErrPathNotFound       = errors.New("path not found")
	ErrPathSearchLimit    = errors.New("path search limit reached")
	ErrThoughNodeNotFound = errors.New("though node not found")
)
View Source
var DBFunctionSortKey = dbFunctionSortKey

Functions

func GetRelName

func GetRelName(colName string) string

GetRelName returns the relationship name

func MarshalDBInfoSnapshot

func MarshalDBInfoSnapshot(di *DBInfo) ([]byte, error)

MarshalDBInfoSnapshot serializes every discovery field needed to rebuild a DBSchema. It deliberately excludes private lookup maps because they are process-local derived state.

Types

type AmbiguousPathError

type AmbiguousPathError struct {
	From, To   string
	Candidates []FKCandidate
}

AmbiguousPathError is returned when a direct (single-hop) relationship between two tables has multiple distinct foreign keys and the caller did not provide a @through hint to disambiguate.

func (*AmbiguousPathError) Error

func (e *AmbiguousPathError) Error() string

type ColPair

type ColPair struct {
	L DBColumn // Local column
	R DBColumn // Referenced (foreign) column
}

ColPair represents a column pair in a composite foreign key relationship.

type CompositeFKInfo

type CompositeFKInfo struct {
	Schema         string
	Table          string
	ConstraintName string
	LocalCols      []string
	FKeySchema     string
	FKeyTable      string
	FKeyCols       []string
}

CompositeFKInfo holds metadata about a composite (multi-column) foreign key constraint.

type CrossDBRel

type CrossDBRel struct {
	SourceTable  DBTable  // local table containing the FK column
	SourceCol    DBColumn // local FK column
	TargetDB     string   // remote database name
	TargetSchema string   // remote schema
	TargetTable  string   // remote table name
	TargetCol    string   // remote column name
	IsOneToOne   bool     // true if target col is PK/unique
}

CrossDBRel represents a cross-database foreign key relationship. These are stored separately from the graph because they connect tables across different databases — the target table doesn't exist in this schema's graph. Resolution happens at runtime via database_join.go.

type DBColumn

type DBColumn struct {
	Comment        string
	ID             int32
	Name           string
	OrigName       string // Original name before normalization (e.g., PascalCase for MSSQL)
	Type           string
	Array          bool
	NotNull        bool
	PrimaryKey     bool
	UniqueKey      bool
	FullText       bool
	FKRecursive    bool
	FKeyDatabase   string // Target database for cross-database FKs (empty = same db)
	FKeySchema     string
	FKeyTable      string
	FKeyCol        string
	FKeyIsUnique   bool // True if FK target column is PK/unique (for correct rel type)
	Blocked        bool
	Table          string
	Schema         string
	Database       string
	Default        string
	Index          bool
	IndexName      string
	FKOnDelete     string
	FKOnUpdate     string
	CodeSQLVirtual string

	// Original names before normalization (used to build dialect name maps for MSSQL)
	OrigTable      string
	OrigSchema     string
	OrigFKeyTable  string
	OrigFKeySchema string
	OrigFKeyCol    string
}

DBColumn returns the column as a string

func (DBColumn) String

func (col DBColumn) String() string

String returns a string representation of the DBColumn

type DBFuncParam

type DBFuncParam struct {
	ID    int
	Name  string
	Type  string
	Array bool
}

DBFuncParam holds the database function parameter information

type DBFunction

type DBFunction struct {
	Comment string
	Schema  string
	Name    string
	Type    string
	Agg     bool
	Inputs  []DBFuncParam
	Outputs []DBFuncParam
}

DBFunction holds the database function information

func (*DBFunction) GetInput

func (fn *DBFunction) GetInput(name string) (ret DBFuncParam, err error)

GetInput returns the input of a function

func (DBFunction) String

func (fn DBFunction) String() string

String returns a string representation of the DBFunction

type DBInfo

type DBInfo struct {
	Type    string
	Version int
	Schema  string
	Name    string

	Tables       []DBTable
	Functions    []DBFunction
	VTables      []VirtualTable    `json:"-"`
	CompositeFKs []CompositeFKInfo `json:"-"`
	// contains filtered or unexported fields
}

DBInfo holds the database schema information

func GetTestCompositeFKDBInfo

func GetTestCompositeFKDBInfo() *DBInfo

GetTestCompositeFKDBInfo returns a DBInfo where the `enrollment` table has a composite FK to `course_offering` on (term_id, course_id). Used to verify that @through(column:) matches a non-primary composite-FK column via ExtraPairs (the second column of the composite).

func GetTestDBInfo

func GetTestDBInfo() *DBInfo

func GetTestDBInfoWithDatabase

func GetTestDBInfoWithDatabase() *DBInfo

GetTestDBInfoWithDatabase returns a DBInfo with tables that have Database field set for testing multi-database support with @database directive

func GetTestMultiFKDBInfo

func GetTestMultiFKDBInfo() *DBInfo

GetTestMultiFKDBInfo returns a DBInfo where the `orders` table has two distinct foreign keys to `users` (customer_id, salesperson_id). Used to exercise ambiguous-path detection.

func GetTestPartitionedDBInfo

func GetTestPartitionedDBInfo() *DBInfo

GetTestPartitionedDBInfo returns a DBInfo with partition keys set on the products table for testing partition filter injection.

func GetTestPartitionedWarnOnlyDBInfo

func GetTestPartitionedWarnOnlyDBInfo() *DBInfo

GetTestPartitionedWarnOnlyDBInfo returns a DBInfo with partition key but no default range (warn-only mode).

func GetTestSnowflakeDBInfo

func GetTestSnowflakeDBInfo() *DBInfo

GetTestSnowflakeDBInfo returns a Snowflake DBInfo with clustering keys set on the products table for testing clustering-aware cursor pagination.

func NewDBInfo

func NewDBInfo(
	dbType string,
	dbVersion int,
	dbSchema string,
	dbName string,
	cols []DBColumn,
	funcs []DBFunction,
	blockList []string,
) *DBInfo

NewDBInfo returns a new DBInfo object

func UnmarshalDBInfoSnapshot

func UnmarshalDBInfoSnapshot(data []byte) (*DBInfo, error)

UnmarshalDBInfoSnapshot loads a durable discovery snapshot and reconstructs lookup maps and table-derived primary/full-text column slices.

func (*DBInfo) AddColumn

func (di *DBInfo) AddColumn(schema, table string, c DBColumn) error

AddColumn adds a column to an existing table and updates the lookup maps.

func (*DBInfo) AddTable

func (di *DBInfo) AddTable(t DBTable)

AddTable adds a table to the DBInfo object

func (*DBInfo) GetColumn

func (di *DBInfo) GetColumn(schema, table, column string) (*DBColumn, error)

GetTable returns a table from the DBInfo object

func (*DBInfo) GetTable

func (di *DBInfo) GetTable(schema, table string) (*DBTable, error)

GetTable returns a table from the DBInfo object

func (*DBInfo) Hash

func (di *DBInfo) Hash() int

Hash returns the hash of the DBInfo object

type DBRel

type DBRel struct {
	Type       RelType
	Left       DBRelLeft
	Right      DBRelRight
	ExtraPairs []ColPair // Additional column pairs for composite FKs
}

DBRel represents a database relationship

func PathToRel

func PathToRel(p TPath) DBRel

PathToRel converts a table path to a relationship

func (*DBRel) IsCrossDatabase

func (r *DBRel) IsCrossDatabase() bool

IsCrossDatabase returns true if this relationship crosses database boundaries. This is used to determine if a join needs to be executed as a database join rather than a SQL join.

func (*DBRel) String

func (re *DBRel) String() string

String returns a string representation of the DBRel

type DBRelLeft

type DBRelLeft struct {
	Ti  DBTable
	Col DBColumn
}

DBRelLeft represents database information

type DBRelRight

type DBRelRight struct {
	VTable string
	Ti     DBTable
	Col    DBColumn
}

DBRelRight represents a database relationship

type DBSchema

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

func GetTestCompositeFKSchema

func GetTestCompositeFKSchema() (*DBSchema, error)

GetTestCompositeFKSchema returns a DBSchema with a composite FK from enrollment to course_offering.

func GetTestMultiFKSchema

func GetTestMultiFKSchema() (*DBSchema, error)

GetTestMultiFKSchema returns a DBSchema with two FKs from orders to users.

func GetTestPartitionedSchema

func GetTestPartitionedSchema() (*DBSchema, error)

GetTestPartitionedSchema returns a DBSchema with partition config for testing.

func GetTestPartitionedWarnOnlySchema

func GetTestPartitionedWarnOnlySchema() (*DBSchema, error)

GetTestPartitionedWarnOnlySchema returns a DBSchema with warn-only partition config.

func GetTestSchema

func GetTestSchema() (*DBSchema, error)

func GetTestSnowflakeSchema

func GetTestSnowflakeSchema() (*DBSchema, error)

GetTestSnowflakeSchema returns a DBSchema backed by Snowflake test data with clustering keys.

func NewDBSchema

func NewDBSchema(
	info *DBInfo,
	aliases map[string][]string,
) (*DBSchema, error)

NewDBSchema creates a new database schema

func (*DBSchema) AddToGraph

func (s *DBSchema) AddToGraph(from DBTable, lc DBColumn, to DBTable, rc DBColumn, rt RelType) ([]int32, error)

func (*DBSchema) CanReach

func (s *DBSchema) CanReach(from, to int32) bool

func (*DBSchema) ClearPathCache

func (s *DBSchema) ClearPathCache()

func (*DBSchema) DBName

func (s *DBSchema) DBName() string

DBName returns the database name

func (*DBSchema) DBSchema

func (s *DBSchema) DBSchema() string

DBSchema returns the database schema

func (*DBSchema) DBType

func (s *DBSchema) DBType() string

DBType returns the database type

func (*DBSchema) DBVersion

func (s *DBSchema) DBVersion() int

DBVersion returns the database version

func (*DBSchema) FKCyclesComponents

func (s *DBSchema) FKCyclesComponents() [][]int32

func (*DBSchema) FKCyclesSelf

func (s *DBSchema) FKCyclesSelf() []int32

func (*DBSchema) Find

func (s *DBSchema) Find(schema, name string) (DBTable, error)

Find returns a table by schema and name. If an exact schema:name match is not found, it falls back to searching across all discovered schemas. When multiple schemas contain the same table name, the default schema is preferred. If the table exists in multiple non-default schemas, an error listing the available schemas is returned.

func (*DBSchema) FindCrossDBPath

func (s *DBSchema) FindCrossDBPath(childName, parentName string) (TPath, bool)

FindCrossDBPath checks cross-database FK metadata for a relationship between two tables identified by their unqualified names (as used in GraphQL queries). Returns a synthetic TPath if found, without requiring the target table to be a node in the graph.

func (*DBSchema) FindPath

func (s *DBSchema) FindPath(from, to, through string) ([]TPath, error)

FindPath returns a path between two tables

func (*DBSchema) FindPathByColumn

func (s *DBSchema) FindPathByColumn(from, to, col string) ([]TPath, error)

FindPathByColumn returns a path between two tables, disambiguating by the FK column name when the two tables have multiple foreign keys between them.

func (*DBSchema) GetAliases

func (s *DBSchema) GetAliases() map[string]DBTable

GetAliases returns a map of table aliases

func (*DBSchema) GetCrossDBRels

func (s *DBSchema) GetCrossDBRels() []CrossDBRel

GetCrossDBRels returns all cross-database relationships in the schema.

func (*DBSchema) GetFirstDegree

func (s *DBSchema) GetFirstDegree(t DBTable) (items []RelNode, err error)

GetFirstDegree returns the first degree relationships of a table

func (*DBSchema) GetFunctions

func (s *DBSchema) GetFunctions() map[string]DBFunction

GetFunction returns a function from the schema

func (*DBSchema) GetSecondDegree

func (s *DBSchema) GetSecondDegree(t DBTable) (items []RelNode, err error)

GetSecondDegree returns the second degree relationships of a table

func (*DBSchema) GetTables

func (s *DBSchema) GetTables() []DBTable

GetTables returns a table from the schema

func (*DBSchema) IsAlias

func (s *DBSchema) IsAlias(name string) bool

IsAlias checks if a table is an alias

func (*DBSchema) TableCount

func (s *DBSchema) TableCount() int

func (*DBSchema) TableNameByID

func (s *DBSchema) TableNameByID(id int32) (string, bool)

func (*DBSchema) TableNodeID

func (s *DBSchema) TableNodeID(schema, table string) (int32, bool)

type DBTable

type DBTable struct {
	Comment    string
	Schema     string
	Name       string
	OrigName   string // Original name before normalization (e.g., PascalCase for MSSQL)
	OrigSchema string // Original schema before normalization
	Type       string
	// Database is the name of the database this table belongs to (for multi-database support).
	// Empty string means the default database.
	Database             string
	Columns              []DBColumn
	PrimaryCols          []DBColumn
	PrimaryCol           DBColumn // backward compat: alias for PrimaryCols[0]
	SecondaryCol         DBColumn
	FullText             []DBColumn
	Blocked              bool
	Func                 DBFunction
	ClusteringKeys       []string          // Warehouse clustering key columns (normalized to snake_case)
	ClusteringOrder      map[string]string // Cassandra clustering column -> asc|desc
	PartitionKeys        []string          // Cassandra composite partition key columns (in order)
	AllowFiltering       bool              // Cassandra: per-table ALLOW FILTERING opt-in
	PartitionKey         string            // Partition column name (from config, e.g., "created_at")
	PartitionRangeDays   int               // Default range in days for auto-injected partition filter (0 = warn only)
	PartitionNone        bool
	ImplicitPartitionKey string
	// StrictColumns marks Columns as the table's complete surface: selecting
	// a column not in the list is a compile error instead of the lenient
	// pass-through remote tables get by default. Set by integrations whose
	// column set is closed (filesystem tables); OpenAPI and user-resolver
	// tables leave it false because their registered columns may be partial
	// or absent entirely.
	StrictColumns bool

	// Args lists synthetic field-level arguments (used for top-level
	// remote tables that take query/path params as GraphQL args).
	Args []DBColumn
	// contains filtered or unexported fields
}

DBTable holds the database table information

func NewDBTable

func NewDBTable(schema, name, _type string, cols []DBColumn) DBTable

NewDBTable returns a new DBTable object

func (*DBTable) ColumnExists

func (ti *DBTable) ColumnExists(name string) (DBColumn, bool)

ColumnExists returns true if a column exists in a table

func (*DBTable) GetColumn

func (ti *DBTable) GetColumn(name string) (DBColumn, error)

GetColumn returns a column from a table

func (*DBTable) GetColumnIndex

func (t *DBTable) GetColumnIndex(name string) (int, bool)

GetColumnIndex returns the index of a column in the table by name, and whether it was found.

func (*DBTable) HasCompositePK

func (t *DBTable) HasCompositePK() bool

HasCompositePK returns true if the table has a multi-column primary key.

func (*DBTable) IsPKCol

func (t *DBTable) IsPKCol(name string) bool

IsPKCol returns true if the named column is part of the primary key.

func (*DBTable) PKColNames

func (t *DBTable) PKColNames() []string

PKColNames returns the names of all primary key columns.

func (*DBTable) String

func (ti *DBTable) String() string

String returns a string representation of the DBTable

type FKCandidate

type FKCandidate struct {
	Column           string
	TargetTable      string
	TargetColumn     string
	IsComposite      bool
	CompositeColumns []string
}

FKCandidate describes one foreign key option when an A→B relationship has multiple FKs and disambiguation is required.

type RelNode

type RelNode struct {
	Name  string
	Type  RelType
	Table DBTable
}

RelNode represents a relationship node

type RelType

type RelType int
const (
	RelNone RelType = iota
	RelOneToOne
	RelOneToMany
	RelPolymorphic
	RelRecursive
	RelEmbedded
	RelRemote
	RelSkip
	// RelDatabaseJoin represents a cross-database relationship (multi-database support).
	// Similar to RelRemote but for in-process database joins rather than HTTP calls.
	RelDatabaseJoin
)

func (RelType) String

func (i RelType) String() string

type TEdge

type TEdge struct {
	From, To, Weight int32

	Type   RelType
	LT, RT DBTable
	L, R   DBColumn
	CName  string

	ExtraPairs []ColPair // Additional column pairs for composite FKs
	// contains filtered or unexported fields
}

TEdge represents a table edge for the graph

type TPath

type TPath struct {
	Rel        RelType
	LT         DBTable
	LC         DBColumn
	RT         DBTable
	RC         DBColumn
	ExtraPairs []ColPair // Additional column pairs for composite FKs
}

TPath represents a table path

func (*TPath) String

func (tp *TPath) String() string

String returns a string representation of a table path

type VirtualTable

type VirtualTable struct {
	Name       string
	IDColumn   string
	TypeColumn string
	FKeyColumn string
}

VirtualTable holds the virtual table information

Jump to

Keyboard shortcuts

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