scope

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AttachTempColumnLookup

func AttachTempColumnLookup(tableRef *TableRef, declared []string)

AttachTempColumnLookup lets the scope resolver treat a CTE or derived table as a relation whose columns are known, so an unqualified name it owns resolves through its own lineage instead of being guessed from name order. declared is the CTE's column list when the query wrote one, or the names the query's output exposes; a nil list falls back to the targets the lineage carries.

func ExposedColumnNames

func ExposedColumnNames(declared []string, cols []OutputColumn) []string

ExposedColumnNames lists the names a temporary relation exposes, in the order the relation offers them. A declared list — a CTE's `WITH c (a, b)` or a derived table's `AS d (a, b)` — renames the body's output positionally, so both the relation's own lineage and the columns the scope resolves against have to use the renamed names. The list is honoured only when its arity matches the body, because a mismatch is a statement MySQL rejects.

func NewLineageEdge

func NewLineageEdge(fromQualifier, fromTable, fromField, toQualifier, toTable, toField string, transform []model.Transformation, isTemp bool) model.ColumnRelation

NewLineageEdge creates a ColumnRelation from field-edge parameters, recording the qualifier of each endpoint as a database name. That is what a MySQL-family or StarRocks reference names; PostgreSQL names a schema and uses NewSchemaLineageEdge.

func NewSchemaLineageEdge

func NewSchemaLineageEdge(fromQualifier, fromTable, fromField, toQualifier, toTable, toField string, transform []model.Transformation, isTemp bool) model.ColumnRelation

NewSchemaLineageEdge is NewLineageEdge with the qualifier recorded as a schema name. The distinction is not cosmetic: database and schema are separate fields of an object identifier, so an edge built with the wrong one names a different object than the analyzer resolved.

func TempColumnNames

func TempColumnNames(declared []string, lineage []model.ColumnRelation) []string

TempColumnNames reports the columns a temporary relation exposes, or nil when one of them cannot be named. A wildcard the catalog did not expand, and an output without a name, both leave the list incomplete; an incomplete list is reported as unknown so the resolver keeps its fallback for the relation.

Types

type CTEDefinition

type CTEDefinition struct {
	Name    string
	Columns []string
	// Lineage edges within the CTE
	Lineage []model.ColumnRelation
}

CTEDefinition represents a Common Table Expression.

type ColumnLookup

type ColumnLookup func() []string

ColumnLookup reports the column names a relation exposes. A nil result means the metadata is unavailable, and the resolver keeps its deterministic ordering rule for that relation.

type ColumnRef

type ColumnRef struct {
	Schema string
	Table  string
	Column string
	// Resolved marks a reference that was already resolved against the scope it
	// originated in, so a later lookup does not bind it to a different relation
	// that happens to share the name. Every analyzer sets it where the resolved
	// table lives in a scope a later lookup cannot see: a set-operation arm, a
	// flattened expression subquery, an expanded wildcard.
	Resolved bool
}

ColumnRef represents a reference to a column in the query.

func Refs

func Refs(sources []ColumnSource) []ColumnRef

Refs returns the source references without their transformations, for the callers that only need to resolve or count them.

func WildcardSourceRef

func WildcardSourceRef(tableRef *TableRef) ColumnRef

WildcardSourceRef is the source a `*` contributes for one relation: a wildcard reference to that relation, marked resolved because the relation it names cannot be rebound by name later. StarRocks keeps its own rule for a query-local relation, where the reference has to stay rebindable; see its queryLocalWildcardSourceRef.

type ColumnSource

type ColumnSource struct {
	Ref       ColumnRef
	Transform []model.Transformation
}

ColumnSource is a source column of an output column together with the transformations that produced the output from it. The transformation travels with the source rather than with the output column because a set operation merges arms that compute the same output column in different ways: one transformation for the whole column would attribute the first arm's expression to every other arm's sources, which is lineage that does not exist.

func NewColumnSources

func NewColumnSources(refs []ColumnRef, transform []model.Transformation) []ColumnSource

NewColumnSources pairs every reference with the same transformation, the shape an output column built from a single expression has.

type OutputColumn

type OutputColumn struct {
	Alias string // The alias given to this column (AS clause)
	// Sources are the columns this output depends on, each carrying the
	// transformation that produced it.
	Sources []ColumnSource
	// Whether this is a derived/transformed column
	IsDerived bool
}

OutputColumn represents a column in the SELECT output.

func (*OutputColumn) SetTransform

func (c *OutputColumn) SetTransform(transform []model.Transformation)

SetTransform gives every source the same transformation list, the shape an output column built from a single expression has. The list is shared rather than copied, so callers must treat it as read-only afterwards.

type RelationKey

type RelationKey struct {
	Qualifier string
	Name      string
}

RelationKey identifies a relation inside a scope. Qualifier is the database (MySQL family, StarRocks) or schema (PostgreSQL) the relation was named with, and is empty when the query does not name one. Name is the alias when the relation has one, otherwise its table name: the name a SQL reference uses.

func RelationKeyOf

func RelationKeyOf(id model.ObjectIdentifier) RelationKey

RelationKeyOf builds the key of a relation endpoint recorded on an edge. The qualifier is whichever of the identifier's database or schema is set: the MySQL family and StarRocks record a SQL qualifier as a database, PostgreSQL as a schema.

type ResolvedColumn

