public final class StatementGraph extends Object
name is non-null when this statement is the body of a named
CTE or a FROM-clause subquery. For top-level outer SELECTs it is null.
filterColumnRefs, joinColumnRefs,
groupByColumnRefs, havingColumnRefs, and
orderByColumnRefs are flat lists of column references that
appear in the WHERE, JOIN predicate (ON / USING), GROUP BY, HAVING,
and ORDER BY clauses respectively. For JOIN ... USING (k)
(slice 64) joinColumnRefs contains one ref per
(relation, key) pair on both sides — left side first via
catalog-aware narrowing, then the right side. The IR deliberately
does not model structured
Filter, Join, or GroupBy nodes with predicate
trees yet; later slices will add them. Listing the affected columns
is enough to answer the roadmap's questions about
filter/join/grouping/having/ordering influence.
groupingElements (slice 128) is the structured companion to
the flat groupByColumnRefs: one GroupingElement per
top-level GROUP BY item, preserving the SIMPLE /
ROLLUP / CUBE / GROUPING SETS structure the flat
list discards. See getGroupingElements().
orderByColumnRefs only ever contains references to physical
(base or in-statement) columns. Ordinal references (ORDER BY 1)
and bare-constant sort keys are rejected by the builder — emitting
[] for them would lose the dependency information silently.
Slice 9 (single-SELECT) rejects projection-alias references like
SELECT id AS x ... ORDER BY x. Slice 21 (set-op outer)
accepts alias references positionally against branch[0]'s
outputs — the alias IS the set-op output schema. The two paths
diverge intentionally; see
SemanticIRBuilder.buildOrderByColumnRefs (slice 9) versus
SemanticIRBuilder.buildSetOpOuterOrderByColumnRefs (slice 21).
| Constructor and Description |
|---|
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<ColumnRef> pivotColumnRefs)
Slice 129 PIVOT SELECT constructor — a
SELECT whose FROM
source is a PIVOT. |
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> pivotColumnRefs)
Slice 156 PIVOT SELECT constructor — the slice-129 PIVOT shape plus a
filterColumnRefs slot for an admitted passthrough-only
WHERE clause over a PIVOT (every WHERE ref resolves to a provable
passthrough source column). |
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> pivotColumnRefs)
Slice 158 PIVOT SELECT constructor — the slice-156 PIVOT shape plus a
groupByColumnRefs slot for an admitted passthrough-only
GROUP BY clause over a PIVOT/UNPIVOT (every GROUP BY ref resolves
to a provable passthrough source column). |
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> qualifyColumnRefs,
List<ColumnRef> pivotColumnRefs)
Slice 159 PIVOT SELECT constructor — the slice-158 PIVOT shape plus a
qualifyColumnRefs slot for an admitted passthrough-only
QUALIFY clause over a PIVOT/UNPIVOT (every QUALIFY ref resolves to a
provable passthrough source column). |
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> havingColumnRefs,
List<ColumnRef> qualifyColumnRefs,
List<ColumnRef> pivotColumnRefs)
Slice 160 PIVOT SELECT constructor — the slice-159 PIVOT shape plus a
havingColumnRefs slot for an admitted passthrough-only
HAVING clause over a PIVOT/UNPIVOT (every HAVING ref resolves to a
provable passthrough source column). |
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> joinColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> havingColumnRefs,
List<ColumnRef> orderByColumnRefs,
boolean distinct,
SetOperator setOperator,
RowLimit rowLimit)
Pre-slice-73 constructor preserved so hand-built test fixtures
(e.g.
|
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> havingColumnRefs,
List<ColumnRef> qualifyColumnRefs,
List<ColumnRef> orderByColumnRefs,
List<ColumnRef> pivotColumnRefs)
Slice 161 PIVOT SELECT constructor — the slice-160 PIVOT shape plus an
orderByColumnRefs slot for a passthrough-only ORDER BY
clause over a PIVOT/UNPIVOT (every sort key resolves to a provable
passthrough source column). |
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> joinColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> havingColumnRefs,
List<ColumnRef> orderByColumnRefs,
List<ColumnRef> distinctOnColumnRefs,
boolean distinct,
SetOperator setOperator,
RowLimit rowLimit)
Slice 73 constructor preserved so SELECT-kind production code that
predates slice 78 keeps compiling unchanged.
|
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> joinColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> havingColumnRefs,
List<ColumnRef> orderByColumnRefs,
List<ColumnRef> distinctOnColumnRefs,
boolean distinct,
SetOperator setOperator,
RowLimit rowLimit,
TargetRelation target)
Slice 78 constructor preserved so production code that predates
slice 85 keeps compiling unchanged.
|
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> joinColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> havingColumnRefs,
List<ColumnRef> orderByColumnRefs,
List<ColumnRef> distinctOnColumnRefs,
List<ColumnRef> qualifyColumnRefs,
boolean distinct,
SetOperator setOperator,
RowLimit rowLimit)
Slice 125 SELECT constructor — the slice-73 SELECT shape plus the
qualifyColumnRefs slot. |
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> joinColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> havingColumnRefs,
List<ColumnRef> orderByColumnRefs,
List<ColumnRef> distinctOnColumnRefs,
List<ColumnRef> qualifyColumnRefs,
List<GroupingElement> groupingElements,
boolean distinct,
SetOperator setOperator,
RowLimit rowLimit)
Slice 128 SELECT constructor — the slice-125 SELECT shape plus the
groupingElements slot, the structured GROUP BY view. |
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<OutputColumn> returningColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> joinColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> havingColumnRefs,
List<ColumnRef> orderByColumnRefs,
List<ColumnRef> distinctOnColumnRefs,
boolean distinct,
SetOperator setOperator,
RowLimit rowLimit,
TargetRelation target)
Slice 85 constructor preserved so production code that predates
slice 125 keeps compiling unchanged.
|
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<OutputColumn> returningColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> joinColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> havingColumnRefs,
List<ColumnRef> orderByColumnRefs,
List<ColumnRef> distinctOnColumnRefs,
List<ColumnRef> qualifyColumnRefs,
boolean distinct,
SetOperator setOperator,
RowLimit rowLimit,
TargetRelation target)
Slice 125 primary constructor preserved — adds the optional
qualifyColumnRefs slot for the QUALIFY clause
(Snowflake / BigQuery / Teradata). |
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<OutputColumn> returningColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> joinColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> havingColumnRefs,
List<ColumnRef> orderByColumnRefs,
List<ColumnRef> distinctOnColumnRefs,
List<ColumnRef> qualifyColumnRefs,
List<GroupingElement> groupingElements,
boolean distinct,
SetOperator setOperator,
RowLimit rowLimit,
TargetRelation target)
Slice 128 primary constructor preserved — adds the optional
groupingElements slot, the structured per-top-level-element
view of the GROUP BY (SIMPLE / ROLLUP /
CUBE / GROUPING SETS; see GroupingElement). |
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<OutputColumn> returningColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> joinColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> havingColumnRefs,
List<ColumnRef> orderByColumnRefs,
List<ColumnRef> distinctOnColumnRefs,
List<ColumnRef> qualifyColumnRefs,
List<GroupingElement> groupingElements,
List<ColumnRef> pivotColumnRefs,
boolean distinct,
SetOperator setOperator,
RowLimit rowLimit,
TargetRelation target)
Slice 129 primary constructor — adds the optional
pivotColumnRefs slot, the columns CONSUMED by a PIVOT
operator (the FOR / pivot column(s) followed by the
aggregation-function argument column(s)). |
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<OutputColumn> returningColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> joinColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> havingColumnRefs,
List<ColumnRef> orderByColumnRefs,
List<ColumnRef> distinctOnColumnRefs,
List<ColumnRef> qualifyColumnRefs,
List<GroupingElement> groupingElements,
List<ColumnRef> pivotColumnRefs,
boolean distinct,
SetOperator setOperator,
RowLimit rowLimit,
TargetRelation target,
JoinAnalysisFacts joinAnalysisFacts)
Slice 167 primary constructor — adds the single optional
JoinAnalysisFacts carrier (GAP 1/2/4). |
StatementGraph(String name,
String kind,
List<RelationSource> relations,
List<OutputColumn> outputColumns,
List<OutputColumn> returningColumns,
List<ColumnRef> filterColumnRefs,
List<ColumnRef> joinColumnRefs,
List<ColumnRef> groupByColumnRefs,
List<ColumnRef> havingColumnRefs,
List<ColumnRef> orderByColumnRefs,
List<ColumnRef> distinctOnColumnRefs,
List<ColumnRef> qualifyColumnRefs,
List<GroupingElement> groupingElements,
List<ColumnRef> pivotColumnRefs,
boolean distinct,
SetOperator setOperator,
RowLimit rowLimit,
TargetRelation target,
JoinAnalysisFacts joinAnalysisFacts,
SourceSpan sourceSpan)
Slice 179 (R5) primary constructor — adds the optional block-level
SourceSpan covering this statement's own source text. |
| Modifier and Type | Method and Description |
|---|---|
List<ColumnRef> |
getDistinctOnColumnRefs()
Column references in the
DISTINCT ON (cols) partition list
(PostgreSQL / Greenplum). |
List<ColumnRef> |
getFilterColumnRefs() |
List<ColumnRef> |
getGroupByColumnRefs() |
List<GroupingElement> |
getGroupingElements()
Structured per-top-level-element view of the
GROUP BY (slice
128): one GroupingElement per top-level grouping item in
document order, each tagged SIMPLE / ROLLUP /
CUBE / GROUPING_SETS with its flattened member
columns. |
List<ColumnRef> |
getHavingColumnRefs()
Column references that appear in the
HAVING clause's
predicate. |
JoinAnalysisFacts |
getJoinAnalysisFacts()
Join-analysis facts for this query block (slice 167, GAP 1/2/4):
the structured
JoinGraph, WHERE filter predicates, and
query-block scope. |
List<ColumnRef> |
getJoinColumnRefs() |
JoinGraph |
getJoinGraph()
Convenience accessor for the structured
JoinGraph (slice
167). |
String |
getKind() |
String |
getName()
Nullable: name for a CTE body or FROM-subquery alias, else null.
|
List<ColumnRef> |
getOrderByColumnRefs()
Column references that appear in the
ORDER BY clause's sort
keys. |
List<OutputColumn> |
getOutputColumns() |
List<ColumnRef> |
getPivotColumnRefs()
Slice 129 — columns CONSUMED by a
PIVOT operator, in document
order: the FOR / pivot column(s) first, then the
aggregation-function argument column(s). |
List<ColumnRef> |
getQualifyColumnRefs()
Column references that appear in the
QUALIFY clause's
predicate (Snowflake / BigQuery / Teradata). |
List<RelationSource> |
getRelations() |
List<OutputColumn> |
getReturningColumns()
Slice 85 — RETURNING / OUTPUT projection columns for INSERT / UPDATE /
DELETE statements.
|
RowLimit |
getRowLimit()
Per-statement row-limit metadata (slice 70).
|
SetOperator |
getSetOperator()
Set-operation kind for the outer statement of a set-op program
(slice 12).
|
SourceSpan |
getSourceSpan()
Optional block-level source span (slice 179, R5) covering this
statement's own text, or
null when not set. |
TargetRelation |
getTarget()
Slice 78 — write-side target for INSERT statements.
|
boolean |
isDistinct()
Whether the statement applies row-deduplication.
|
StatementGraph |
withJoinAnalysisFacts(JoinAnalysisFacts facts)
Return a copy of this statement with its
JoinAnalysisFacts
replaced. |
StatementGraph |
withSourceSpan(SourceSpan newSourceSpan)
Return a copy of this statement with its block-level
sourceSpan replaced (slice 179, R5). |
public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<OutputColumn> returningColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> joinColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> havingColumnRefs, List<ColumnRef> orderByColumnRefs, List<ColumnRef> distinctOnColumnRefs, List<ColumnRef> qualifyColumnRefs, List<GroupingElement> groupingElements, List<ColumnRef> pivotColumnRefs, boolean distinct, SetOperator setOperator, RowLimit rowLimit, TargetRelation target)
pivotColumnRefs slot, the columns CONSUMED by a PIVOT
operator (the FOR / pivot column(s) followed by the
aggregation-function argument column(s)). The slot is always non-null
(use Collections.emptyList() when absent); non-empty only on a
SELECT whose FROM source is a PIVOT. All other slots are
unchanged. See getPivotColumnRefs().public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<OutputColumn> returningColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> joinColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> havingColumnRefs, List<ColumnRef> orderByColumnRefs, List<ColumnRef> distinctOnColumnRefs, List<ColumnRef> qualifyColumnRefs, List<GroupingElement> groupingElements, List<ColumnRef> pivotColumnRefs, boolean distinct, SetOperator setOperator, RowLimit rowLimit, TargetRelation target, JoinAnalysisFacts joinAnalysisFacts)
JoinAnalysisFacts carrier (GAP 1/2/4). Every prior
constructor delegates here with JoinAnalysisFacts.EMPTY, so
the additive slot does not grow the constructor surface per GAP. A
null joinAnalysisFacts coalesces to EMPTY.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<OutputColumn> returningColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> joinColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> havingColumnRefs, List<ColumnRef> orderByColumnRefs, List<ColumnRef> distinctOnColumnRefs, List<ColumnRef> qualifyColumnRefs, List<GroupingElement> groupingElements, List<ColumnRef> pivotColumnRefs, boolean distinct, SetOperator setOperator, RowLimit rowLimit, TargetRelation target, JoinAnalysisFacts joinAnalysisFacts, SourceSpan sourceSpan)
SourceSpan covering this statement's own source text. Every
prior constructor delegates here with a null span (additive). Set at
the SELECT construction site (where the parse node is in scope) and
read by attachQueryBlockScopes so each QueryBlockScope
carries an honest span.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<OutputColumn> returningColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> joinColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> havingColumnRefs, List<ColumnRef> orderByColumnRefs, List<ColumnRef> distinctOnColumnRefs, List<ColumnRef> qualifyColumnRefs, List<GroupingElement> groupingElements, boolean distinct, SetOperator setOperator, RowLimit rowLimit, TargetRelation target)
groupingElements slot, the structured per-top-level-element
view of the GROUP BY (SIMPLE / ROLLUP /
CUBE / GROUPING SETS; see GroupingElement).
Delegates to the slice-129 primary with empty pivotColumnRefs.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<OutputColumn> returningColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> joinColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> havingColumnRefs, List<ColumnRef> orderByColumnRefs, List<ColumnRef> distinctOnColumnRefs, List<ColumnRef> qualifyColumnRefs, boolean distinct, SetOperator setOperator, RowLimit rowLimit, TargetRelation target)
qualifyColumnRefs slot for the QUALIFY clause
(Snowflake / BigQuery / Teradata). Delegates to the slice-128
primary constructor with empty groupingElements.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<OutputColumn> returningColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> joinColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> havingColumnRefs, List<ColumnRef> orderByColumnRefs, List<ColumnRef> distinctOnColumnRefs, boolean distinct, SetOperator setOperator, RowLimit rowLimit, TargetRelation target)
qualifyColumnRefs. QUALIFY
is a SELECT-only clause, so DML / predicate-body / set-op-outer
call sites correctly default to empty.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> joinColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> havingColumnRefs, List<ColumnRef> orderByColumnRefs, List<ColumnRef> distinctOnColumnRefs, boolean distinct, SetOperator setOperator, RowLimit rowLimit, TargetRelation target)
returningColumns.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> joinColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> havingColumnRefs, List<ColumnRef> orderByColumnRefs, List<ColumnRef> distinctOnColumnRefs, boolean distinct, SetOperator setOperator, RowLimit rowLimit)
target=null.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> joinColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> havingColumnRefs, List<ColumnRef> orderByColumnRefs, List<ColumnRef> distinctOnColumnRefs, List<ColumnRef> qualifyColumnRefs, boolean distinct, SetOperator setOperator, RowLimit rowLimit)
qualifyColumnRefs slot. Used by the shared SELECT builder
(SemanticIRBuilder.buildSelectStatementImpl) so a SELECT
carrying a QUALIFY clause can pass its resolved filter refs.
Delegates to the slice-125 primary constructor with empty
returningColumns and target=null. The parameter
list differs from the slice-78 14-arg constructor by type
(a List qualifyColumnRefs at position 11 vs a
boolean distinct there), so overload resolution is
unambiguous.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> joinColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> havingColumnRefs, List<ColumnRef> orderByColumnRefs, List<ColumnRef> distinctOnColumnRefs, List<ColumnRef> qualifyColumnRefs, List<GroupingElement> groupingElements, boolean distinct, SetOperator setOperator, RowLimit rowLimit)
groupingElements slot, the structured GROUP BY view. Used by
the shared SELECT builder (SemanticIRBuilder) so a SELECT
with a GROUP BY can pass its structured grouping elements. Delegates
to the slice-128 primary with empty returningColumns and
target=null. The parameter list differs from the slice-125
14-arg SELECT constructor by the extra List groupingElements
arg, so overload resolution is unambiguous.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<ColumnRef> pivotColumnRefs)
SELECT whose FROM
source is a PIVOT. Carries relations (the underlying
pivot source), outputColumns (one per projected column), and
pivotColumnRefs (the consumed FOR + aggregation-arg columns).
Every other slot defaults empty / null: a slice-129 PIVOT skeleton has
no filter / join / group-by / having / order-by / distinct-on /
qualify / grouping / returning refs, is not DISTINCT, is not a
set-op, has no row-limit, and writes no target. The five-arg shape is
unambiguous against every other constructor.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> pivotColumnRefs)
filterColumnRefs slot for an admitted passthrough-only
WHERE clause over a PIVOT (every WHERE ref resolves to a provable
passthrough source column). All other clause slots default empty / null,
exactly as the five-arg PIVOT constructor — so an admitted PIVOT without a
WHERE (empty filterColumnRefs) is byte-identical to the five-arg
form. The six-arg shape (two List<ColumnRef> trailing args) is
unambiguous against every other constructor by arity.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> pivotColumnRefs)
groupByColumnRefs slot for an admitted passthrough-only
GROUP BY clause over a PIVOT/UNPIVOT (every GROUP BY ref resolves
to a provable passthrough source column). All other clause slots default
empty / null, exactly as the six-arg PIVOT constructor — so an admitted
PIVOT without a GROUP BY (empty groupByColumnRefs) is byte-identical
to the six-arg form. The seven-arg shape (three List<ColumnRef>
trailing args) is unambiguous against every other constructor by arity.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> qualifyColumnRefs, List<ColumnRef> pivotColumnRefs)
qualifyColumnRefs slot for an admitted passthrough-only
QUALIFY clause over a PIVOT/UNPIVOT (every QUALIFY ref resolves to a
provable passthrough source column). All other clause slots default empty /
null, exactly as the seven-arg PIVOT constructor — so an admitted PIVOT
without a QUALIFY (empty qualifyColumnRefs) is byte-identical to the
seven-arg form. The eight-arg shape (four List<ColumnRef> trailing
args) is unambiguous against every other constructor by arity.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> havingColumnRefs, List<ColumnRef> qualifyColumnRefs, List<ColumnRef> pivotColumnRefs)
havingColumnRefs slot for an admitted passthrough-only
HAVING clause over a PIVOT/UNPIVOT (every HAVING ref resolves to a
provable passthrough source column). All other clause slots default empty /
null, exactly as the eight-arg PIVOT constructor — so an admitted PIVOT
without a HAVING (empty havingColumnRefs) is byte-identical to the
eight-arg form. The nine-arg shape (five List<ColumnRef> trailing
args) is unambiguous against every other constructor by arity. The trailing
args follow the natural SQL clause order: filter (WHERE), groupBy, having,
qualify, then the consumed pivot refs.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> havingColumnRefs, List<ColumnRef> qualifyColumnRefs, List<ColumnRef> orderByColumnRefs, List<ColumnRef> pivotColumnRefs)
orderByColumnRefs slot for a passthrough-only ORDER BY
clause over a PIVOT/UNPIVOT (every sort key resolves to a provable
passthrough source column). UNLIKE the WHERE/GROUP BY/HAVING/QUALIFY
slots, an ORDER BY over a pivot was already admitted (slice 142,
lineage-neutral), so this slot only refines the lineage and is empty when
no passthrough sort key can be proven. All other clause slots default
empty / null, exactly as the nine-arg PIVOT constructor — so an admitted
PIVOT without a passthrough ORDER BY (empty orderByColumnRefs) is
byte-identical to the nine-arg form. The ten-arg shape (six
List<ColumnRef> trailing args) is unambiguous against every other
constructor by arity. The trailing args follow the natural SQL clause
order: filter (WHERE), groupBy, having, qualify, orderBy, then the
consumed pivot refs.public StatementGraph(String name, String kind, List<RelationSource> relations, List<OutputColumn> outputColumns, List<ColumnRef> filterColumnRefs, List<ColumnRef> joinColumnRefs, List<ColumnRef> groupByColumnRefs, List<ColumnRef> havingColumnRefs, List<ColumnRef> orderByColumnRefs, boolean distinct, SetOperator setOperator, RowLimit rowLimit)
SemanticIRProjectorBodyIndexesTest) continue to
compile without touching every call site. Delegates to the
slice-73 constructor with an empty distinctOnColumnRefs
list. New production code should call the slice-78 primary
constructor directly.public StatementGraph withJoinAnalysisFacts(JoinAnalysisFacts facts)
JoinAnalysisFacts
replaced. Used by the builder (slices 167/168/169/170) to attach
join/predicate/scope facts after the flat graph is built, without
mutating this immutable value. Preserves the block sourceSpan.public StatementGraph withSourceSpan(SourceSpan newSourceSpan)
sourceSpan replaced (slice 179, R5). Preserves the
JoinAnalysisFacts.public List<RelationSource> getRelations()
public List<OutputColumn> getOutputColumns()
public List<OutputColumn> getReturningColumns()
For PG / Oracle RETURNING, each entry's
OutputColumn.getName() is the explicit alias when present,
else the verbatim bare column spelling.
OutputColumn.getSources() lists the underlying column refs;
the relationAlias resolves through the same provider used
for SET RHS / WHERE / JOIN ON, so a joined-UPDATE with
RETURNING t.a, s.x produces refs against both target and
FROM-side relations.
For SQL Server OUTPUT pseudo-table refs (INSERTED.col,
DELETED.col), the relationAlias is preserved as the
uppercase pseudo-table name ("INSERTED" or
"DELETED") so consumers can distinguish post-write from
pre-write row state. Lineage edges still flow to
LineageRef.tableColumn(String, String) pointing at the
physical target table column — both INSERTED and DELETED ultimately
reference the same physical column; only the temporal phase differs.
public List<ColumnRef> getFilterColumnRefs()
public List<ColumnRef> getJoinColumnRefs()
public List<ColumnRef> getGroupByColumnRefs()
public List<ColumnRef> getHavingColumnRefs()
HAVING clause's
predicate. The list is per-statement and per-clause: a HAVING
predicate that names d.id contributes one entry; a HAVING
predicate inside an aggregate (HAVING SUM(salary) > 1000)
contributes the underlying column (salary) — the same
convention used for projection-side aggregate arguments
(slice 6 OutputColumn.sources).
Subqueries in HAVING (scalar, EXISTS, IN-SELECT, ANY/ALL/SOME) and window functions in HAVING are rejected by the builder rather than silently captured, because the visitor would descend into inner scopes and leak refs (mirrors the slice-9 ORDER BY guards).
HAVING is row-influence semantically (it filters out groups),
but it deliberately does not contribute to the canonical
lineage model (slice 7 / CanonicalLineageEdge). The
canonical model is a parity contract between IR and dlineage, and
dlineage exposes no per-clause HAVING field — it folds HAVING refs
into aggregate-function fdr/fdd edges. Including HAVING-derived
canonical edges only on the IR side would manufacture
divergence-by-design. The havingColumnRefs field remains
useful for downstream consumers (SQL Guard, lineage explainers)
that don't depend on the dlineage parity contract.
public List<ColumnRef> getOrderByColumnRefs()
ORDER BY clause's sort
keys. Only physical column references are recorded — ordinal
(ORDER BY 1) and projection-alias (ORDER BY x)
forms are rejected by the builder, not silently emitted as
[]. Sort direction (ASC/DESC) and null
placement (NULLS FIRST/NULLS LAST) are presentation
metadata and are not modelled.
The flag is per-statement: in
WITH x AS (... ORDER BY id) SELECT id FROM x the inner
statement's orderByColumnRefs contains id while the
outer's is empty.
public boolean isDistinct()
SELECT DISTINCT, Oracle's deprecated synonym
SELECT UNIQUE, AND PostgreSQL / Greenplum
SELECT DISTINCT ON (cols); false for SELECT,
SELECT ALL, and the absence of any row-filter clause.
The flag is per-statement, never per-output.
For DISTINCT ON (cols) the partition keys live on
getDistinctOnColumnRefs(); the boolean here pins the
semantic invariant that the statement deduplicates rows
regardless of which key shape is used.
public List<ColumnRef> getDistinctOnColumnRefs()
DISTINCT ON (cols) partition list
(PostgreSQL / Greenplum). Empty for plain SELECT DISTINCT,
SELECT UNIQUE, SELECT ALL, and the absence of any
row-filter clause.
Invariant: !distinctOnColumnRefs.isEmpty() implies
isDistinct() == true. The reverse does not hold
(plain DISTINCT also returns true).
The list collects physical column refs the same way
groupByColumnRefs does: column refs inside compound
expressions (a + b, CASE WHEN ...) and aggregate
arguments (COUNT(x)) are descended into; subqueries and
window functions in DISTINCT ON are rejected by the
builder so they cannot leak inner-scope refs.
Oracle, MySQL, Redshift and other non-PG vendors silently
accept DISTINCT ON (...) as plain DISTINCT —
their parser drops the ON expression list, so this slot stays
empty for those vendors regardless of the surface SQL.
public List<ColumnRef> getQualifyColumnRefs()
QUALIFY clause's
predicate (Snowflake / BigQuery / Teradata). QUALIFY filters rows on
window-function results; it is row-influence in the same family as
WHERE and HAVING.
Two surface forms reduce to the SAME set of influencing base columns:
QUALIFY ROW_NUMBER() OVER (PARTITION BY a ORDER BY b) = 1)
— the window's PARTITION BY / ORDER BY / argument refs are
collected directly (a, b).QUALIFY rn = 1 where
rn aliases a window projection) — the alias resolves to
the matching OutputColumn; its influencing columns are
getSources() unioned with the
WindowSpec.getPartitionRefs() and
WindowSpec.getOrderRefs() of its window spec (a window
OutputColumn.getSources() is empty on its own).Subqueries in QUALIFY are rejected by the builder (they would leak inner-scope refs); window functions are admitted (the whole point of QUALIFY).
Like havingColumnRefs, this slot is row-influence
semantically but deliberately does not contribute to the
canonical lineage model (slice 7 / CanonicalLineageEdge).
The canonical model is a parity contract with dlineage, which
exposes no per-clause QUALIFY field; emitting QUALIFY-derived
canonical edges only on the IR side would manufacture
divergence-by-design.
public List<GroupingElement> getGroupingElements()
GROUP BY (slice
128): one GroupingElement per top-level grouping item in
document order, each tagged SIMPLE / ROLLUP /
CUBE / GROUPING_SETS with its flattened member
columns. Empty iff the statement has no GROUP BY items; a
plain GROUP BY a, b yields [SIMPLE: a, SIMPLE: b].
This is additive to getGroupByColumnRefs(), which still
returns the flat, deduplicated, document-order union of every
grouping column (slice 127) regardless of grouping structure.
groupingElements preserves the structure the flat list
discards — relevant for governance (a ROLLUP/CUBE
changes output cardinality and produces super-aggregate rows) and
for downstream OpenLineage / DataHub consumers.
public List<ColumnRef> getPivotColumnRefs()
PIVOT operator, in document
order: the FOR / pivot column(s) first, then the
aggregation-function argument column(s). All resolve to the underlying
pivot source relation (getRelations()). Empty on every
non-PIVOT statement.
These are the input columns a PIVOT reads; the IN-list values
become the new output column names (synthesised in a later sub-slice).
Function names, literals, and column-alias nodes (e.g. the Oracle
SUM(quantity) AS q) are not columns and do not appear here.
Slice 129 (sub-slice a) admits only a PIVOT over a base-table
source with an explicit (non-*) projection and no other query
clauses; broader shapes (UNPIVOT, subquery source, SELECT *
expansion, output-column lineage) are deferred to later sub-slices and
rejected with structured PIVOT_* diagnostics until then.
public SetOperator getSetOperator()
_ALL variants encode TSelectSqlStatement#isAll();
MINUS (Oracle / Spark / Hive) and EXCEPT
(PostgreSQL / SQL Server / standard) are kept distinct because the
parser exposes them as separate
ESetOperatorType values, even though
they are semantically equivalent.public RowLimit getRowLimit()
LIMIT N OFFSET M, MySQL inline LIMIT M, N,
set-op outer row-limit) — those surfaces continue to be rejected
by the builder with their existing diagnostic codes.
When non-null, the RowLimit.getKind() captures which
surface SQL form was used (LIMIT vs FETCH FIRST)
and RowLimit.getCount() captures the verbatim count text.
Row-limit metadata does not change column lineage. The
canonical lineage model (slice 7 / CanonicalLineageEdge)
deliberately ignores it: row-limit is presentation-time pruning,
not a column-flow influence. ORDER BY refs, output sources,
filter / join / group-by / having refs are all unaffected.
public TargetRelation getTarget()
"INSERT"-kind statements; null on every "SELECT"-kind
statement (whether the SELECT is an outer, CTE body, FROM-subquery
body, scalar-subquery body, or set-op branch).
When non-null, TargetRelation.getBinding() is the target
table (kind = RelationKind.TABLE) and
TargetRelation.getColumns() holds the verbatim SQL column-list
spellings (empty list when the SQL author omitted the column list).
Cross-statement LineageEdges for INSERT use
LineageRef.tableColumn(String, String) as the from
endpoint (target_table, target_col) and
LineageRef.statementOutput(int, String) as the to
endpoint (source SELECT body statement index + output name).
public JoinAnalysisFacts getJoinAnalysisFacts()
JoinGraph, WHERE filter predicates, and
query-block scope. Never null (JoinAnalysisFacts.EMPTY when
not populated).public JoinGraph getJoinGraph()
JoinGraph (slice
167). Never null (JoinGraph.EMPTY when this block has no
modelled joins).public SourceSpan getSourceSpan()
null when not set. The same span is
surfaced on QueryBlockScope#getSourceSpan().