sqlode/query_analyzer/column_inferencer
Values
pub fn extract_cte_tables(
query_name: String,
tokens: List(lexer.Token),
catalog: model.Catalog,
) -> Result(List(model.Table), context.AnalysisError)
Extract CTE definitions from a query’s tokens and return the
resulting virtual tables. Each name AS (body) (or
name(c1, c2) AS (body)) becomes a Table whose columns come from
running infer_columns_from_tokens on the body. RECURSIVE CTEs use
the anchor (first) branch via the existing tok_strip_compound, so
recursive self-references are not analysed.
pub fn extract_derived_tables(
query_name: String,
tokens: List(lexer.Token),
catalog: model.Catalog,
) -> Result(List(model.Table), context.AnalysisError)
Find every derived table in the token stream — FROM (SELECT ...),
JOIN (SELECT ...), JOIN LATERAL (SELECT ...), and comma-LATERAL
, LATERAL (SELECT ...) — and build a virtual Table for each. Each
body is resolved against catalog via infer_columns_from_tokens,
so nested CTEs / VALUES / derived tables compose naturally. An
explicit AS alias(c1, c2) column list overrides the body’s names.
pub fn extract_values_tables(
tokens: List(lexer.Token),
) -> List(model.Table)
Find every (VALUES ...) AS alias(c1, c2, ...) in the token stream
and build a virtual Table for each. Column types come from the first
row’s literals; rows with unsupported expressions are skipped silently
(the resolver will surface any downstream issue).
pub fn infer_columns_from_tokens(
query_name: String,
tokens: List(lexer.Token),
catalog: model.Catalog,
) -> Result(List(model.ResultItem), context.AnalysisError)
Token-based column inference, exposed so callers (notably the CTE
virtual-table builder in query_analyzer) can reuse the SELECT
resolver without re-lexing or constructing a synthetic ParsedQuery.
pub fn infer_columns_from_tokens_scoped(
query_name: String,
tokens: List(lexer.Token),
catalog: model.Catalog,
outer_tables: List(String),
) -> Result(List(model.ResultItem), context.AnalysisError)
Same as infer_columns_from_tokens, but when the inner query has no
FROM clause of its own, fall back to outer_tables so correlated
references like SELECT (SELECT books.id) can still be resolved
against the enclosing query’s FROM list.
Every entry point also runs VALUES and derived-table discovery over its own token scope and augments the catalog before resolution, so nested subqueries pick up sibling virtual tables without extra work from the caller.
pub fn infer_result_columns(
ctx: context.AnalyzerContext,
engine: model.Engine,
query: model.ParsedQuery,
tokens: List(lexer.Token),
statement: query_ir.SqlStatement,
catalog: model.Catalog,
) -> Result(List(model.ResultItem), context.AnalysisError)