Skip to content

feat: Implement NTILE window function#23760

Merged
mergify[bot] merged 8 commits intomatrixorigin:mainfrom
ck89119:feat/win_ntile
Feb 26, 2026
Merged

feat: Implement NTILE window function#23760
mergify[bot] merged 8 commits intomatrixorigin:mainfrom
ck89119:feat/win_ntile

Conversation

@ck89119
Copy link
Contributor

@ck89119 ck89119 commented Feb 25, 2026

What type of PR is this?

  • Feature

Which issue(s) this PR fixes:

#23017

What this PR does / why we need it:

This PR implements the MySQL NTILE window function, which divides an ordered partition into a specified number of approximately equal groups (buckets) and returns the bucket number for each row.

Implementation Details

NTILE Function Behavior:

  • Syntax: NTILE(N) OVER (PARTITION BY ... ORDER BY ...)
  • Divides rows into N buckets numbered from 1 to N
  • When rows don't divide evenly, extra rows are distributed to the first buckets
  • Example: 10 rows with NTILE(3) → buckets of size 4, 3, 3

Changes:

  1. Parser Layer - Added NTILE token and grammar rules
  2. Function Registration - Registered NTILE as a WIN_ORDER window function
  3. Executor Implementation - Implemented ntileWindowExec with bucket distribution algorithm
  4. Window Operator - Added special handling for NTILE to evaluate bucket count parameter
  5. Tests - Added comprehensive unit tests and verified with SQL integration tests

Bug Fix:

  • Fixed ID conflicts in register.go:
    • AggIdOfStdDevSample and AggIdOfBitXor both had ID -25
    • AggIdOfBitmapConstruct and AggIdOfBitmapOr both had ID -29
    • Reassigned IDs to ensure uniqueness

Test Results

Unit Tests:

  • ✅ 10 rows / 3 buckets → [1,1,1,1,2,2,2,3,3,3]
  • ✅ 9 rows / 3 buckets → [1,1,1,2,2,2,3,3,3]
  • ✅ 5 rows / 3 buckets → [1,1,2,2,3]

SQL Integration Tests:

  • ✅ Basic usage with ORDER BY
  • ✅ With PARTITION BY
  • ✅ Edge cases (1 bucket, bucket count > row count)
  • ✅ NULL values and duplicate values
  • ✅ Error handling (bucket count <= 0)

Example Usage

-- Divide employees into 3 salary groups
SELECT name, salary, 
       NTILE(3) OVER (ORDER BY salary) as salary_group
FROM employees;

-- Divide into 2 groups within each department
SELECT name, department, salary,
       NTILE(2) OVER (PARTITION BY department ORDER BY salary) as dept_group
FROM employees;

- Implement NTILE window function in pkg/sql/colexec/aggexec/window.go
- Add comprehensive unit tests with 83% coverage in window_test.go
- Add BVT tests in test/distributed/cases/window/
- Support all integer types for bucket count parameter
- Handle uneven distribution correctly
@mergify mergify bot added the queued label Feb 26, 2026
@mergify
Copy link
Contributor

mergify bot commented Feb 26, 2026

Merge Queue Status

Rule: main


  • Entered queue2026-02-26 11:12 UTC
  • Checks passed · in-place
  • Merged2026-02-26 12:07 UTC · at 8b37fe75429a0da078aab8cf58ecb400a6c76ac3

This pull request spent 55 minutes 16 seconds in the queue, including 55 minutes 5 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]
  • branch-protection-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-success = Matrixone Utils CI / Coverage
    • check-neutral = Matrixone Utils CI / Coverage
    • check-skipped = Matrixone Utils CI / Coverage

@mergify mergify bot merged commit 4dc31c8 into matrixorigin:main Feb 26, 2026
23 of 24 checks passed
@mergify mergify bot removed the queued label Feb 26, 2026
@ck89119 ck89119 deleted the feat/win_ntile branch February 26, 2026 12:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/feature size/XXL Denotes a PR that changes 2000+ lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants