Skip to content

fix(plugin-snowflake): take the affected row count from the statement type, not a column name - #2469

Merged
datlechin merged 1 commit into
fix/snowflake-temporal-decodingfrom
fix/snowflake-affected-rows
Aug 26, 2026
Merged

fix(plugin-snowflake): take the affected row count from the statement type, not a column name#2469
datlechin merged 1 commit into
fix/snowflake-temporal-decodingfrom
fix/snowflake-affected-rows

Conversation

@datlechin

Copy link
Copy Markdown
Member

Stacked on the Snowflake decoding work. Base is fix/snowflake-temporal-decoding, which carries #2466's commit plus the merged #2467 and #2468. Retarget to main when that branch lands.

Found while investigating #2454.

The defect

extractAffectedRows decided what a result meant by reading its column names:

guard columns.count == 1,
      columns[0].name.lowercased().contains("number of rows"),

It is wrong in both directions.

It misses real counts. An UPDATE returns two columns, number of rows updated and number of multi-joined rows updated, and a multi-clause MERGE returns one per clause. columns.count == 1 rejects them, so a save that changed rows reported none: the completion message dropped the count and query history recorded 0.

It invents counts that never happened. SELECT COUNT(*) AS "number of rows" FROM orders is one column with that name holding 1523, so a plain read was reported as having changed 1523 rows.

The fix

The server already says what the statement was. The response carries statementTypeId, which the driver never read, so the count now comes from that and the sum of the count row:

static func isDML(_ identifier: Int) -> Bool {
    (dml ... multiTableInsert).contains(identifier)
}

The range and the summing both follow the official Go driver, which gates on isDml(data.Data.StatementTypeID) and whose updateRows sums every column of the first row rather than reading one:

  • statementTypeIDSelect = 0x1000
  • statementTypeIDDml = 0x3000
  • statementTypeIDMultiTableInsert = statementTypeIDDml + 0x500
  • statementTypeIDMultistatement = 0xA000

A SELECT is no longer DML whatever its columns are called, and a DML statement reports the sum of its counts however many it has.

This is the same rule the ClickHouse driver already follows: classify a result from the server's answer, never from its shape.

Tests

SnowflakeStatementTypeTests, 5 cases: the DML range and its boundaries at 0x2FFF and 0x3501, a single count, an UPDATE and a three-clause MERGE summed, a SELECT holding 1523 in a column named number of rows reporting nothing, and an unreadable or missing count reporting nothing rather than a guess.

Verified: build PASS, 43/43 across this and the neighbouring Snowflake suites, SwiftLint 0 violations.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@datlechin
datlechin merged commit e2eb1a4 into fix/snowflake-temporal-decoding Aug 26, 2026
@datlechin
datlechin deleted the fix/snowflake-affected-rows branch August 26, 2026 16:42
datlechin added a commit that referenced this pull request Aug 26, 2026
…dpoint sends (#2466)

* fix(plugin-snowflake): decode the wire encodings the query-request endpoint sends

Claude-Session: https://claude.ai/code/session_01Qk1xfY3vnneRifC22eV2r7

* fix(plugin-snowflake): give every statement builder one SQL escaper (#2467)

Claude-Session: https://claude.ai/code/session_01Qk1xfY3vnneRifC22eV2r7

* fix(plugin-snowflake): keep a timestamp offset the date parser cannot represent as text (#2468)

Claude-Session: https://claude.ai/code/session_01Qk1xfY3vnneRifC22eV2r7

* fix(plugin-snowflake): take the affected row count from the statement type, not a column name (#2469)

Claude-Session: https://claude.ai/code/session_01Qk1xfY3vnneRifC22eV2r7

* fix(plugin-snowflake): key the shared session on the saved connection and scope Stop to its own driver (#2470)

Claude-Session: https://claude.ai/code/session_01Qk1xfY3vnneRifC22eV2r7

---------

Co-authored-by: Ngo Quoc Dat <datlechin@gmail.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