Skip to content

fix(snowflake): do not quote parameter names in ALTER SESSION - #6122

Open
DG47 wants to merge 6 commits into
SQLMesh:mainfrom
DG47:fix/snowflake-alter-session-quoting
Open

DG47 wants to merge 6 commits into
SQLMesh:mainfrom
DG47:fix/snowflake-alter-session-quoting

Conversation

@DG47

@DG47 DG47 commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Description

Fixes #5666.

Snowflake session parameters (TIMEZONE, QUERY_TAG, ...) are keywords, not identifiers, so ALTER SESSION SET "TIMEZONE" = 'UTC' is a syntax error. sqlglot parses the parameter names in ALTER SESSION SET/UNSET as identifiers (Column(Identifier) / Identifier), so a model pre/post statement such as

ALTER SESSION SET TIMEZONE = 'UTC';

was quoted twice: once by the renderer's normalize-and-quote step and again by EngineAdapter._to_sql. It reached Snowflake as ALTER SESSION SET "TIMEZONE" = 'UTC'.

This adds a small parser override in sqlmesh/core/dialect.py, following the same pattern as the existing T-SQL ALTER COLUMN override. After sqlglot parses ALTER SESSION, unquoted parameter names become exp.Var, so they are neither normalized nor quoted. Values are left alone (literals, macros such as @tag, etc.), and so are parameter names the user quoted explicitly.

The SQL produced for the unrendered statement doesn't change (TIMEZONE = 'UTC' both before and after), so model data and metadata hashes stay the same and existing snapshots aren't affected. I checked this on a sample model.

