fix(snowflake): quote case-sensitive lowercase column identifiers in generated SQL - #43312
fix(snowflake): quote case-sensitive lowercase column identifiers in generated SQL#43312sadpandajoe wants to merge 4 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #43312 +/- ##
==========================================
- Coverage 66.73% 66.67% -0.06%
==========================================
Files 2876 2876
Lines 164194 164133 -61
Branches 37883 37849 -34
==========================================
- Hits 109570 109434 -136
- Misses 52467 52543 +76
+ Partials 2157 2156 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Code Review Agent Run #3918edActionable Suggestions - 0Review Details
Bito Usage GuideCommands Type the following command in the pull request comment and save the comment.
Refer to the documentation for additional commands. Configuration This repository uses Documentation & Help |
fix(snowflake): quote case-sensitive lowercase column identifiers in generated SQL
SUMMARY
Snowflake folds unquoted identifiers to UPPERCASE. A physical table created with an
explicitly double-quoted, case-sensitive lowercase column (e.g.
create table t ("id" int)) is stored exactly asid, but Superset's generatedchart queries referenced it unquoted (
SELECT id ...). Snowflake then resolved theunquoted reference to
ID, which does not match the physical column, and the queryfailed with a column-not-found error.
Root cause: Superset's Snowflake integration correctly detects the exact reflected
case of a column via SQLAlchemy's
quoted_name(..., quote=True), but that signal islost when the name is persisted into a plain string ORM column
(
TableColumn.column_name). At query-generation time, Superset falls back toSQLAlchemy's generic auto-quoting heuristic, which only quotes identifiers containing
uppercase or special characters — the opposite of Snowflake's own case-folding
convention, where it's the all-lowercase identifiers that need quoting to survive.
Fix: add a
prepare_identifier()hook toBaseEngineSpec(default: no-op, so everyother engine's SQL generation is unchanged) and override it in
SnowflakeEngineSpecto explicitly force-quote the stored identifier via
quoted_name(name, quote=True)whenever the owning dataset has
normalize_columnsdisabled (the default) — in thatcase the stored name is already the exact physical identifier, so quoting it verbatim
is always safe. The hook is applied at the physical-column construction sites used by
chart SELECT/GROUP BY/ORDER BY/WHERE/metric expressions and timestamp columns.
A related but separate symptom — a table whose own name is an explicitly
quoted lowercase Snowflake identifier can block dataset creation — is a different code
path (table/schema existence checks, not column query generation) and is intentionally
out of scope here; it needs its own follow-up.
BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
N/A — backend-only SQL generation fix, no UI change. No Snowflake credentials were
available in this environment to capture a live before/after against a real warehouse;
see TESTING INSTRUCTIONS for how the fix was verified offline.
TESTING INSTRUCTIONS
pytest tests/unit_tests/connectors/sqla/models_test.py -k snowflake_case_sensitivepytest tests/unit_tests/models/helpers_test.py -k snowflake_case_sensitivepytest tests/unit_tests/db_engine_specs/test_snowflake.py -k prepare_identifierpytest tests/unit_tests/db_engine_specs/test_base.py -k prepare_identifierManual verification against a real Snowflake instance (not performed here — no
credentials available):
create table bug_test ("id" int, "name" varchar);then insert a few rows.bug_test.id/namecolumns.ADDITIONAL INFORMATION