Skip to content

Commit 0095b5a

Browse files
committed
[CALCITE-7639] Descope binary right shift pending endianness design (CALCITE-7651)
The byte[] shift added for LEFTSHIFT treats binary as little-endian and modulo-wraps the amount, which is inconsistent with the big-endian CAST(INT AS BINARY) from CALCITE-7368. Rather than cement that behaviour in a new operator, restrict >> and RIGHTSHIFT to integer/unsigned operands and reject BINARY/VARBINARY at validation. Binary shift semantics are tracked separately in CALCITE-7651; binary left shift is left as released. - Split the shared shift operand type checker: keep BINARY for <</LEFTSHIFT, add a non-binary checker for >>/RIGHTSHIFT. - Remove the unused rightShift(byte[])/rightShift(ByteString) overloads. - Replace the binary/VARBINARY right-shift tests with checkFails that pin the rejection; keep the integer/unsigned coverage. - Update the RIGHTSHIFT reference docs accordingly.
1 parent d7fc15d commit 0095b5a

5 files changed

Lines changed: 54 additions & 178 deletions

File tree

core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java

Lines changed: 3 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3945,65 +3945,9 @@ public static long rightShift(long x, long y) {
39453945
return y >= 0 ? x >> shift : x << shift;
39463946
}
39473947

3948-
/**
3949-
* Performs PostgresSQL-style bitwise shift on a byte array.
3950-
* Positive shift: right shift.
3951-
* Negative shift: treated as positive shift with modulo arithmetic.
3952-
*
3953-
* @param bytes the input byte array
3954-
* @param y the shift amount in bits
3955-
* @return the shifted byte array
3956-
*/
3957-
public static byte[] rightShift(byte[] bytes, long y) {
3958-
if (bytes.length == 0) {
3959-
return new byte[0];
3960-
}
3961-
3962-
int bitLen = bytes.length * 8;
3963-
3964-
// PostgreSQL behavior: always treat as right shift with modulo arithmetic
3965-
// Negative y becomes equivalent positive shift
3966-
int shift = positiveModulo(y, bitLen);
3967-
3968-
if (shift == 0) {
3969-
return bytes.clone();
3970-
}
3971-
3972-
byte[] result = new byte[bytes.length];
3973-
3974-
// Always perform right shift (even for originally negative y)
3975-
int byteShift = shift / 8;
3976-
int bitShift = shift % 8;
3977-
3978-
for (int i = 0; i < bytes.length; i++) {
3979-
int srcIndex = i + byteShift;
3980-
int val = 0;
3981-
3982-
// Get the main byte
3983-
if (srcIndex < bytes.length) {
3984-
val = (bytes[srcIndex] & 0xFF) >>> bitShift;
3985-
}
3986-
3987-
// Get carry bits from next byte
3988-
if (srcIndex + 1 < bytes.length && bitShift != 0) {
3989-
val |= (bytes[srcIndex + 1] & 0xFF) << (8 - bitShift);
3990-
}
3991-
3992-
result[i] = (byte) val;
3993-
}
3994-
return result;
3995-
}
3996-
3997-
/**
3998-
* Performs PostgresSQL-style bitwise shift on ByteString.
3999-
*
4000-
* @param bytes the ByteString to shift
4001-
* @param y the shift amount in bits
4002-
* @return shifted ByteString
4003-
*/
4004-
public static ByteString rightShift(ByteString bytes, long y) {
4005-
return new ByteString(rightShift(bytes.getBytes(), y));
4006-
}
3948+
// Right shift on binary (byte[]/ByteString) is intentionally not implemented:
3949+
// BINARY/VARBINARY operands are rejected for >> and RIGHTSHIFT until the
3950+
// endianness of bitwise shifts on binary is settled. See [CALCITE-7651].
40073951

