Repository navigation
Conversation
developer-rpai
left a comment
Contributor
There was a problem hiding this comment.
Nice defensive work — an unpinned sqlglot silently reclassifying a write as a read would be a nasty failure mode, and tripwires are the right belt-and-suspenders.
A few observations:
- The tests import
_DATA_MODIFYING_NODES(underscore-private) from sql_validation. If a refactor renames that constant — exactly the drift this guards — the tests fail at import time rather than with a useful message. Testing through the publicparse_sql/collect_table_referencesAPI would keep the tripwire semantics without the private coupling. _DIALECTScovers postgres/mysql/snowflake/bigquery/sqlite, but the write-denial parse assertions only run under postgres.MERGE/COPY/SELECT ... INTOparse trees differ by dialect — worth parametrizing at least the dialect-sensitive statements.- On the overlap test: if sqlglot renames a denied class, the old name fails test (a) first anyway, so the failure ordering is sensible — a one-line comment noting that would save the next reader some puzzling.
- Scope question: the root cause named in the comment block is the missing upper bound on sqlglot in pyproject.toml. Tripwires are good, but is an upper-bound pin also wanted?
kaxil
reviewed
Oct 9, 2026
Lee-W
force-pushed
the
common-ai-sqlglot-ast-tripwire
branch
from
October 10, 2026 07:23
cbbde87 to
e5c5cc4
Compare
kaxil
reviewed
Oct 10, 2026
Lee-W
force-pushed
the
common-ai-sqlglot-ast-tripwire
branch
from
October 11, 2026 06:58
e5c5cc4 to
3124621
Compare
sqlglot has no upper bound in common.ai, so an upstream rename, split or removal of an expression class could make the read-only check silently let a write through. These tests fail in CI instead, pointing at the node list in sql_validation.py to review.
- Run the write-rejection matrix with allow_read_only_metadata on and off,
add DESCRIBE ALTER and EXPLAIN DELETE cases, and pin the guard each
statement is expected to hit via match=
- Parse every write statement to its denied node in every dialect from a
single {statement: node} mapping, including CTE and CREATE ... AS SELECT
- Rename the side-effect function test to say it is only flagged when
allowed_tables is set, and pin that validate_sql itself accepts the call
- Drop tripwires that could not fail for the drift they described and the
duplicated read-statement and allow-list control tests
- Add a DESCRIBE ALTER SYSTEM row to the wrapped-write matrix so removing exp.Command from the deny-list fails a test in metadata mode - Add a cte_merge row (MERGE ... THEN DELETE inside a CTE) so removing exp.Merge fails the validate_sql cases, not only the node-type check - Drop test_explain_wrapped_write_still_blocked, which the matrix's explain_delete_mysql row already covers
Lee-W
force-pushed
the
common-ai-sqlglot-ast-tripwire
branch
from
October 11, 2026 09:38
3124621 to
3023832
Compare
This branch has not been deployed
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.
Why
apache-airflow-providers-common-aihas no upper bound onsqlglot. If an upstream release renames, splits or removes anexpexpression class thatutils/sql_validation.pyreferences, the read-only check could silently stop recognising a write statement and let it through. A failure at that point should show up in CI, not in production.What
Adds a
TestSqlglotDriftTripwirestest class. When one of its tests fails after asqlglotbump, the message points at_DATA_MODIFYING_NODES/DEFAULT_ALLOWED_TYPESinutils/sql_validation.pyfor review.CREATE ... AS SELECT, alter, CTE-wrappedDELETE/INSERT,SELECT ... INTO) still parses to the node class named in the deny-list, in postgres, mysql, snowflake, bigquery and sqlite.COPYandGRANT, are rejected in all five dialects withallow_read_only_metadataon and off, and each case pins whether the top-level type check or the deep scan rejects it.DESCRIBE ALTERandEXPLAIN DELETEare rejected by the deep scan in metadata mode.CREATE ... AS SELECT, alter, CTE-wrappedDELETE/INSERT/MERGE,SELECT ... INTO) still parses to the node class named in the deny-list, in postgres, mysql, snowflake, bigquery and sqlite.COPYandGRANT, are rejected in all five dialects withallow_read_only_metadataon and off, and each case pins whether the top-level type check or the deep scan rejects it.DESCRIBE ALTER,DESCRIBE ALTER SYSTEM(parsed asexp.Command) andEXPLAIN DELETEare rejected by the deep scan in metadata mode.Was generative AI tooling used to co-author this PR?
Generated-by: [Claude] following the guidelines
{pr_number}.significant.rst, in airflow-core/newsfragments. You can add this file in a follow-up commit after the PR is created so you know the PR number.