Skip to content

fix: support LIMIT 0 and improve error messages for NULL/negative LIMIT/OFFSET - #24455

Merged
mergify[bot] merged 10 commits into
matrixorigin:mainfrom
ULookup:fix/issue-23103-limit-offset
May 20, 2026
Merged

fix: support LIMIT 0 and improve error messages for NULL/negative LIMIT/OFFSET#24455
mergify[bot] merged 10 commits into
matrixorigin:mainfrom
ULookup:fix/issue-23103-limit-offset

Conversation

@ULookup

@ULookup ULookup commented May 19, 2026

Copy link
Copy Markdown
Collaborator

What type of PR is this?

  • API-change
  • BUG
  • Improvement
  • Documentation
  • Feature
  • Test and CI
  • Code Refactoring

Which issue(s) this PR fixes:

issue #23103

What this PR does / why we need it:

Fix three problems with LIMIT/OFFSET value handling:

  1. LIMIT 0 was rejectedSELECT * FROM t LIMIT 0 failed with "only uint64 support in limit/offset clause", but 0 is a valid uint64 and should return 0 rows.
  2. NULL values had unclear errorsLIMIT NULL and OFFSET NULL produced the same generic "only uint64 support" message instead of explaining that NULL is not allowed.
  3. Negative values had unclear errorsLIMIT -1 and OFFSET -5 also fell through to the generic uint64 message, instead of telling the user the value must be non-negative.
    ### Changes
  • pkg/sql/plan/limit_binder.go — Added isOffset field to LimitBinder to distinguish LIMIT from OFFSET in error messages. Added early interception of UNARY_MINUS + NumVal (parser does
    not fold this into a negative literal). Added explicit NULL check. All error messages are now clause-specific.
  • pkg/sql/plan/query_builder.go — Updated 5 call sites in bindSelectClause, bindLimit, buildUnion, bindRecursiveCte, and bindSelectClause to pass isOffset and use separate binder
    instances for offset vs count.
  • pkg/sql/plan/types.go — Added isOffset bool field to LimitBinder struct.
  • pkg/sql/plan/limit_binder_test.go — 10 new tests covering: LIMIT 0, positive limits, OFFSET 0, negative LIMIT/OFFSET, NULL LIMIT/OFFSET, string coercion, large uint64, and star rejection.

Behavior changes

Input Before After
LIMIT 0 Error: "only uint64 support..." Returns 0 rows
LIMIT NULL Error: "only uint64 support..." Error: "LIMIT cannot be NULL"
OFFSET NULL Error: "only uint64 support..." Error: "OFFSET cannot be NULL"
LIMIT -1 Error: "only uint64 support..." Error: "LIMIT must be a non-negative integer"
OFFSET -5 Error: "offset value must be nonnegative" Error: "OFFSET must be a non-negative integer"

ULookup added 3 commits May 18, 2026 22:23
- Add isOffset field to LimitBinder to distinguish LIMIT from OFFSET
- Reject NULL with clear "LIMIT/OFFSET cannot be NULL" message
- Use clause-specific error messages for negative values
- Update all NewLimitBinder call sites with isOffset parameter
Cover LIMIT 0, LIMIT -1, LIMIT NULL, OFFSET -5, OFFSET NULL,
string LIMIT, large uint64 LIMIT, and star-in-limit cases.
The NULL check now uses isOffset to output "LIMIT cannot be NULL" or
"OFFSET cannot be NULL", consistent with other error paths in the binder.
Also adds nil guard for Expr_Lit.Lit.
@ULookup
ULookup requested review from aunjgr and ouyuanning as code owners May 19, 2026 05:41
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@CLAassistant

CLAassistant commented May 19, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@mergify mergify Bot added the kind/bug Something isn't working label May 19, 2026
@ULookup ULookup changed the title Fix/issue 23103 limit offset fix: support LIMIT 0 and improve error messages for NULL/negative LIMIT/OFFSET May 19, 2026
@mergify

mergify Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

Merge Queue Status

  • Entered queue2026-05-20 09:58 UTC · Rule: main
  • Checks passed · in-place
  • Merged2026-05-20 12:01 UTC · at 491dda20fe6b8c6fb1538303e54a88243d524201 · squash

This pull request spent 2 hours 3 minutes 7 seconds in the queue, including 1 hour 1 minute 59 seconds running CI.

Required conditions to merge
  • #approved-reviews-by >= 1 [🛡 GitHub branch protection]
  • #changes-requested-reviews-by = 0 [🛡 GitHub branch protection]
  • #review-threads-unresolved = 0 [🛡 GitHub branch protection]
  • github-review-decision = APPROVED [🛡 GitHub branch protection]
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
    • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
    • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(PESSIMISTIC)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
    • check-neutral = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
    • check-skipped = Matrixone Standlone CI / Multi-CN e2e BVT Test on Linux/x64(LAUNCH, PROXY)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
    • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
    • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH, PESSIMISTIC)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone CI / SCA Test on Ubuntu/x86
    • check-neutral = Matrixone CI / SCA Test on Ubuntu/x86
    • check-skipped = Matrixone CI / SCA Test on Ubuntu/x86
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone CI / UT Test on Ubuntu/x86
    • check-neutral = Matrixone CI / UT Test on Ubuntu/x86
    • check-skipped = Matrixone CI / UT Test on Ubuntu/x86
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
    • check-neutral = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
    • check-skipped = Matrixone Compose CI / multi cn e2e bvt test docker compose(Optimistic/PUSH)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
    • check-neutral = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
    • check-skipped = Matrixone Standlone CI / e2e BVT Test on Linux/x64(LAUNCH,Optimistic)
  • any of [🛡 GitHub branch protection]:
    • check-success = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
    • check-neutral = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
    • check-skipped = Matrixone Upgrade CI / Compatibility Test With Target on Linux/x64(LAUNCH)
  • any of [🛡 GitHub branch protection]:
    • check-skipped = Matrixone Utils CI / Coverage
    • check-neutral = Matrixone Utils CI / Coverage
    • check-success = Matrixone Utils CI / Coverage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/bug Something isn't working size/M Denotes a PR that changes [100,499] lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Limitation: LIMIT/OFFSET only supports uint64, NULL and negative numbers not supported

5 participants