40083952
/**
40093953
* Performs PostgresSQL-style bitwise shift on UByte.

core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,16 +1369,28 @@ public class SqlStdOperatorTable extends ReflectiveSqlOperatorTable {
13691369
new SqlBitOpAggFunction(SqlKind.BIT_XOR);
13701370

13711371
/**
1372-
* Operand type checker shared by the shift operators ({@code <<}, {@code >>})
1373-
* and their function forms ({@code LEFTSHIFT}, {@code RIGHTSHIFT}). The first
1374-
* operand is the value being shifted (integer, binary or unsigned numeric) and
1375-
* the second is the integer shift amount.
1372+
* Operand type checker shared by the left shift operator ({@code <<}) and its
1373+
* function form ({@code LEFTSHIFT}). The first operand is the value being
1374+
* shifted (integer, binary or unsigned numeric) and the second is the integer
1375+
* shift amount.
13761376
*/
13771377
private static final SqlOperandTypeChecker SHIFT_OPERAND_TYPE_CHECKER =
13781378
OperandTypes.INTEGER_INTEGER
13791379
.or(OperandTypes.family(SqlTypeFamily.BINARY, SqlTypeFamily.INTEGER))
13801380
.or(OperandTypes.family(SqlTypeFamily.UNSIGNED_NUMERIC, SqlTypeFamily.INTEGER));
13811381

1382+
/**
1383+
* Operand type checker for the right shift operator ({@code >>}) and its
1384+
* function form ({@code RIGHTSHIFT}). Like {@link #SHIFT_OPERAND_TYPE_CHECKER}
1385+
* but the value being shifted may only be integer or unsigned numeric, not
1386+
* binary. Binary right shift is intentionally excluded until the endianness of
1387+
* bitwise shifts on {@code BINARY}/{@code VARBINARY} is settled; see
1388+
* <a href="https://issues.apache.org/jira/browse/CALCITE-7651">[CALCITE-7651]</a>.
1389+
*/
1390+
private static final SqlOperandTypeChecker NON_BINARY_SHIFT_OPERAND_TYPE_CHECKER =
1391+
OperandTypes.INTEGER_INTEGER
1392+
.or(OperandTypes.family(SqlTypeFamily.UNSIGNED_NUMERIC, SqlTypeFamily.INTEGER));
1393+
13821394
/**
13831395
* <code>{@code <<}</code> (left shift) operator.
13841396
*/
@@ -1413,7 +1425,7 @@ public class SqlStdOperatorTable extends ReflectiveSqlOperatorTable {
14131425
true,
14141426
ReturnTypes.ARG0_NULLABLE,
14151427
InferTypes.FIRST_KNOWN,
1416-
SHIFT_OPERAND_TYPE_CHECKER);
1428+
NON_BINARY_SHIFT_OPERAND_TYPE_CHECKER);
14171429

14181430
/**
14191431
* right shift function.
@@ -1423,7 +1435,7 @@ public class SqlStdOperatorTable extends ReflectiveSqlOperatorTable {
14231435
"RIGHTSHIFT",
14241436
SqlKind.OTHER_FUNCTION,
14251437
ReturnTypes.ARG0_NULLABLE,
1426-
SHIFT_OPERAND_TYPE_CHECKER);
1438+
NON_BINARY_SHIFT_OPERAND_TYPE_CHECKER);
14271439

14281440
//-------------------------------------------------------------
14291441
// WINDOW Aggregate Functions

core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2080,40 +2080,9 @@ private long sqlTimestamp(String str) {
20802080
}
20812081

20822082
@Test void testRightShift() {
2083-
// For every shift amount, cross-check the byte-array shift against the
2084-
// equivalent shift computed on the value's integer interpretation. The byte
2085-
// array is treated as a little-endian bit string of width 8 * length (index
2086-
// 0 is the least-significant byte); rightShift always shifts right (zero
2087-
// fill) by the amount normalized modulo that width, so a negative amount
2088-
// wraps into range rather than reversing direction.
2089-
byte[] data1 = {(byte) 0xF0}; // 11110000
2090-
for (int shift = -10; shift <= 10; shift++) {
2091-
byte[] result = SqlFunctions.rightShift(data1.clone(), shift);
2092-
assertEquals(1, result.length);
2093-
int norm = Math.floorMod(shift, 8);
2094-
int expected = (data1[0] & 0xFF) >>> norm;
2095-
assertEquals((byte) expected, result[0]);
2096-
}
2097-
2098-
byte[] data2 = {(byte) 0x12, (byte) 0x34};
2099-
for (int shift = -18; shift <= 18; shift++) {
2100-
byte[] result = SqlFunctions.rightShift(data2.clone(), shift);
2101-
assertEquals(2, result.length);
2102-
int value = (data2[0] & 0xFF) | ((data2[1] & 0xFF) << 8); // little-endian
2103-
int norm = Math.floorMod(shift, 16);
2104-
int expected = value >>> norm;
2105-
assertEquals((byte) expected, result[0]);
2106-
assertEquals((byte) (expected >>> 8), result[1]);
2107-
}
2108-
2109-
// Verify specific known cases
2110-
assertArrayEquals(new byte[]{(byte) 0xAB, (byte) 0xCD},
2111-
SqlFunctions.rightShift(new byte[]{(byte) 0xAB, (byte) 0xCD}, 0));
2112-
2113-
assertArrayEquals(new byte[]{(byte) 0x40, (byte) 0x00},
2114-
SqlFunctions.rightShift(new byte[]{(byte) 0x80, (byte) 0x00}, 1));
2115-
2116-
// Scalar arithmetic (sign-preserving) right shift
2083+
// Scalar arithmetic (sign-preserving) right shift. Binary right shift is
2084+
// intentionally not supported (see [CALCITE-7651]), so there is no
2085+
// byte-array overload to exercise here.
21172086
assertEquals(2, SqlFunctions.rightShift(8, 2));
21182087
assertEquals(-5, SqlFunctions.rightShift(-20, 2));
21192088
}

site/_docs/reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2974,7 +2974,7 @@ In the following:
29742974
| * | BITOR(value1, value2) | Returns the bitwise OR of *value1* and *value2*. *value1* and *value2* must both be integer or binary values. Binary values must be of the same length.
29752975
| * | BITXOR(value1, value2) | Returns the bitwise XOR of *value1* and *value2*. *value1* and *value2* must both be integer or binary values. Binary values must be of the same length.
29762976
| * | LEFTSHIFT(value1, value2) | Returns the result of left-shifting *value1* by *value2* bits. *value1* can be integer, unsigned integer, or binary. For binary, the result has the same length as *value1*. The shift amount *value2* is normalized using modulo arithmetic based on the bit width of *value1* (for example, modulo 32 for `INTEGER` and modulo 64 for `BIGINT`); for binary types it is modulo (8 × N), where N is the actual length in bytes of the *value1* value — for a variable-length `VARBINARY` value this is the length of the value itself, not its declared maximum. For integer and unsigned types the sign of *value2* selects the direction: a non-negative amount shifts left and a negative amount shifts right by the normalized magnitude (for example, `LEFTSHIFT(1, -2)` returns `0`, a right shift by 30, and `LEFTSHIFT(8, -1)` returns `0`). For binary the shift is always to the left; a negative *value2* is simply folded into the range [0, 8 × N) by the same modulo.
2977-
| * | RIGHTSHIFT(value1, value2) | Returns the result of right-shifting *value1* by *value2* bits. For signed integers the shift is arithmetic (the sign bit is preserved). *value1* can be integer, unsigned integer, or binary. For binary, the result has the same length as *value1*. The shift amount *value2* is normalized using modulo arithmetic based on the bit width of *value1* (for example, modulo 32 for `INTEGER` and modulo 64 for `BIGINT`); for binary types it is modulo (8 × N), where N is the actual length in bytes of the *value1* value — for a variable-length `VARBINARY` value this is the length of the value itself, not its declared maximum. For integer and unsigned types the sign of *value2* selects the direction: a non-negative amount shifts right and a negative amount shifts left by the normalized magnitude (for example, `RIGHTSHIFT(1024, 2)` returns `256`, `RIGHTSHIFT(-20, 2)` returns `-5`, and `RIGHTSHIFT(1, -2)` returns `1073741824`, a left shift by 30). For binary the shift is always to the right; a negative *value2* is simply folded into the range [0, 8 × N) by the same modulo.
2977+
| * | RIGHTSHIFT(value1, value2) | Returns the result of right-shifting *value1* by *value2* bits. For signed integers the shift is arithmetic (the sign bit is preserved). *value1* can be integer or unsigned integer (binary right shift is not yet supported). The shift amount *value2* is normalized using modulo arithmetic based on the bit width of *value1* (for example, modulo 32 for `INTEGER` and modulo 64 for `BIGINT`). The sign of *value2* selects the direction: a non-negative amount shifts right and a negative amount shifts left by the normalized magnitude (for example, `RIGHTSHIFT(1024, 2)` returns `256`, `RIGHTSHIFT(-20, 2)` returns `-5`, and `RIGHTSHIFT(1, -2)` returns `1073741824`, a left shift by 30).
29782978
| * | BITNOT(value) | Returns the bitwise NOT of *value*. *value* must be either an integer type or a binary value.
29792979
| f | BITAND_AGG(value) | Equivalent to `BIT_AND(value)`
29802980
| f | BITOR_AGG(value) | Equivalent to `BIT_OR(value)`

testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java

Lines changed: 29 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -17226,7 +17226,7 @@ private static void checkLogicalOrFunc(SqlOperatorFixture f) {
1722617226
f.checkScalar("CAST(8 AS INTEGER) >> CAST(2 AS BIGINT)", "2", "INTEGER NOT NULL");
1722717227
f.checkFails("^8 >> CAST(2 AS INTEGER UNSIGNED)^",
1722817228
"Cannot apply '>>' to arguments of type '<INTEGER> >> <INTEGER UNSIGNED>'\\. "
17229-
+ "Supported form\\(s\\): '<INTEGER> >> <INTEGER>'\\n'<BINARY> >> <INTEGER>'\\n"
17229+
+ "Supported form\\(s\\): '<INTEGER> >> <INTEGER>'\\n"
1723017230
+ "'<UNSIGNED_NUMERIC> >> <INTEGER>'",
1723117231
false);
1723217232

@@ -17241,46 +17241,25 @@ private static void checkLogicalOrFunc(SqlOperatorFixture f) {
1724117241
f.checkScalar("0 >> 32", "0", "INTEGER NOT NULL");
1724217242
f.checkScalar("0 >> 100", "0", "INTEGER NOT NULL");
1724317243

17244-
// === Binary type tests ===
17245-
// A binary literal such as X'FF' already has type BINARY(1) (X'FFFF' is
17246-
// BINARY(2), and so on), so no cast is needed to exercise the BINARY path.
17247-
f.checkScalar("X'FF' >> 1", "7f", "BINARY(1) NOT NULL");
17248-
f.checkScalar("X'F0' >> 4", "0f", "BINARY(1) NOT NULL");
17249-
f.checkScalar("X'08' >> 3", "01", "BINARY(1) NOT NULL");
17250-
f.checkScalar("X'00' >> 5", "00", "BINARY(1) NOT NULL");
17251-
17252-
f.checkScalar("X'FFFF' >> 1", "ff7f", "BINARY(2) NOT NULL");
17253-
f.checkScalar("X'1234' >> 4", "4103", "BINARY(2) NOT NULL");
17254-
f.checkScalar("X'1234' >> 8", "3400", "BINARY(2) NOT NULL");
17255-
17256-
f.checkScalar("X'FF' >> 8", "ff", "BINARY(1) NOT NULL");
17257-
f.checkScalar("X'FFFF' >> 16", "ffff", "BINARY(2) NOT NULL");
17258-
17259-
f.checkScalar("X'ABCD' >> 0", "abcd", "BINARY(2) NOT NULL");
17260-
f.checkScalar("X'123456' >> 4", "416305", "BINARY(3) NOT NULL");
17261-
f.checkScalar("X'0001' >> 1", "8000", "BINARY(2) NOT NULL");
17262-
f.checkScalar("X'8000' >> 1", "4000", "BINARY(2) NOT NULL");
17263-
f.checkScalar("X'F0' >> -4", "0f", "BINARY(1) NOT NULL");
17264-
17265-
// === VARBINARY type tests ===
17266-
// For variable-length binary the shift width is 8 * the actual value
17267-
// length, so the modulo used to normalize the amount tracks the value.
17268-
f.checkScalar("CAST(X'FF' AS VARBINARY) >> 1", "7f", "VARBINARY NOT NULL");
17269-
f.checkScalar("CAST(X'F0' AS VARBINARY) >> 4", "0f", "VARBINARY NOT NULL");
17270-
f.checkScalar("CAST(X'FFFF' AS VARBINARY) >> 1", "ff7f", "VARBINARY NOT NULL");
17271-
f.checkScalar("CAST(X'123456' AS VARBINARY) >> 4", "416305",
17272-
"VARBINARY NOT NULL");
17273-
// 8 % (8 * 1) = 0 leaves the 1-byte value unchanged, while 8 % (8 * 2) = 8
17274-
// shifts the 2-byte value by a whole byte: the width follows the value.
17275-
f.checkScalar("CAST(X'FF' AS VARBINARY) >> 8", "ff", "VARBINARY NOT NULL");
17276-
f.checkScalar("CAST(X'FFFF' AS VARBINARY) >> 8", "ff00",
17277-
"VARBINARY NOT NULL");
17278-
f.checkScalar("CAST(X'F0' AS VARBINARY) >> -4", "0f", "VARBINARY NOT NULL");
17244+
// === Binary operands are not supported ===
17245+
// Unlike '<<', binary right shift is intentionally rejected until the
17246+
// endianness of bitwise shifts on binary is settled (see [CALCITE-7651]).
17247+
// A binary literal such as X'FF' already has type BINARY(1).
17248+
f.checkFails("^X'FF' >> 1^",
17249+
"Cannot apply '>>' to arguments of type '<BINARY\\(1\\)> >> <INTEGER>'\\. "
17250+
+ "Supported form\\(s\\): '<INTEGER> >> <INTEGER>'\\n"
17251+
+ "'<UNSIGNED_NUMERIC> >> <INTEGER>'",
17252+
false);
17253+
f.checkFails("^CAST(X'FF' AS VARBINARY) >> 1^",
17254+
"Cannot apply '>>' to arguments of type '<VARBINARY> >> <INTEGER>'\\. "
17255+
+ "Supported form\\(s\\): '<INTEGER> >> <INTEGER>'\\n"
17256+
+ "'<UNSIGNED_NUMERIC> >> <INTEGER>'",
17257+
false);
1727917258

1728017259
// === Invalid argument types ===
1728117260
f.checkFails("^1.2 >> 2^",
1728217261
"Cannot apply '>>' to arguments of type '<DECIMAL\\(2, 1\\)> >> <INTEGER>'\\. Supported "
17283-
+ "form\\(s\\): '<INTEGER> >> <INTEGER>'\\n'<BINARY> >> <INTEGER>'\\n'<UNSIGNED_NUMERIC> "
17262+
+ "form\\(s\\): '<INTEGER> >> <INTEGER>'\\n'<UNSIGNED_NUMERIC> "
1728417263
+ ">> <INTEGER>'",
1728517264
false);
1728617265

@@ -17347,54 +17326,26 @@ private static void checkLogicalOrFunc(SqlOperatorFixture f) {
1734717326
f.checkScalar("RIGHTSHIFT(0, 32)", "0", "INTEGER NOT NULL");
1734817327
f.checkScalar("RIGHTSHIFT(0, 100)", "0", "INTEGER NOT NULL");
1734917328

17350-
// === Binary types ===
17351-
// A binary literal such as X'FF' already has type BINARY(1) (X'FFFF' is
17352-
// BINARY(2), and so on), so no cast is needed to exercise the BINARY path.
17353-
f.checkScalar("RIGHTSHIFT(X'FF', 1)", "7f", "BINARY(1) NOT NULL");
17354-
f.checkScalar("RIGHTSHIFT(X'F0', 4)", "0f", "BINARY(1) NOT NULL");
17355-
f.checkScalar("RIGHTSHIFT(X'08', 3)", "01", "BINARY(1) NOT NULL");
17356-
f.checkScalar("RIGHTSHIFT(X'00', 5)", "00", "BINARY(1) NOT NULL");
17357-
17358-
f.checkScalar("RIGHTSHIFT(X'FFFF', 1)", "ff7f", "BINARY(2) NOT NULL");
17359-
f.checkScalar("RIGHTSHIFT(X'1234', 4)", "4103", "BINARY(2) NOT NULL");
17360-
f.checkScalar("RIGHTSHIFT(X'1234', 8)", "3400", "BINARY(2) NOT NULL");
17361-
f.checkScalar("RIGHTSHIFT(X'FF', 8)", "ff", "BINARY(1) NOT NULL");
17362-
f.checkScalar("RIGHTSHIFT(X'FFFF', 16)", "ffff", "BINARY(2) NOT NULL");
17363-
17364-
f.checkScalar("RIGHTSHIFT(X'ABCD', 0)", "abcd", "BINARY(2) NOT NULL");
17365-
f.checkScalar("RIGHTSHIFT(X'123456', 4)", "416305", "BINARY(3) NOT NULL");
17366-
f.checkScalar("RIGHTSHIFT(X'0001', 1)", "8000", "BINARY(2) NOT NULL");
17367-
f.checkScalar("RIGHTSHIFT(X'8000', 1)", "4000", "BINARY(2) NOT NULL");
17368-
f.checkScalar("RIGHTSHIFT(X'F0', -4)", "0f", "BINARY(1) NOT NULL");
17369-
17370-
// === VARBINARY types ===
17371-
// For variable-length binary the shift width is 8 * the actual value
17372-
// length, so the modulo used to normalize the amount tracks the value.
17373-
f.checkScalar("RIGHTSHIFT(CAST(X'FF' AS VARBINARY), 1)", "7f",
17374-
"VARBINARY NOT NULL");
17375-
f.checkScalar("RIGHTSHIFT(CAST(X'F0' AS VARBINARY), 4)", "0f",
17376-
"VARBINARY NOT NULL");
17377-
f.checkScalar("RIGHTSHIFT(CAST(X'FFFF' AS VARBINARY), 1)", "ff7f",
17378-
"VARBINARY NOT NULL");
17379-
f.checkScalar("RIGHTSHIFT(CAST(X'123456' AS VARBINARY), 4)", "416305",
17380-
"VARBINARY NOT NULL");
17381-
// 8 % (8 * 1) = 0 leaves the 1-byte value unchanged, while 8 % (8 * 2) = 8
17382-
// shifts the 2-byte value by a whole byte: the width follows the value.
17383-
f.checkScalar("RIGHTSHIFT(CAST(X'FF' AS VARBINARY), 8)", "ff",
17384-
"VARBINARY NOT NULL");
17385-
f.checkScalar("RIGHTSHIFT(CAST(X'FFFF' AS VARBINARY), 8)", "ff00",
17386-
"VARBINARY NOT NULL");
17387-
f.checkScalar("RIGHTSHIFT(CAST(X'F0' AS VARBINARY), -4)", "0f",
17388-
"VARBINARY NOT NULL");
17329+
// === Binary operands are not supported ===
17330+
// Unlike LEFTSHIFT, binary right shift is intentionally rejected until the
17331+
// endianness of bitwise shifts on binary is settled (see [CALCITE-7651]).
17332+
// A binary literal such as X'FF' already has type BINARY(1).
17333+
f.checkFails("^RIGHTSHIFT(X'FF', 1)^",
17334+
"Cannot apply 'RIGHTSHIFT' to arguments of type 'RIGHTSHIFT\\(<BINARY\\(1\\)>, <INTEGER>\\)'\\. Supported form\\(s\\): 'RIGHTSHIFT\\(<INTEGER>, <INTEGER>\\)'\\n'RIGHTSHIFT\\(<UNSIGNED_NUMERIC>, <INTEGER>\\)'",
17335+
false);
17336+
f.checkFails("^RIGHTSHIFT(CAST(X'FF' AS VARBINARY), 1)^",
17337+
"Cannot apply 'RIGHTSHIFT' to arguments of type 'RIGHTSHIFT\\(<VARBINARY>, <INTEGER>\\)'\\. Supported form\\(s\\): 'RIGHTSHIFT\\(<INTEGER>, <INTEGER>\\)'\\n'RIGHTSHIFT\\(<UNSIGNED_NUMERIC>, <INTEGER>\\)'",
17338+
false);
17339+
1738917340
// === Invalid types ===
1739017341
f.checkFails("^RIGHTSHIFT(1.2, 2)^",
17391-
"Cannot apply 'RIGHTSHIFT' to arguments of type 'RIGHTSHIFT\\(<DECIMAL\\(2, 1\\)>, <INTEGER>\\)'\\. Supported form\\(s\\): 'RIGHTSHIFT\\(<INTEGER>, <INTEGER>\\)'\\n'RIGHTSHIFT\\(<BINARY>, <INTEGER>\\)'\\n'RIGHTSHIFT\\(<UNSIGNED_NUMERIC>, <INTEGER>\\)'",
17342+
"Cannot apply 'RIGHTSHIFT' to arguments of type 'RIGHTSHIFT\\(<DECIMAL\\(2, 1\\)>, <INTEGER>\\)'\\. Supported form\\(s\\): 'RIGHTSHIFT\\(<INTEGER>, <INTEGER>\\)'\\n'RIGHTSHIFT\\(<UNSIGNED_NUMERIC>, <INTEGER>\\)'",
1739217343
false);
1739317344
// A BIGINT shift amount is accepted, but an unsigned shift amount is not:
1739417345
// the second argument must be a signed integer type.
1739517346
f.checkScalar("RIGHTSHIFT(8, CAST(2 AS BIGINT))", "2", "INTEGER NOT NULL");
1739617347
f.checkFails("^RIGHTSHIFT(8, CAST(2 AS INTEGER UNSIGNED))^",
17397-
"Cannot apply 'RIGHTSHIFT' to arguments of type 'RIGHTSHIFT\\(<INTEGER>, <INTEGER UNSIGNED>\\)'\\. Supported form\\(s\\): 'RIGHTSHIFT\\(<INTEGER>, <INTEGER>\\)'\\n'RIGHTSHIFT\\(<BINARY>, <INTEGER>\\)'\\n'RIGHTSHIFT\\(<UNSIGNED_NUMERIC>, <INTEGER>\\)'",
17348+
"Cannot apply 'RIGHTSHIFT' to arguments of type 'RIGHTSHIFT\\(<INTEGER>, <INTEGER UNSIGNED>\\)'\\. Supported form\\(s\\): 'RIGHTSHIFT\\(<INTEGER>, <INTEGER>\\)'\\n'RIGHTSHIFT\\(<UNSIGNED_NUMERIC>, <INTEGER>\\)'",
1739817349
false);
1739917350

1740017351

0 commit comments

Comments
 (0)