type ResolvedColumn struct {
	Ref      ColumnRef
	Relation *TableRef
}

ResolvedColumn is a column reference together with the relation that owns it. An unqualified name yields one per relation in scope that exposes it, which is more than one when several relations share the name — the shape a coalesced USING or NATURAL JOIN column has, where every owner really is a source.

type Scope

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

Scope represents a lexical scope in SQL, tracking available tables and columns. Scopes are nested (e.g., subquery inside a main query).

func NewScope

func NewScope(parent *Scope) *Scope

NewScope creates a new scope with an optional parent.

func NewScopeWithDefinitions

func NewScopeWithDefinitions(parent, definitions *Scope) *Scope

NewScopeWithDefinitions creates a scope that resolves the CTE definitions of definitions while resolving the relations of parent. The two namespaces are usually reached through the same link, which is why NewScope is the ordinary constructor; a clause that may read a query's CTEs but not the relations that query reads from needs them separated.

func (*Scope) AddCTE

func (s *Scope) AddCTE(cte *CTEDefinition)

AddCTE adds a CTE definition to the current scope.

func (*Scope) AddOutputColumn

func (s *Scope) AddOutputColumn(col OutputColumn)

AddOutputColumn adds an output column to the current scope.

func (*Scope) AddTable

func (s *Scope) AddTable(ref *TableRef)

AddTable adds a table reference to the current scope. Registering the same address twice replaces the earlier reference, which keeps a repeated registration idempotent; two same-named relations from different databases or schemas have different keys and coexist.

func (*Scope) FindCTE

func (s *Scope) FindCTE(name string) (*CTEDefinition, bool)

FindCTE looks up a CTE definition a FROM clause names: this scope's own definitions, the definitions this scope reads, and then their parent chain. A CTE is named from a FROM clause and nowhere else, which is why the query resolution path uses findCTEQualifier instead.

func (*Scope) FindRelation

func (s *Scope) FindRelation(key RelationKey) (*TableRef, bool)

FindRelation returns the relation a reference with this key addresses, searching parent scopes when the current one has none. An exactly matching key wins; otherwise a relation that accepts the reference (see TableRef.addresses) is returned.

func (*Scope) FindTable

func (s *Scope) FindTable(name string) (*TableRef, bool)

FindTable returns the relation addressed by name alone, which is how a reference that names no qualifier addresses it.

func (*Scope) GetOutputColumns

func (s *Scope) GetOutputColumns() []OutputColumn

GetOutputColumns returns the output columns of this scope.

func (*Scope) Parent

func (s *Scope) Parent() *Scope

Parent returns the parent scope.

func (*Scope) ResolveColumn

func (s *Scope) ResolveColumn(colRef ColumnRef) (*ColumnRef, error)

ResolveColumn resolves a column reference to its source table. It handles both qualified (table.column) and unqualified (column) references.

func (*Scope) ResolveColumnRef

func (s *Scope) ResolveColumnRef(colRef ColumnRef) (*ColumnRef, *TableRef, error)

ResolveColumnRef is ResolveColumn plus the relation the reference resolved to, so a caller can tell a base table from a query-local one without looking the name up again and guessing. It reports the first of ResolveColumnRefs' resolutions, which is the only one for every reference except an unqualified name that several relations in scope own. A CTE that is in scope only as a definition is presented as the relation it describes. The relation is nil when this scope cannot identify it, which happens for a reference that was already resolved against a scope this one does not share.

func (*Scope) ResolveColumnRefs

func (s *Scope) ResolveColumnRefs(colRef ColumnRef) ([]ResolvedColumn, error)

ResolveColumnRefs resolves a column reference to every relation in scope that owns it, in the scope's name order. A qualified reference and one that was already resolved elsewhere have exactly one resolution; an unqualified name has one per owning relation, which is how a coalesced USING or NATURAL JOIN column reports both sides.

func (*Scope) SetOutputColumns

func (s *Scope) SetOutputColumns(cols []OutputColumn)

SetOutputColumns replaces every output column of this scope. A merge that produces the whole list uses it so a shorter list cannot silently leave a column behind.

func (*Scope) Tables

func (s *Scope) Tables() []*TableRef

Tables returns the scope's relations in registration order, without the parent scope's. Every relation is returned, so a wildcard expands against both db1.t and db2.t.

type TableRef

type TableRef struct {
	Schema string
	Table  string
	Alias  string
	// For subqueries and CTEs
	IsSubquery bool
	IsCTE      bool
	// Lineage edges for subqueries (how output columns relate to source tables)
	Lineage []model.ColumnRelation
	// contains filtered or unexported fields
}

TableRef represents a table or table-like source (subquery, CTE).

func (*TableRef) ColumnNames

func (r *TableRef) ColumnNames() []string

ColumnNames returns the relation's column names, or nil when they are unknown.

func (*TableRef) Key

func (r *TableRef) Key() RelationKey

Key returns the key a SQL reference addresses the relation by.

func (*TableRef) SetColumnLookup

func (r *TableRef) SetColumnLookup(lookup ColumnLookup)

SetColumnLookup attaches the catalog column lookup for this relation. Analyzers set it when they register a base table, so every scope — including the CTE, derived-table and subquery scopes the analyzers resolve in — disambiguates an unqualified column the same way.

Jump to

Keyboard shortcuts

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