docs: broaden the SQL API truncated post-processing warning beyond ORDER BY - #11467
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
Claude finished @igorlukanin's task in 2m 35s —— View job Docs accuracy review — the core correction is right; 2 medium issues in the new workaround text (2 medium, 1 nit)Full review
What holds upThe central premise of the PR is correct. The cap is applied in The All three new anchors resolve — The Issues (inline)
Docs-only change; no code, tests, security, or performance surface. No prior review threads to resolve. |
|
Claude finished @igorlukanin's task in 1m 51s —— View job Follow-up review — the two medium issues are addressed; 1 new medium on the reworded
|
| Severity | Issue |
|---|---|
| Medium | None doesn't render as null — limit has skip_serializing_if = "Option::is_none", so the key is absent from the printed JSON. A reader looking for "limit": null finds nothing and concludes the recipe doesn't apply. Same failure mode as the previous wording, one step downstream. Suggestion posted inline; it also fixes "prints the request it sends" (fmt_as prints the unclamped self.request; execute sends a clamped clone). |
Everything else in the workaround list holds: CUBESQL_NON_STREAMING_QUERY_MAX_ROW_LIMIT defaulting to and being clamped by CUBEJS_DB_QUERY_LIMIT is exactly config/mod.rs:157-170, the SortExec caveat on the explicit-LIMIT workaround is correct, and the doubled blank line is gone. All six link references resolve to existing ## anchors.
Docs-only; no code, test, security, or performance surface.
|
Claude finished @igorlukanin's task in 2m 38s —— View job Follow-up review — the
|
| Severity | Issue |
|---|---|
| Medium | The parenthetical says a plan printing CubeScanExecutionPlan, SQL: means "there is no post-processing to worry about". Pushdown isn't all-or-nothing at the scan: evaluate_wrapped_sql recurses and generates SQL for a CubeScanWrapperNode at any depth (query_engine.rs:326-360), so unwrappable operators remain above it — and set_max_limit_for_node stamps the cap onto WrappedSelectNode as well (wrapper.rs:936-941), so the printed SQL carries the LIMIT and the truncation is identical. A reader with a SortExec over a SQL: scan is told they're safe when they're in exactly this case. Secondary: the recipe gives no signal to check on the SQL: branch; the LIMIT in the printed SQL is it. That parenthetical came from my suggestion last round — the correction is on me, not a regression you introduced. |
Everything else still holds
- Broadening the trigger past
ORDER BYmatchesset_max_limit_for_node/execute, neither of which knows which operation was left behind. CUBESQL_NON_STREAMING_QUERY_MAX_ROW_LIMITdefaulting to and being clamped byCUBEJS_DB_QUERY_LIMIT(config/mod.rs:157-170).- The stream-mode rule on both pages matches
scan.rs:528-531, andset_max_limit_for_nodereturns early under stream mode, so "streamed queries aren't capped" is right on the wrapper path too. - The
SortExec-between caveat on the explicit-LIMITworkaround, and the note that it doesn't stack with stream mode. - All six link references resolve to existing
##anchors; the doubled blank line is gone.
Docs-only; no code, test, security, or performance surface. Four prior threads all resolved — nothing re-affirmed.
|
Claude finished @igorlukanin's task in 2m 22s —— View job Follow-up review —
|
| Claim | Code |
|---|---|
| Cap is applied without regard to which operation was left behind | set_max_limit_for_node (wrapper.rs:906-949) and the clamp in execute (scan.rs:533-537) both operate on the node/request, not the post-processing shape |
Plan prints Request:<json> or SQL:<sql>; missing limit key is the Request: signal |
fmt_as (scan.rs:605-620); limit is skip_serializing_if = "Option::is_none" |
CUBESQL_NON_STREAMING_QUERY_MAX_ROW_LIMIT defaults to CUBEJS_DB_QUERY_LIMIT (50,000) and can't exceed it |
config/mod.rs:157-170, with a startup warning on the clamp |
| Streamed queries aren't capped | set_max_limit_for_node returns early under stream mode; normalizeQuery leaves limit untouched for persistent queries (query.js:444-455), and gateway.stream sets persistent: true (gateway.ts:1966-1990) |
Stream mode engages only on limit None or > cap, so bullets 1 and 3 don't stack |
scan.rs:528-532 |
SortExec between GlobalLimitExec and the scan means the limit bounds output, not what the sort reads |
matches the example plan; consistent with limit pushdown only being valid directly above the scan |
Anchors: #cubejs_db_query_limit, #cubesql_stream_mode, #cubesql_non_streaming_query_max_row_limit all exist as ## headings in environment-variables.mdx (lines 1078, 1517, 1545); #row-limit exists in queries.mdx:32. The dropped CUBEJS_DB_QUERY_DEFAULT_LIMIT reference is no longer linked, so no dangling ref.
Five prior threads, all resolved — none re-affirmed, no new inline comments. Docs-only; no code, test, security, or performance surface. Reads as ready to merge.
• branch igor/core-722-document-sql-api-fallback-limitations-over-50k-rows •
|
Claude finished @igorlukanin's task in 1m 21s —— View job Follow-up review —
|
| Severity | Issue |
|---|---|
| Nit | "a LIMIT that reaches the scan turns streaming back off" doesn't hold for a limit above the cap — arm 2 keeps streaming on. The correct rule is stated one clause earlier, so this is a summary slightly overshooting it; and a limit above the cap isn't a limit anyone would add pursuing workaround 1. Non-blocking. |
Everything else still holds
Re-verified nothing in this commit disturbed the earlier findings: the broadened trigger, the missing-limit-key signal on the Request: branch, the printed LIMIT on the SQL: branch, partial pushdown, CUBESQL_NON_STREAMING_QUERY_MAX_ROW_LIMIT defaulting to and clamped by CUBEJS_DB_QUERY_LIMIT, and the SortExec-between caveat. All six link references still resolve to existing ## anchors.
Docs-only; no code, test, security, or performance surface. Five prior threads, all resolved — none re-affirmed. Ready to merge with or without the nit.
• branch igor/core-722-document-sql-api-fallback-limitations-over-50k-rows •
|
Claude finished @igorlukanin's task in 58s —— View job Follow-up review —
|
| Claim | Code |
|---|---|
| Cap applies regardless of which operation was left to post-processing | set_max_limit_for_node (wrapper.rs:906-949) and the clamp in execute (scan.rs:533-537) both act on the node/request, not the post-processing shape |
Missing limit key is the signal on the Request: branch |
fmt_as prints self.request; limit is skip_serializing_if = "Option::is_none" |
Printed LIMIT is the signal on the SQL: branch, and pushdown can be partial |
evaluate_wrapped_sql recurses; set_max_limit_for_node has a WrappedSelectNode branch |
CUBESQL_NON_STREAMING_QUERY_MAX_ROW_LIMIT defaults to CUBEJS_DB_QUERY_LIMIT (50,000) and is clamped to it with a startup warning |
config/mod.rs:157-170 — confirmed again on this checkout |
| Streamed queries aren't capped | set_max_limit_for_node returns early under stream mode; normalizeQuery leaves limit untouched for persistent queries |
SortExec between GlobalLimitExec and the scan means the limit bounds output, not the sort's input |
matches the example plan |
Anchors: #cubejs_db_query_limit (1078), #cubesql_stream_mode (1517), #cubesql_non_streaming_query_max_row_limit (1545) all exist as ## headings; #row-limit still resolves in queries.mdx. No dangling refs after dropping CUBEJS_DB_QUERY_DEFAULT_LIMIT.
Six prior threads, all resolved — none re-affirmed, no new inline comments. Docs-only; no code, test, security, or performance surface. Ready to merge.
• branch igor/core-722-document-sql-api-fallback-limitations-over-50k-rows •
The SQL API's row-limit warning is scoped to
ORDER BY, but that isn't the actual trigger.Any operation left to post-processing over a regular query that isn't bounded by a small
enough limit reads at most
CUBEJS_DB_QUERY_LIMITrows and computes over just those, sothe result can be wrong with no error raised. Sorting is only one way to get there. As
written, the docs tell someone chasing a wrong result from a different query shape that
their situation is impossible.
What changed:
ORDER BYcan't be pushed down" to any post-processing overan unbounded regular query, and kept the "rarely comes up" framing without resting it on
the
ORDER BY-only premise.EXPLAIN, which works for any query shape, rather than addinga second worked example whose plan output isn't captured here.
LIMITonlyhelps when it reaches the scan (a surviving
SortExecmeans it doesn't);CUBESQL_NON_STREAMING_QUERY_MAX_ROW_LIMITdefaults toCUBEJS_DB_QUERY_LIMITand capsnon-streaming queries separately; streamed queries aren't capped, so nothing is truncated.
thr->thetypo in the sentence above the first example.Docs only.
mintlify broken-links --check-anchorspasses and the page was checked in thelocal preview.