Skip to content

sql: preserve common type for homogeneous builtins - #174720

Open
Alignyx wants to merge 1 commit into
cockroachdb:masterfrom
Alignyx:fix-159153-least-mixed-int-width
Open

sql: preserve common type for homogeneous builtins#174720
Alignyx wants to merge 1 commit into
cockroachdb:masterfrom
Alignyx:fix-159153-least-mixed-int-width

Conversation

@Alignyx

@Alignyx Alignyx commented Sep 5, 2026

Copy link
Copy Markdown

Fixes #159153.

Root cause

Homogeneous overload resolution selected INT4 as the common type for mixed-width integer arguments, but equivalent integer types were allowed to keep their original widths. least and greatest derive their return type from the first non-NULL argument, so a narrow INT2 first argument made the result slot INT2 even when evaluation selected an INT4 value. The wider value was then truncated; in the reported case -1347373370 became -18746.

How I tracked it down

I reproduced the nested least result and compared it with commuting the arguments, explicitly promoting the narrow argument, and an equivalent CASE expression. Those controls agreed on the full-width result, while the flat mixed-width least call remained correct. The plans differed only in scalar rendering. A focused overload-resolution test then showed the violated invariant directly: common-type selection returned INT4, but the first return-determining expression still resolved as INT2. That localized the bug to the HomogeneousType overload path rather than comparison or vectorized evaluation.

Fix

After homogeneous arguments have been validated and their common type selected, overload resolution now retypes only the first non-NULL argument to that common type when necessary. This keeps the change scoped to builtins that use HomogeneousType and FirstNonNullReturnType, while preserving the existing common-type checks and the types of the remaining arguments.

Test coverage

  • Added overload-resolution unit cases for mixed-width columns and for an integer constant followed by an INT4 column, asserting that the homogeneous arguments and return-determining expression resolve as INT4.
  • Added SQL regressions for the reported nested least, commuted arguments, explicit promotion, a NULL outer argument, the corresponding greatest case, and a flat mixed-width control.
  • Ran the regression in five local/fake-distributed row, vectorized, and disk-spilling configurations, plus the full tree and builtin packages and complete local/fake-distributed builtin-function logic suites.

Homogeneous overload resolution can select a wider common type while
leaving the first argument with a narrower, equivalent type. Since least
and greatest derive their return type from that argument, a wider selected
value can then be truncated by the result slot.

Retype only the first non-NULL homogeneous argument to the already checked
common type. Add type-checking and SQL regressions for mixed integer widths,
including commuted, promoted, NULL, and greatest variants.

Fixes cockroachdb#159153

Release note (bug fix): Fixed incorrect truncation in nested least and
greatest calls over mixed-width integer arguments.
@Alignyx
Alignyx requested a review from a team as a code owner September 5, 2026 01:24
@Alignyx
Alignyx requested review from andyyang890 and removed request for a team September 5, 2026 01:24
@blathers-crl

blathers-crl Bot commented Sep 5, 2026

Copy link
Copy Markdown

Thank you for contributing to CockroachDB. Please ensure you have followed the guidelines for creating a PR.

My owl senses detect your PR is good for review. Please keep an eye out for any test failures in CI.

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf.

@blathers-crl blathers-crl Bot added the O-community Originated from the community label Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

O-community Originated from the community

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inconsistent results for the least function

1 participant