Skip to content

fix: prevent panic in valueDec128Compare when comparing decimal with integer types#24088

Merged
mergify[bot] merged 2 commits intomatrixorigin:3.0-devfrom
jiangxinmeng1:fix-decimal-compare-panic-24081
Apr 9, 2026
Merged

fix: prevent panic in valueDec128Compare when comparing decimal with integer types#24088
mergify[bot] merged 2 commits intomatrixorigin:3.0-devfrom
jiangxinmeng1:fix-decimal-compare-panic-24081

Conversation

@jiangxinmeng1
Copy link
Copy Markdown
Contributor

@jiangxinmeng1 jiangxinmeng1 commented Apr 8, 2026

What type of PR is this?

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

Which issue(s) this PR fixes:

issue #24081

What this PR does / why we need it:

When executing a window function query like:

SELECT ... FROM (
    SELECT ROW_NUMBER() OVER (...) AS rn,
           SUM(amount) OVER (...) AS cum_val  -- amount is DECIMAL(10,2)
    FROM orders
) AS x
WHERE x.rn = 2;

The filter x.rn = 2 panics with:

panic unsafe slice cast: from length 8 is not enough for length 16

Root cause: The comparison dispatcher (equalFn) selects valueDec128Compare based on one parameter's type (decimal128). When the other parameter is int64 (from ROW_NUMBER()), it tries to read 8-byte int64 data as 16-byte Decimal128, causing a panic.

Fix: Extend the existing type-mismatch fallback mechanism in func_compare_fix.go:

  • Add T_decimal64 and T_decimal128 to isNumericType() so shouldUseTypeMismatchPath() catches decimal-vs-integer mismatches
  • Add decimal conversion cases in getAsFloat64Slice() using Decimal64ToFloat64 / Decimal128ToFloat64

Test coverage

Added tests:

  • TestEqualFnDecimalIntMismatch — reproduces the exact panic scenario (decimal128 == int64, int64 == decimal128, decimal64 == decimal128)
  • Updated TestIsNumericType and TestShouldUseTypeMismatchPath for decimal types
  • Added decimal→float64 conversion tests in TestGetAsFloat64Slice

…integer types (matrixorigin#24081)

The comparison function dispatcher (equalFn, greatThanFn, etc.) dispatches
based on parameters[0]'s type. When a decimal128 parameter is paired with
an int64 parameter (e.g., ROW_NUMBER() result compared with a decimal literal),
valueDec128Compare tries to read 8-byte int64 data as 16-byte Decimal128,
causing: panic unsafe slice cast: from length 8 is not enough for length 16

Fix:
- Add T_decimal64 and T_decimal128 to isNumericType() so the type-mismatch
  fallback path (shouldUseTypeMismatchPath) catches decimal-vs-integer mismatches
- Add decimal conversion cases in getAsFloat64Slice() using Decimal64ToFloat64
  and Decimal128ToFloat64

Approved by: @jiangxinmeng1
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@XuPeng-SH XuPeng-SH left a comment

Choose a reason for hiding this comment

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

Code Review Summary

LGTM ✅

Changes Reviewed

  1. isNumericType() - Correctly extended to include T_decimal64 and T_decimal128
  2. getAsFloat64Slice() - Properly added decimal→float64 conversion using Decimal64ToFloat64() and Decimal128ToFloat64() with correct Scale handling
  3. Test coverage - Comprehensive tests for all new functionality

Root Cause

When comparing decimal128 with int64 (e.g., ROW_NUMBER() = 2), the comparison function tried to read 8-byte int64 data as 16-byte Decimal128, causing panic:

panic unsafe slice cast: from length 8 is not enough for length 16

Fix Mechanism

The fix correctly leverages the existing type-mismatch fallback path by:

  1. Recognizing decimal types as numeric in isNumericType()
  2. Converting decimal values to float64 for comparison when type mismatch is detected

Potential Note

Decimal→float64 conversion has precision loss (38 digits → 15-16 digits), but this is acceptable for the fallback path. For ROW_NUMBER() comparisons (integer values), precision is preserved.

All tests pass ✅

@jiangxinmeng1 jiangxinmeng1 force-pushed the fix-decimal-compare-panic-24081 branch from 49e4dc5 to ad0bf58 Compare April 8, 2026 08:43
@jiangxinmeng1 jiangxinmeng1 requested a review from heni02 as a code owner April 8, 2026 08:43
@mergify
Copy link
Copy Markdown
Contributor

mergify bot commented Apr 9, 2026

Merge Queue Status

  • Entered queue2026-04-09 03:10 UTC · Rule: release-3.0
  • Checks skipped · PR is already up-to-date
  • Merged2026-04-09 03:10 UTC · at 9e20b7a5712c50c8f7833b08c3f8f0b0f26bff75

This pull request spent 13 seconds in the queue, including 1 second running CI.

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

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 kind/feature size/M Denotes a PR that changes [100,499] lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants