Skip to content

fix: SQL fallback snapshot flush drops PAYLOAD and TAGS#33

Merged
vigneshnarayanaswamy merged 2 commits into
mainfrom
fix/sql-fallback-snapshot-payload
Jul 9, 2026
Merged

fix: SQL fallback snapshot flush drops PAYLOAD and TAGS#33
vigneshnarayanaswamy merged 2 commits into
mainfrom
fix/sql-fallback-snapshot-payload

Conversation

@vigneshnarayanaswamy

Copy link
Copy Markdown
Collaborator

The DDL-free SQL fallback (_flush_snapshots_sql) — the path taken whenever the role can't CREATE TEMPORARY TABLE, i.e. every least-privilege deployment with row-level grants only — inserted just the 7 scalar columns. Every snapshot flushed through it persisted with NULL PAYLOAD and TAGS, silently dropping the event data itself (discovered ports/metadata, observation payloads, record bodies).

The pandas path has always carried both columns; the fallback now matches it: payload/tags ride the UNION ALL source as escaped JSON strings and land via PARSE_JSON(...) in the INSERT...SELECT (expressions are not allowed in VALUES, but are in SELECT).

Regression tests: content preservation through the fallback, and SQL NULL (not the string 'null') for empty payload/tags.

Found by automated review on the downstream repin (a deployment whose writer role has exactly this grant shape); verified against the wheel source before fixing.

🤖 Generated with Claude Code

vigneshnarayanaswamy and others added 2 commits July 9, 2026 10:22
_flush_snapshots_sql — the DDL-free path taken whenever the role cannot
CREATE TEMPORARY TABLE (least-privilege deployments: INSERT/UPDATE only) —
inserted only the 7 scalar columns, silently persisting every snapshot
with NULL PAYLOAD and TAGS. The pandas path carries both; the fallback
must too. Payload/tags now ride the UNION ALL source as escaped JSON
strings and land via PARSE_JSON in the INSERT...SELECT (expressions are
not allowed in VALUES, but are in SELECT).

Two regression tests: content preservation, and NULL (not 'null') for
empty payloads.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d4fc2113c3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +433 to +434
f"{_esc(json.dumps(s.payload, default=str)) if s.payload else 'NULL'}, "
f"{_esc(json.dumps(s.tags, default=str)) if s.tags else 'NULL'}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Escape JSON backslashes before parsing payloads

When the SQL fallback is used and a payload/tag string contains JSON escapes (\n, \t, \\, \uXXXX, Windows paths, regexes), _esc(json.dumps(...)) only doubles quotes but leaves backslashes inside a Snowflake single-quoted literal. Snowflake treats backslashes in such literals as escape sequences (docs), so PARSE_JSON sees different or invalid JSON (for example, an actual newline inside a JSON string) and the flush can fail or corrupt payloads; escape backslashes or use dollar-quoted/parameterized literals before parsing.

Useful? React with 👍 / 👎.

@vigneshnarayanaswamy vigneshnarayanaswamy merged commit 55d8300 into main Jul 9, 2026
9 checks passed
vigneshnarayanaswamy added a commit that referenced this pull request Jul 10, 2026
…35)

Blind post-merge review of #33/#34 found the composition bug: Snowflake
processes backslash escape sequences inside single-quoted constants, and
_esc only doubled single quotes — so any JSON payload containing an
embedded double quote (serialized by json.dumps as \") or a backslash
reached PARSE_JSON mangled. On the SQL fallback path (which #34 routes
all non-native-transport deployments onto) that meant: INSERT fails,
buffer never clears, every subsequent flush-before-read 500s — the
poisoned-buffer incident, reintroduced on common data. Verified live:
PARSE_JSON('{"a": "x \" y"}') errors; the doubled form round-trips.

Also from the review: privilege denials (the expected steady state of
least-privilege roles) short-circuit quietly again instead of warning +
issuing a doomed DROP per flush; unexpected failures log with exc_info;
the failure-path cleanup DROP is gone (temp tables die with the session,
and it could target a same-named permanent table); row construction sits
inside the try; the null-payload regression test inspected the wrong
side of FROM and could never fail — fixed; snapshot-path fallback and
quote/backslash round-trip tests added. Version 0.7.12.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant