Skip to content

Document SQL LIKE semantics: wildcards, ESCAPE, case per engine, cost - #786

Closed
kriszyp wants to merge 9 commits into
mainfrom
docs/sql-like-semantics
Closed

kriszyp wants to merge 9 commits into
mainfrom
docs/sql-like-semantics

Conversation

@kriszyp

@kriszyp kriszyp commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

⊙ Problem

The SQL reference describes LIKE only as "Searches for a pattern". harper#3936 makes ESCAPE work and stops matching from backtracking in v5.4. No page says what a pattern means. Also undocumented: the new engine matches case-sensitively and the legacy engine does not. Under the default sql.engine: auto, the same LIKE can match different rows depending on indexes.

🤔 Is the requirement right?

Yes. The brief asks for the v5.4 matching rules. The case split is the part most likely to change which rows an UPDATE or DELETE touches, so it gets the most space.

💡 Solution

🤔 Define sql.engine and sql.allowFullScan on the SQL page?

Yes, in two short paragraphs, because LIKE depends on them and no page defines them. A full sql entry in the configuration options page also needs maxSortRows and maxHashRows, which I did not check. It is tracked in #785.

⚖️ Alternatives

  • Rewrite only the operators-table row: a table cell can't hold the per-engine case rules or the cost and full-scan rules.
  • Make both engines match case the same way, in harper: harper#3936 keeps the split on purpose. These docs describe what ships.

🔧 Changes

✅ Verification

  • Checked against harper#3936 (48d0e92) DESIGN.md, sqlEngine/expressions/like.ts, sqlTranslator/alasqlLike.ts, and integration/unit tests, plus a scratch Harper build under auto, new, new with allowFullScan, and legacy.
  • Checked the "before v5.4.0" claims against harper@5.4.0-alpha.2. On the new engine, ESCAPE was ignored, * acted as a quantifier, and % and _ skipped line breaks. On the legacy engine, _ skipped line breaks and 'a\d' matched a5.
  • npm run build passes, including links and anchors. So do format:check, lint, typecheck and test:examples.
Selected results (PR head, sql.engine: auto unless noted)
Query Result
ip LIKE 't0!%' ESCAPE '!' t0% only
ip LIKE 't0%' (indexed, new engine) t0%, t0!z, t0a; not T0b
note LIKE 't0%' (unindexed, falls back) also T0b
note LIKE 't0%' ORDER BY id new engine, not T0b
ip LIKE '%T0B' falls back, matches T0b
DELETE ... WHERE ip LIKE 't0%' deletes 3, keeps T0b
note LIKE 'a_b' matches a\nb and a\rb on both engines
note LIKE '[z-a]%' 400 (legacy)
ESCAPE '!!', ESCAPE '', ESCAPE 1, trailing escape 400 on all engines
Segment > 10,000 characters between % wildcards 400 on all engines
Legacy > 64 _ pattern naming every noncharacter and PUA pair 400 (legacy)
note LIKE '%_%_%_%_%_%_%_%_%_%_%_%_%_%_Z' on a 100 KB value about 40 ms per request
sql.engine: new, note LIKE 't0%' 400, no usable index condition

🤔 Merge after harper#3936?

Yes. harper#3936 merged to main (ef427ad), and the v5.4.0-beta.1 tag includes it, but that release is not published yet, so the v5.4.0 badges match the next release.

Refs HarperFast/harper#3936

🤖 Generated by Gemini (gemini-4-argon-high); posted via @kriszyp.

Related PRs: #783 overlaps, #788 overlaps
Complexity: medium

Deferred findings

  • 58823b88daf1f164 minor documentation — reference/operations-api/sql.md — No sql.engine/allowFullScan/HARPER_SQL_ENGINE entries in configuration docs that the fallback contract links to — NOT FILED
  • 6960e19497514b0b minor documentation — reference/operations-api/sql.md — 'no rows are changed' unverified for expression patterns checked per row in UPDATE/DELETE — NOT FILED
  • 1fb37cf7647bc110 minor documentation — reference/configuration/options.md — No sql section in configuration options for sql.engine / allowFullScan / HARPER_SQL_ENGINE — filed Document the sql configuration block (engine, allowFullScan, maxSortRows, maxHashRows) in configuration options #785
  • d2d3f81fc83e88c1 minor documentation — release-notes/v5-lincoln/5.4.md — harper#3936 release status unverified; SQL entry lacks 'not released yet' line unlike sibling sections — NOT FILED
  • 426309ddbbac72bd nit documentation — reference/operations-api/sql.md — Open PR Assemble the v5 reference and open release notes from harper and harper-pro #788 also edits sql.md; the merge order can restore 'results don't change' — NOT FILED
Origin — the dispatch brief this PR was written from

Document SQL LIKE wildcards, ESCAPE, and case sensitivity (harper#3936)

Document SQL LIKE semantics in the operations-API SQL reference (reference/operations-api/sql.md, which today lists LIKE only as "Searches for a pattern"), following HarperFast/harper PR HarperFast/harper#3936 (milestone v5.4).

What to document, as user-facing behavior:

  • Wildcards: % matches any run of characters, including line breaks; _ matches exactly one character other than a line break (\n, \r, U+2028, U+2029).
  • LIKE pattern ESCAPE 'c': the escape character makes the next character literal (for example ip LIKE 't0!%' ESCAPE '!' matches exactly t0%). The escape must be exactly one character. A pattern ending in the escape character, an empty or multi-character ESCAPE, and a non-string ESCAPE are rejected with a 400. ESCAPE works in SELECT, UPDATE and DELETE.
  • Case sensitivity: with sql.engine: new (and statements auto serves with the new engine) LIKE is case-sensitive; the legacy engine (sql.engine: legacy, and auto fallbacks) is case-insensitive. Say this plainly; a user running auto can see either.
  • Legacy-only extension: [abc], [a-z] and [^abc] character classes; a reversed range such as [z-a] is a 400. Characters such as *, \, ^, $ are literals in patterns on both engines.
  • Matching cost is linear in the value length for a given pattern (no pathological patterns), so a long pattern on a large table costs time proportional to data scanned; a LIKE with no other indexed condition may require sql.allowFullScan or fall back to the legacy engine under auto (link the existing sql.engine docs if present).

Version note: these are v5.4 behaviors; earlier versions ignored ESCAPE in the new engine and treated * as a wildcard-like regex quantifier there.

Dispatch: task docs-harper-3936 · queued by task:harper-sql-like-linear-matcher-escape · ran by claude/opus/xhigh · worker kzyp-xps-1

Review-Coverage: authored=claude; ran=gemini,cursor-composer,codex; adjudicated=domain; declined=cursor-grok,muse; rounds=11; full=2 @ b85698e

Review-Attention: skim ~2m (decisions: engine-dependent-like-case-documented, legacy-64-underscore-rejection-documented, historical-exception-granularity) @ b85698e

@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 and release notes to detail the new SQL engine's behavior, specifically regarding case sensitivity, the new ESCAPE clause in LIKE pattern matching, and performance improvements that prevent backtracking. The review feedback suggests minor documentation improvements, such as avoiding the VersionBadge component mid-sentence inside tables, restructuring a section to place a list of rejected patterns immediately after its introductory sentence, and separating performance limitations from recommendations into distinct sentences for better readability.

Comment thread reference/operations-api/sql.md Resolved
Comment thread reference/operations-api/sql.md Resolved
Comment thread reference/operations-api/sql.md Resolved
@github-actions
github-actions Bot temporarily deployed to pr-786 November 2, 2026 22:18 Inactive
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

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

This preview will update automatically when you push new commits.

@github-actions
github-actions Bot temporarily deployed to pr-786 November 2, 2026 22:24 Inactive
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

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

This preview will update automatically when you push new commits.

@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

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

This preview will update automatically when you push new commits.

@kriszyp
kriszyp force-pushed the docs/sql-like-semantics branch from e2509bd to 0fc2fb7 Compare November 4, 2026 16:00
@github-actions
github-actions Bot temporarily deployed to pr-786 November 4, 2026 16:04 Inactive
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

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

This preview will update automatically when you push new commits.

kriszyp and others added 9 commits November 4, 2026 18:44
Adds a LIKE Pattern Matching section to the operations-API SQL reference
for harper#3936 (v5.4): % and _ semantics, ESCAPE and its 400s, case
sensitivity per engine and how auto can serve either, legacy-only
character classes, and the per-value linear matching bound. Defines
sql.engine and sql.allowFullScan in the fallback contract, lists LIKE
among the engine behavior differences, and adds a 5.4 release note.

Refs HarperFast/harper#3936

Dispatch-Task: docs-harper-3936
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Name what keeps an unindexed LIKE on the new engine under auto: an
  indexed AND condition, ORDER BY on the primary key, allowFullScan.
- Say the legacy engine checks a pattern when it tests a row.
- Drop the claim that no pattern is expensive; both lengths multiply.
- Scope the full-scan fallback list to auto with allowFullScan off, and
  note that pairing a suffix LIKE with an indexed condition makes it
  case-sensitive.

Dispatch-Task: docs-harper-3936
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Point the scan-routing sentences at the fallback contract rather than
enumerating which statements fall back, scan on the new engine, or get a
400, and scope eager pattern checks to statements the new engine plans.

Dispatch-Task: docs-harper-3936
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dispatch-Task: docs-harper-3936
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…length advice

Dispatch-Task: docs-harper-3936
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Document that _ matches any one character including line breaks on both SQL engines in v5.4.0.
- Document the 10,000-character LIKE segment limit and its 400 error shape on both engines.
- Document the legacy-engine 400 error when a pattern with more than 64 _ wildcards uses a character from every reserved noncharacter and Private Use Area pair.
- Clarify escaped [ on the legacy engine and literal pattern checking under auto.

Dispatch-Task: documentation-786-like-rules-update
Co-Authored-By: Gemini <noreply@google.com>
Dispatch-Task: documentation-786-like-rules-update
Dispatch-Task: pr-maint-53d171c3888f7402736f60bbd9a4d118
Co-Authored-By: Gemini <noreply@google.com>
…PE, and literal characters

- A literal prefix followed by one trailing % was already matched as a prefix
  before 5.4, so `%` and `*` did not change for it.
- A non-literal ESCAPE is unsupported on the new engine and falls back under auto.
- Only `*`, `\`, `^` and `$` changed meaning; `.`, `?` and `+` were already literal.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Dispatch-Task: pr-maint-53d171c3888f7402736f60bbd9a4d118
…rved

A prefix pattern evaluated as a residual filter used the regular-expression
matcher before 5.4, so its matches did change.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Dispatch-Task: pr-maint-53d171c3888f7402736f60bbd9a4d118
@kriszyp
kriszyp force-pushed the docs/sql-like-semantics branch from 0fc2fb7 to b85698e Compare November 5, 2026 01:55
@github-actions
github-actions Bot temporarily deployed to pr-786 November 5, 2026 01:58 Inactive
@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

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

This preview will update automatically when you push new commits.

@kriszyp

kriszyp commented Nov 5, 2026

Copy link
Copy Markdown
Member Author

Moved to harper#4037: the v5 reference and 5.4 release notes now live in harper's docs/ (documentation#788).

— Claude Opus 5.5

@kriszyp kriszyp closed this Nov 5, 2026
@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown

🧹 Preview Cleanup

The preview deployment for this PR has been removed.

kriszyp added a commit to HarperFast/harper that referenced this pull request Nov 5, 2026
…ocumentation) (#4037)

* docs: SQL LIKE semantics and tracked update() writes, from HarperFast/documentation

Ports the open HarperFast/documentation#786 (SQL LIKE: wildcards, ESCAPE, case per engine,
cost) and HarperFast/documentation#760 (what a tracked update() record writes, addTo
composition) now that the v5 reference lives here. Their 5.4 notes become fragments in new
SQL and Resource API sections.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: the Int range check still applies to a BigInt addTo delta

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch was previously deployed

1 inactive deployment
pr-786 — b85698ec Deployed Nov 5, 2026 by github-actions[bot]
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