Niels Pardon created CALCITE-7648:
-------------------------------------
Summary: Support unsigned shift amounts in the bitwise shift
operators and functions
Key: CALCITE-7648
URL: https://issues.apache.org/jira/browse/CALCITE-7648
Project: Calcite
Issue Type: Improvement
Reporter: Niels Pardon
The bitwise shift operators {{<<}} and {{>>}} and their function forms
{{LEFTSHIFT}} and {{RIGHTSHIFT}} (added under CALCITE-7639, [PR
5073|https://github.com/apache/calcite/pull/5073]) currently require the
*second* operand -- the shift amount -- to be a *signed* integer type. An
unsigned amount is rejected during validation:
{code:sql}
-- Cannot apply '>>' to arguments of type '<INTEGER> >> <INTEGER UNSIGNED>'
SELECT 8 >> CAST(2 AS INTEGER UNSIGNED);
SELECT RIGHTSHIFT(8, CAST(2 AS INTEGER UNSIGNED));
{code}
This is because {{SqlStdOperatorTable.SHIFT_OPERAND_TYPE_CHECKER}} only accepts
{{SqlTypeFamily.INTEGER}} for the second operand, and the runtime
{{SqlFunctions.leftShift}} / {{rightShift}} overloads take a signed {{long}}.
The value being shifted (first operand) already accepts unsigned numeric types;
only the shift amount does not, which is inconsistent.
h3. Suggested approach
(per review discussion on the CALCITE-7639 PR)
* Widen {{SHIFT_OPERAND_TYPE_CHECKER}} to also accept {{UNSIGNED_NUMERIC}} for
the second operand.
* In {{RexImpTable}}, cast the unsigned amount to {{long}} in the generated
enumerable code before calling the existing {{long}}-amount shift methods, so
no new runtime overloads are needed.
* {{BIGINT UNSIGNED}} ({{ULong}}) needs special handling: a value with the high
bit set exceeds {{Long.MAX_VALUE}}, so a naive cast to {{long}} yields a
negative value that the shift code reads as "shift in the opposite direction".
Decide and document how an out-of-{{long}}-range unsigned amount maps before
the modulo normalization.
h3. Test coverage to add
Executing operator tests for {{a >> CAST(x AS UNSIGNED)}} / {{RIGHTSHIFT(a,
CAST(x AS UNSIGNED))}} across {{TINYINT}} / {{SMALLINT}} / {{INTEGER}} /
{{BIGINT UNSIGNED}} shift amounts, including a {{BIGINT UNSIGNED}} amount with
the high bit set.
Follow-up to CALCITE-7639.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)