An earlier attempt (#5670) turned quoting off for every Alter/Set statement in the Snowflake adapter and also special-cased the renderer. Its author closed it. This change only touches ALTER SESSION parameter names and lives at the parse level, so the renderer and the engine adapter both pick it up without engine-specific code in either.

Test Plan

  • tests/core/test_dialect.py::test_snowflake_alter_session_parameters_are_not_quoted: parse/generate with identify=True for SET (with a macro value), UNSET, and an explicitly quoted name, plus rendered model pre/post statements.
  • tests/core/engine_adapter/test_snowflake.py::test_alter_session_parameters_are_not_quoted: SQL executed by the mocked Snowflake adapter.
  • Both tests fail on main (ALTER SESSION SET "TIMEZONE" = 'UTC') and pass with the fix.
  • pytest -n 8 -m "fast and not web and not github and not dbt and not jupyter and not cicdonly and not isolated": 2436 passed. 6 failures in tests/core/test_connection_config.py (pyodbc) are unrelated and come from a missing local unixODBC library; they fail the same way on main.
  • pytest -m "dbt and fast" tests/dbt: 88 passed.
  • SKIP=prettier,eslint pre-commit run --all-files (ruff, ruff-format, mypy, migrations): passed. The prettier/eslint hooks were skipped because no frontend files changed.

Checklist

  • I have run make style and fixed any issues
  • I have added tests for my changes (if applicable)
  • All existing tests pass (make fast-test) (I ran the core fast and dbt fast subsets listed above, not the whole target)
  • My commits are signed off (git commit -s) per the DCO

Summary by CodeRabbit

  • Bug Fixes
    • Snowflake ALTER SESSION SET and UNSET statements now retain unquoted parameter names when generated, avoiding unexpected quoting.
    • Explicitly quoted parameter names remain quoted, and model pre- and post-statements preserve unquoted names.

DG47 and others added 3 commits October 8, 2026 06:39
Session parameters such as TIMEZONE or QUERY_TAG are keywords, not
identifiers, so Snowflake rejects them when quoted. sqlglot parses them
as identifiers, which means model pre/post statements like
ALTER SESSION SET TIMEZONE = 'UTC' were rendered and executed as
ALTER SESSION SET "TIMEZONE" = 'UTC', a syntax error.

Parse unquoted parameter names in ALTER SESSION SET/UNSET as vars so
they are neither normalized nor quoted.

Fixes SQLMesh#5666

Signed-off-by: Dhruv Gupta <dg@usesparx.com>
…ession-quoting

# Conflicts:
#	tests/core/engine_adapter/test_snowflake.py

@Vamsi-klu Vamsi-klu left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, doing this at parse time is a lot cleaner than the adapter + renderer route from #5670. I double checked the hash claim: a Snowflake model with ALTER SESSION SET TIMEZONE = 'UTC', query_tag = 'x' as a pre statement has the same data and metadata hash on main and on this branch, only the rendered SQL changes. One scoping nit inline, looks good otherwise.

Comment thread sqlmesh/core/dialect.py Outdated
_override(Parser, _parse_interval_span)
_override(Parser, _warn_unsupported)
_override(Snowflake.Parser, _parse_table_parts)
_override(Parser, _parse_alter_session)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On sqlglot 30.8 only the Snowflake parser sends ALTER SESSION to _parse_alter_session, Oracle and Databricks still end up as Command. So it's Snowflake only in practice, but overriding the base Parser makes it read as global. Could this be _override(Snowflake.Parser, _parse_alter_session) like the _parse_table_parts one above? Keeps the scope obvious and won't quietly pick up other dialects if sqlglot routes them here later.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, done in 637af55: the override is now registered on Snowflake.Parser next to _parse_table_parts, and the function is annotated accordingly. I checked that Databricks and Oracle still come out as Command with the original text untouched.

Comment thread sqlmesh/core/dialect.py
if isinstance(name, exp.Column) and not name.table:
name = name.this
if isinstance(name, exp.Identifier) and not name.quoted:
name.replace(exp.var(name.name))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, no change needed: since these are Vars now they don't get normalized, so query_tag stays lowercase where main uppercased it. Snowflake doesn't care about case for parameter names so it's harmless, but maybe worth a line in the comment above so nobody "fixes" it later.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a sentence to the comment in the same commit explaining that vars skip case normalization, that query_tag therefore stays lowercase, and that Snowflake treats parameter names case-insensitively so this is intentional.

@DG47

DG47 commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

@cmgoffena13 could you take a look at this one? It fixes #5666: Snowflake session parameters in ALTER SESSION SET/UNSET were quoted as identifiers (ALTER SESSION SET "TIMEZONE" = 'UTC'), which Snowflake rejects. @Vamsi-klu's two review points from 10-18 are addressed in 637af55: the override is registered on Snowflake.Parser only, and there's a comment on the lowercase parameter names.

@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 27abc448-98ec-4e15-8000-db4266a0c4a6
Commits

Reviewing files that changed from the base of the PR and between f6527ff and 99b31ca.

Files selected for processing: 3
  • sqlmesh/core/dialect.py
  • tests/core/engine_adapter/test_snowflake.py
  • tests/core/test_dialect.py

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Walkthrough

The Snowflake parser now converts unquoted ALTER SESSION parameter names to vars. Tests cover SQL rendering through parser, engine adapter, and model-loading paths. Explicitly quoted names remain quoted.

Changes: Snowflake ALTER SESSION parameter handling

Layer / File(s) Summary
Parse unquoted session parameters
sqlmesh/core/dialect.py
The Snowflake parser converts unquoted identifier parameter names in SET and UNSET statements to vars. The parser override is registered on Snowflake.Parser.
Verify SQL rendering paths
tests/core/test_dialect.py, tests/core/engine_adapter/test_snowflake.py
Tests check rendering with identifier quoting enabled, preserve explicitly quoted names, and verify engine adapter and model pre-/post-statement output.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: vamsi-klu

Merge Risk: Minimal · up to 99b31

The Snowflake parameter-rendering change has no identified issue that needs resolution before merging.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surv… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title "fix(snowflake): do not quote parameter names in ALTER SESSION" states the main change. The changeset adds a Snowflake parser override in sqlmesh/core/dialect.py so unquoted ALTER SESSION SE…
Description check Passed The description follows the template. It has a Description section that explains the bug (Snowflake session parameters are keywords, and sqlglot parses ALTER SESSION parameter names as identifiers, so…
Linked Issues check Passed Issue [#5666] requires Snowflake session parameter names to remain unquoted in generated ALTER SESSION SQL. sqlmesh/core/dialect.py adds a Snowflake parser override that converts unquoted SET an…
Out of Scope Changes check Passed The changes are limited to the Snowflake parser override and focused dialect and Snowflake engine adapter tests. The tests directly validate the issue behavior. No unrelated production changes or unre…
Full details: Title check

Explanation

The title "fix(snowflake): do not quote parameter names in ALTER SESSION" states the main change. The changeset adds a Snowflake parser override in sqlmesh/core/dialect.py so unquoted ALTER SESSION SET/UNSET parameter names parse as exp.Var and are not quoted on output. The title is short, specific, and follows the conventional-commit style. It is clear enough for a teammate scanning history to understand the primary change.

Full details: Description check

Explanation

The description follows the template. It has a Description section that explains the bug (Snowflake session parameters are keywords, and sqlglot parses ALTER SESSION parameter names as identifiers, so they get quoted twice), the fix (a parser override following the existing T-SQL ALTER COLUMN pattern), and the effect on hashes and snapshots. It has a Test Plan section listing the new unit and engine adapter tests, the fail-before and pass-after results, and the commands run with their outcomes. The Checklist is present. One item is left unchecked (make fast-test was not run), and the author explains why. The description also links issue #5666.

Full details: Linked Issues check

Explanation

Issue [#5666] requires Snowflake session parameter names to remain unquoted in generated ALTER SESSION SQL. sqlmesh/core/dialect.py adds a Snowflake parser override that converts unquoted SET and UNSET parameter names to exp.Var. The reported tests cover generated SQL, explicit quoted names, macro values, and rendered model pre/post statements. The engine adapter test verifies ALTER SESSION SET TIMEZONE = 'UTC' and ALTER SESSION UNSET TIMEZONE.

Full details: Out of Scope Changes check

Explanation

The changes are limited to the Snowflake parser override and focused dialect and Snowflake engine adapter tests. The tests directly validate the issue behavior. No unrelated production changes or unrelated test changes are shown.

Full details: Docstring Coverage

Explanation

Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 4 functions across 3 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@DG47
DG47 requested a review from Vamsi-klu October 27, 2026 18:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

quoting parameters in ALTER SESSION SET for Snowflake is illegal syntax.

2 participants