Skip to content

docs(sql): 5.2 SQL engine performance guidance#588

Open
kriszyp wants to merge 4 commits into
mainfrom
kris/sql-52-engine-guidance
Open

docs(sql): 5.2 SQL engine performance guidance#588
kriszyp wants to merge 4 commits into
mainfrom
kris/sql-52-engine-guidance

Conversation

@kriszyp

@kriszyp kriszyp commented Jul 15, 2026

Copy link
Copy Markdown
Member

Adds guidance to the SQL operations-api reference for the new Resource-API SQL engine landing in 5.2 (harper #1285 — New SQL engine on the Resource API), per Kris's request to document which SQL is well supported / runs efficiently and what to avoid.

Changes to reference/operations-api/sql.md

  • Replaced the blanket "SQL is not recommended for production" warning with an accurate 5.2 note: the new engine serves index-plannable queries as streaming, bounded-memory operations and transparently falls back to the legacy path for anything it can't plan. REST is still steered as the choice for the hottest production read paths.
  • New ## Query Performance section:
    • Index-served (efficient): PK lookups, equality/IN on indexed attributes, range/BETWEEN, prefix LIKE 'x%', index-order ORDER BY with LIMIT/OFFSET pushdown, GROUP BY on an indexed attribute, INNER/LEFT JOIN on an indexed inner key, projection pushdown.
    • Full-scan fallback (avoid on large tables): un-indexed predicates, cross-attribute OR, suffix/substring LIKE, !=/NOT negations, un-driven ORDER BY, SEARCH_JSON; plus a note that RIGHT/FULL JOIN, no-WHERE UPDATE/DELETE, and COUNT(DISTINCT) run on the legacy engine.
    • The fallback contract: auto default, results never change (only the performance profile), and the sql-engine v2 fallback: log signal.
    • Practical guidance: index what you filter/sort/join on, prefer prefix LIKE, constrain before sort/group/join/SEARCH_JSON, use REST for hot paths.

Accuracy notes

  • Guidance is grounded in the engine's optimizer rules (predicate normalization for LIKE/BETWEEN, sort-from-index, validate-scannable) and the phase-5 cutover parity work in #1285.
  • Reconciled against the existing Features Matrix: UNION, sub-SELECT, and INSERT … SELECT are unsupported by both engines, so they are called out as "not supported" rather than "slow fallback."
  • Verified the RIGHT/FULL JOIN fallback claim against source: normalizer.ts throws EngineUnsupportedError for both, and the router catches exactly that under auto to fall back to legacy (which supports them).

Note: #1285 is still open and targeted at 5.2; the "As of Harper 5.2" framing lines up with that release. If the merge/version slips, the version reference should move with it.

🤖 Generated with Claude Code

Document the new Resource-API SQL engine landing in 5.2 (harper #1285):
which queries run index-served/streaming vs. which fall back to the
legacy full-scan path, and the auto-fallback contract. Replace the blanket
"SQL not recommended" warning with accurate, nuanced guidance.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kriszyp
kriszyp requested a review from a team as a code owner July 15, 2026 19:40

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates the SQL documentation for Harper 5.2, introducing the new SQL engine built on indexed storage and the Resource API. It replaces the previous warning against SQL use in production with an informative block and adds a comprehensive 'Query Performance' section detailing index-served queries, full-scan fallbacks, and practical optimization guidance. There are no review comments, so no further feedback is provided.

@github-actions
github-actions Bot temporarily deployed to pr-588 July 15, 2026 19:43 Inactive
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-588

This preview will update automatically when you push new commits.

@kriszyp
kriszyp removed the request for review from a team July 15, 2026 20:06
…full scan

Table.search executes a top-level OR as a union of per-condition index
searches (resources/search.ts), and the new engine pushes an OR group down
when every branch is index-driving (whereToConditions conditionUsesIndex).
So `a = 1 OR b = 2` with both attributes indexed is index-served; only an
OR with an un-indexed / non-index-comparator branch falls back to a scan.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kriszyp

kriszyp commented Jul 15, 2026

Copy link
Copy Markdown
Member Author

Follow-up commit (14d4523) corrects the OR guidance. An earlier draft said WHERE a = 1 OR b = 2 always forces a full scan — that's wrong. Table.search executes a top-level OR as a union of per-condition index searches (resources/search.ts), and the new engine pushes the disjunction down when every branch is index-driving (conditionUsesIndex in whereToConditions.ts). So an all-indexed OR is index-served; only an OR with an un-indexed (or non-index-comparator, e.g. %x% LIKE) branch falls back to a scan. Doc now reflects that in both the index-served and fallback lists.

@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-588

This preview will update automatically when you push new commits.

@github-actions
github-actions Bot temporarily deployed to pr-588 July 15, 2026 20:16 Inactive
:::warning
SQL querying is not recommended for production use or on large tables. SQL queries often do not utilize indexes and are not optimized for performance. Use the [REST interface](../rest/overview.md) for production data access — it provides a more stable, secure, and performant interface. SQL is intended for ad-hoc data investigation and administrative queries.
:::info Harper 5.2 introduces a new SQL engine
As of Harper 5.2, SQL runs on a new engine built directly on Harper's indexed storage and Resource API. Queries that can be planned against an index now execute as streaming, index-driven operations with memory bounded by the size of the result — not the size of the table. Queries the engine can't plan against an index automatically fall back to the legacy execution path, returning the same results but with the older full-scan cost. See [Query Performance](#query-performance) for how to keep your queries on the fast path.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is cool, how do users get observability into the ability to plan?


## Query Performance

Harper 5.2's SQL engine maps SQL clauses onto Harper's native indexed storage. When a query can be planned against an index, it runs as a streaming, index-driven operation with memory bounded by the size of the result — not the size of the table. When it can't, the engine falls back to the legacy path, which fetches candidate rows and evaluates the query in memory, with cost and memory growing with the number of rows scanned.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There should be some form of larger callout here that the fallback incurs full table scans which is problematic for large tables.


These can't be served from an index. They still return correct results, but the engine falls back to the legacy full-scan path, so cost and memory grow with table size:

- **Filters on un-indexed attributes** — any equality, range, or `IN` on an attribute with no index.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What if there is another indexed filter in an AND?


### Practical guidance

- Index every attribute you filter, sort, or join on.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is it worth calling out performance and storage implications of over indexing?

Adds a 'Behavior changes from the legacy engine' subsection covering the
standard-SQL corrections the new engine applies to queries it plans (empty-set
aggregates -> NULL, string MIN/MAX, NULL!=NULL join keys, explicit-null
expression results), and scopes the fallback-contract 'results don't change'
promise to genuine fallbacks. Adds TOTAL to the reserved-word list and notes
that reserved words used as AS aliases must be quoted (e.g. AS `total`).

Sourced from the sql-engine-v2 QA differential wave (findings D-217, F-143).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions
github-actions Bot temporarily deployed to pr-588 July 15, 2026 21:32 Inactive
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-588

This preview will update automatically when you push new commits.

…equirement; OFFSET behavior change

QA verification against the engine (sql-engine-v2 @ 8a46e0302) found three
inaccuracies:
- The fallback log line is 'SQL engine v2 fallback:' (router.ts), not
  'sql-engine v2 fallback:' — the documented grep string matched nothing.
- ORDER BY / GROUP BY on an indexed attribute run on the legacy path unless
  an index-driving WHERE condition is present (validateScannable requires a
  scan driver) — state the requirement instead of promising them
  unconditionally.
- Behavior changes: OFFSET past the end of a result now correctly returns
  no rows (legacy could still return rows).

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

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-588

This preview will update automatically when you push new commits.

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.

2 participants