mihaibudiu commented on code in PR #4478:
URL: https://github.com/apache/calcite/pull/4478#discussion_r2299450551
##########
core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java:
##########
@@ -3506,6 +3506,152 @@ private static ByteString binaryOperator(
return new ByteString(result);
}
+ /**
+ * Performs bitwise shift on two integers.
+ * If the shift amount is positive, a left shift is applied.
+ * If the shift amount is negative, a logical right shift is applied.
+ * The shift amount is taken modulo 32.
+ */
+
+ public static int leftShift(int x, int y) {
+ int shift = Math.abs(y % 32);
+ return y >= 0 ? x << shift : x >>> shift;
+ }
+
+ /**
+ * Performs bitwise shift on a long value.
+ * If the shift amount is positive, a left shift is applied.
+ * If the shift amount is negative, a logical right shift is applied.
+ * The shift amount is taken modulo 64.
+ */
+
+ public static long leftShift(long x, int y) {
+ int shift = Math.abs(y % 64);
+ return y >= 0 ? x << shift : x >>> shift;
+ }
+
+ /**
+ * Performs bitwise shift with long shift amount.
+ * Note: input x is int, so shift mod 32 is used.
+ * Returns long to prevent overflow.
+ */
+ public static long leftShift(int x, long y) {
+ int shift = (int) Math.abs(y % 32);
+ return y >= 0 ? (long) x << shift : (long) x >>> shift;
+ }
+
+ /**
+ * Performs bitwise shift on a byte array.
+ * A positive shift amount performs a left shift.
+ * A negative shift amount performs a logical right shift.
+ */
+ public static ByteString leftShift(ByteString bytes, int y) {
+ byte[] result = leftShift(bytes.getBytes(), y);
+ return new ByteString(result);
+ }
+
+ /**
+ * Performs bitwise shift on a byte array.
+ * A positive shift amount performs a left shift.
+ * A negative shift amount performs a logical right shift.
+ */
+ public static byte[] leftShift(byte[] bytes, int y) {
Review Comment:
are you planning to do this?
probably using the BigInteger library is also the best way to test this
function.
##########
testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java:
##########
@@ -16518,6 +16518,218 @@ private static void
checkLogicalOrFunc(SqlOperatorFixture f) {
f.checkNull("CAST(NULL AS INTEGER UNSIGNED) ^^ CAST(NULL AS INTEGER
UNSIGNED)");
}
+ /**
+ * Test cases for
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-7109">[CALCITE-7109]
+ * Implement SHIFT_LEFT operator </a>.
+ */
+ @Test void testLeftShiftScalarFunc() {
+ final SqlOperatorFixture f = fixture();
+ f.setFor(SqlStdOperatorTable.BIT_LEFT_SHIFT, VmName.EXPAND);
+
+ // === Basic functionality ===
+ f.checkScalar("2 << 2", "8", "INTEGER NOT NULL");
+ f.checkScalar("1 << 10", "1024", "INTEGER NOT NULL");
+ f.checkScalar("0 << 5", "0", "INTEGER NOT NULL");
+
+ // === Type coercion and signed behavior ===
+ f.checkScalar("CAST(2 AS INTEGER) << CAST(3 AS BIGINT)", "16", "INTEGER
NOT NULL");
+ f.checkScalar("-5 << 2", "-20", "INTEGER NOT NULL");
+ f.checkScalar("-5 << 3", "-40", "INTEGER NOT NULL");
+ f.checkScalar("CAST(-5 AS TINYINT) << CAST(2 AS TINYINT)", "-20", "TINYINT
NOT NULL");
+
+ // === Verify return type matches first argument type ===
+ f.checkType("CAST(2 AS TINYINT) << CAST(3 AS TINYINT)", "TINYINT NOT
NULL");
+ f.checkType("CAST(2 AS SMALLINT) << CAST(3 AS SMALLINT)", "SMALLINT NOT
NULL");
+ f.checkType("CAST(2 AS INTEGER) << CAST(3 AS INTEGER)", "INTEGER NOT
NULL");
+ f.checkType("CAST(2 AS BIGINT) << CAST(3 AS BIGINT)", "BIGINT NOT NULL");
+
+ // === BigInt shifts with explicit BIGINT inputs ===
+ f.checkScalar("CAST(1 AS BIGINT) << 62", "4611686018427387904", "BIGINT
NOT NULL"); // 2^62
Review Comment:
Well, If you were computing 2^62 in Java it would be easier to check.
Maybe that's the right way, using the BigInteger library.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]