Fix array_lower/array_upper to respect custom lower bounds#36780
Merged
Conversation
array_lower hardcoded a return value of 1 and array_upper returned the dimension length, both ignoring the array's actual lower bound. For arrays created with a non-default lower bound (e.g. via array_fill with a lower-bounds argument), this produced wrong results that disagreed with Postgres. Both now derive their results from ArrayDimension::dimension_bounds, so array_lower returns the lower bound and array_upper returns lower_bound + length - 1. Fixes https://github.com/MaterializeInc/database-issues/issues/11278 https://claude.ai/code/session_01A4oEvWwfEb6yE8FYgPAfpQ
antiguru
commented
May 29, 2026
Remove is_infix_op from array_lower/array_upper so they render as function calls (e.g. array_lower(arr, 1)) in EXPLAIN, consistent with array_length. Also drop the issue-number reference from the slt comment. https://claude.ai/code/session_01A4oEvWwfEb6yE8FYgPAfpQ
Reduce the sqlfunc attribute lists for array_lower/array_upper to just is_infix_op = true; output_type, sqlname, propagates_nulls and introduces_nulls are all inferred by the macro from the function signature, matching the previous explicit values. https://claude.ai/code/session_01A4oEvWwfEb6yE8FYgPAfpQ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Closes https://github.com/MaterializeInc/database-issues/issues/11278
Both
array_lower()andarray_upper()ignored the array's custom lower bound:array_lower()always returned1, regardless of the array's actual lower bound.array_upper()returned the dimension's length rather than its upper bound (lower_bound + length - 1).For arrays with the default lower bound of
1these happen to be correct (sinceupper_bound == length), so the bug only surfaced for arrays with a non-default lower bound, e.g. those built byarray_fill():PostgreSQL returns
5and7respectively.Description
array_lower(): now returns the dimension's actual lower bound viadim.dimension_bounds()instead of hardcoding1. The return type changed fromOption<i32>toResult<Option<i32>, EvalError>(matchingarray_upper()) so a bound that does not fit ini32is reported as an error.array_upper(): now returns the dimension's upper bound viadim.dimension_bounds()instead ofdim.length.sqlfuncattribute lists on both functions to justis_infix_op = true;output_type,sqlname,propagates_nulls, andintroduces_nullsare inferred by the macro from the signature and matched the previous explicit values.Verification
array_lower_upper_respect_lower_bound) insrc/expr/src/scalar/func.rscovering default, custom positive, negative, and out-of-range dimensions for both functions.test/sqllogictest/array_fill.sltfor single-dimension custom (5), negative (-3), and multi-dimensional (4,3) lower bounds.https://claude.ai/code/session_01A4oEvWwfEb6yE8FYgPAfpQ