Skip to content

fix(plugin-clickhouse): show the result grid whenever the server returns rows - #1896

Merged
datlechin merged 1 commit into
mainfrom
fix/clickhouse-result-grid
Jul 16, 2026
Merged

fix(plugin-clickhouse): show the result grid whenever the server returns rows#1896
datlechin merged 1 commit into
mainfrom
fix/clickhouse-result-grid

Conversation

@datlechin

Copy link
Copy Markdown
Member

Fixes #1886.

Root cause

The ClickHouse driver guessed whether a query returns data by taking the first token of the SQL, split on a literal space character. SELECT on its own line yields the token SELECT\n, and a leading -- or /* */ comment yields --, so both misclassified a real SELECT. The misclassified path discarded the HTTP response body without reading it and returned empty columns, which the app renders as "Query executed successfully" with no grid. The same guess also gated the streaming export path, so exports of comment-prefixed queries wrote empty files.

This is the bug class the ClickHouse JDBC maintainers fixed in clickhouse-java#2784: client-side statement classification must never make server-returned rows disappear.

Fix

Stop classifying the query text. Every request now pins the output format out of band and the response decides what to show:

  • default_format=TabSeparatedWithNamesAndTypes and wait_end_of_query=1 go on the URL, never appended to the SQL. Appending FORMAT X to the SQL text was also independently broken: a trailing -- comment swallowed it silently and a user-written FORMAT clause produced a double-FORMAT syntax error. Verified against a live ClickHouse 26.7 server.
  • Body in the pinned format: parse as TSV. Zero rows still carry the two header lines, so an empty result shows a grid with real columns instead of a success message.
  • Empty body: no result set. Affected rows now come from the X-ClickHouse-Summary header's written_rows, so INSERT stops reporting 0 rows affected.
  • Body in a different format (the user wrote their own FORMAT clause, detected via the X-ClickHouse-Format response header): the raw output is shown in a single column instead of being dropped.
  • http_write_exception_in_output_format=0 is sent only to servers on 23.8 or later, gated through ClickHouseCapabilities, because older servers reject unknown settings.
  • The streaming export request uses default_format=JSONEachRow instead of string concatenation, closing the same hole there.

The response classification and TSV parsing moved into TableProPluginKit as ClickHouseResponseClassifier so the shipped code is unit-testable. ClickHouseConnectionTests now tests that shipped code instead of a private copy of the unescape function.

ABI

scripts/check-pluginkit-abi.sh main reports an additive-only diff: one new public type, nothing removed or changed. No PluginKit version bump. ClickHouse is a bundled plugin, so this ships with the next app release.

Testing

  • 33 unit tests across ClickHouseResponseClassifierTests (new), ClickHouseCapabilitiesTests (new), and ClickHouseConnectionTests; xcodebuild test passes.
  • Test shapes taken from real bug reports in other clients: leading comment, SELECT on its own line, zero-row result vs no result set, user FORMAT clause, malformed and oversized bodies, row-cap truncation.
  • swiftlint lint --strict clean on changed files.

Follow-up filed separately: #1895 (statement scanner turns a trailing comment after the last semicolon into a phantom statement).

@datlechin datlechin added the abi-additive PluginKit ABI diff reviewed as additive; no version bump needed label Jul 16, 2026
@mintlify

mintlify Bot commented Jul 16, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
TablePro 🟢 Ready View Preview Jul 16, 2026, 6:09 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@datlechin
datlechin merged commit e1fcbb2 into main Jul 16, 2026
3 checks passed
@mintlify

mintlify Bot commented Jul 16, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
TablePro 🟡 Building Jul 16, 2026, 6:08 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@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: 886b7dedef

ℹ️ 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".

var isTruncated = false
for index in 2..<lines.count {
let line = lines[index]
if line.isEmpty { continue }

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 Preserve empty single-column TSV rows

When ClickHouse returns a one-column row whose value is the empty string, TabSeparatedWithNamesAndTypes represents that data row as an empty line, e.g. s\nString\n\n. This check skips every empty line, so queries such as SELECT '' AS s (including the comment-prefixed SELECTs this patch is meant to recover) are shown as zero rows even though the server returned a row. Only the final line separator should be discarded; an empty data line can be a real row.

Useful? React with 👍 / 👎.

@datlechin
datlechin deleted the fix/clickhouse-result-grid branch July 17, 2026 05:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

abi-additive PluginKit ABI diff reviewed as additive; no version bump needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: 执行SQL查询Clickshoue数据表,仅显示查询成功,但没有显示结果

1 participant