feat(query): extract query lineage from plans - #20201
Open
youngsofun wants to merge 2 commits into
Open
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
youngsofun
force-pushed
the
codex/extract-query-lineage
branch
2 times, most recently
from
July 24, 2026 23:47
d3bc3c8 to
5db6ae0
Compare
Contributor
🤖 CI Job Analysis
📊 Summary
❌ NO RETRY NEEDEDAll failures appear to be code/test issues requiring manual fixes. 🔍 Job Details
🤖 AboutAutomated analysis using job annotations to distinguish infrastructure issues (auto-retried) from code/test issues (manual fixes needed). |
youngsofun
force-pushed
the
codex/extract-query-lineage
branch
2 times, most recently
from
July 26, 2026 16:41
28ce0b9 to
1491c63
Compare
12 tasks
youngsofun
force-pushed
the
codex/extract-query-lineage
branch
from
July 30, 2026 06:57
1491c63 to
85fb6a9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I hereby agree to the terms of the CLA available at: https://docs.databend.com/dev/policies/cla/
Summary
Extract object-level and column-level data flow from optimized query plans through
Plan::query_lineage(), and expose stable column IDs insystem.columnsfor downstream lineage resolution.The extraction result is storage-independent: this PR does not persist lineage or add a query interface. #20230 consumes this planner model through the history-table pipeline.
Motivation
Lineage consumers need a canonical representation of which input relations and columns contribute data to each target relation and column. Reconstructing those edges later from formatted SQL would duplicate binder semantics and would be unreliable for aliases, casts, subqueries, CTEs, optimizer rewrites, mutation expressions, Views, and Streams.
The planner already has resolved relation identities, column IDs, scalar expressions, and the optimized relational tree. Extracting lineage there produces a reusable model while leaving persistence and query policy to downstream consumers.
Stable column IDs are also exposed through
system.columns. This lets a consumer resolve an ID-addressed historical column to its current name after a rename, while correctly rejecting a dropped-and-recreated column that reuses the old name with a new ID.Output model
QueryLineagerecords the statement kind and canonical data-flow edges:The model groups source relations under each target relation. Column edges are sorted and deduplicated. Relations carry catalog, database, name, optional stable ID, catalog type, and relation kind.
Supported target statements include:
CREATE TABLE ... AS SELECT(CTAS)CREATE VIEWwhen the caller supplies its optional query planINSERT ... SELECTand INSERT from StageREPLACE INTO ... SELECTCOPY INTOUPDATE ... FROMandMERGEStatements without a data-producing query return no lineage.
Resolution algorithm
Extraction has two phases:
SExprand build symbol definitions for base scans and data-producing operators.Definitions cover scalar evaluation, aggregate functions, window functions, set-returning functions, UDFs, async functions,
UNION ALL, expression scans, scalar subqueries, and automatic materialized CTE references.Only target value expressions are traversal roots. Columns used exclusively by filters, join predicates,
WHENconditions, or ordering do not become lineage unless they also contribute to an output expression. Aggregate arguments such ascount(col)propagatecol, whilecount(*)has no input column edge.Cycle detection prevents recursive symbol definitions from looping, and ordered sets keep multi-source expressions deterministic.
Relation semantics
AS MATERIALIZEDCTE lineage is not included because the query-scoped temporary relation does not retain its original producer-column mapping.For ordinary INSERT, the target ID is stored only in a lineage field.
table_inforemains unset, so execution still resolves the target by catalog/database/table name and is not pinned to the object observed during planning.Tests
Planner coverage includes CTAS, Views, INSERT SELECT, View and Stream boundaries, Stage scans, CTEs, automatic materialized CTEs, aggregates, joins, subqueries, REPLACE, UPDATE, MERGE, self-insert candidates, external catalog addressing, and multi-table INSERT.
The sqllogic test verifies that
system.columnsexposes stable column IDs.Type of change
AI assistance
This change is