This is an automated email from the ASF dual-hosted git repository.

luchunliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/inlong.git


The following commit(s) were added to refs/heads/master by this push:
     new cb4b61b5a8 [INLONG-10965][SDK] Transform support Bitwise operation 
(#10970)
cb4b61b5a8 is described below

commit cb4b61b5a889cbb035b51ad1dd48f6a02790573f
Author: Zkplo <87751516+zk...@users.noreply.github.com>
AuthorDate: Tue Sep 3 10:26:19 2024 +0800

    [INLONG-10965][SDK] Transform support Bitwise operation (#10970)
    
    Co-authored-by: ZKpLo <14148880+zk...@user.noreply.gitee.com>
---
 .../transform/process/parser/BitwiseAndParser.java |  61 +++++++
 .../process/parser/BitwiseLeftShiftParser.java     |  67 ++++++++
 .../transform/process/parser/BitwiseOrParser.java  |  62 ++++++++
 .../process/parser/BitwiseRightShiftParser.java    |  66 ++++++++
 .../transform/process/parser/BitwiseXorParser.java |  62 ++++++++
 .../sdk/transform/process/parser/SignParser.java   |  26 ++-
 .../TestTransformArithmeticFunctionsProcessor.java | 175 +++++++++++++++++++++
 7 files changed, 513 insertions(+), 6 deletions(-)

diff --git 
a/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseAndParser.java
 
b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseAndParser.java
new file mode 100644
index 0000000000..b8920434ef
--- /dev/null
+++ 
b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseAndParser.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.inlong.sdk.transform.process.parser;
+
+import org.apache.inlong.sdk.transform.decode.SourceData;
+import org.apache.inlong.sdk.transform.process.Context;
+import org.apache.inlong.sdk.transform.process.operator.OperatorTools;
+
+import lombok.extern.slf4j.Slf4j;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseAnd;
+
+import java.math.BigInteger;
+
+/**
+ * BitwiseAndParser
+ */
+@Slf4j
+@TransformParser(values = BitwiseAnd.class)
+public class BitwiseAndParser implements ValueParser {
+
+    private final ValueParser left;
+
+    private final ValueParser right;
+
+    public BitwiseAndParser(BitwiseAnd expr) {
+        this.left = OperatorTools.buildParser(expr.getLeftExpression());
+        this.right = OperatorTools.buildParser(expr.getRightExpression());
+    }
+
+    @Override
+    public Object parse(SourceData sourceData, int rowIndex, Context context) {
+        try {
+            Object leftObj = this.left.parse(sourceData, rowIndex, context);
+            Object rightObj = this.right.parse(sourceData, rowIndex, context);
+            if (leftObj == null || rightObj == null) {
+                return null;
+            }
+            BigInteger leftValue = 
OperatorTools.parseBigDecimal(leftObj).toBigInteger();
+            BigInteger rightValue = 
OperatorTools.parseBigDecimal(rightObj).toBigInteger();
+            return 
Long.toUnsignedString(leftValue.and(rightValue).longValue());
+        } catch (Exception e) {
+            log.error("Value parsing failed", e);
+            return null;
+        }
+    }
+}
diff --git 
a/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseLeftShiftParser.java
 
b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseLeftShiftParser.java
new file mode 100644
index 0000000000..c68bc89e54
--- /dev/null
+++ 
b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseLeftShiftParser.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.inlong.sdk.transform.process.parser;
+
+import org.apache.inlong.sdk.transform.decode.SourceData;
+import org.apache.inlong.sdk.transform.process.Context;
+import org.apache.inlong.sdk.transform.process.operator.OperatorTools;
+
+import lombok.extern.slf4j.Slf4j;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseLeftShift;
+
+import java.math.BigInteger;
+
+/**
+ * BitwiseLeftShiftParser
+ * 
+ */
+@Slf4j
+@TransformParser(values = BitwiseLeftShift.class)
+public class BitwiseLeftShiftParser implements ValueParser {
+
+    private final ValueParser left;
+
+    private final ValueParser right;
+
+    public BitwiseLeftShiftParser(BitwiseLeftShift expr) {
+        this.left = OperatorTools.buildParser(expr.getLeftExpression());
+        this.right = OperatorTools.buildParser(expr.getRightExpression());
+    }
+
+    @Override
+    public Object parse(SourceData sourceData, int rowIndex, Context context) {
+        try {
+            Object leftObj = this.left.parse(sourceData, rowIndex, context);
+            Object rightObj = this.right.parse(sourceData, rowIndex, context);
+            if (leftObj == null || rightObj == null) {
+                return null;
+            }
+            BigInteger leftValue = 
OperatorTools.parseBigDecimal(leftObj).toBigInteger();
+            String unsignedRight = 
Long.toUnsignedString(OperatorTools.parseBigDecimal(rightObj).longValue());
+            int cmp = new BigInteger(unsignedRight).compareTo(new 
BigInteger("65"));
+            if (cmp >= 0) {
+                return 
Long.toUnsignedString(leftValue.shiftLeft(65).longValue());
+            } else {
+                return 
Long.toUnsignedString(leftValue.shiftLeft(Integer.parseInt(unsignedRight)).longValue());
+            }
+        } catch (Exception e) {
+            log.error("Value parsing failed", e);
+            return null;
+        }
+    }
+}
diff --git 
a/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseOrParser.java
 
b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseOrParser.java
new file mode 100644
index 0000000000..2cbf5e9d09
--- /dev/null
+++ 
b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseOrParser.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.inlong.sdk.transform.process.parser;
+
+import org.apache.inlong.sdk.transform.decode.SourceData;
+import org.apache.inlong.sdk.transform.process.Context;
+import org.apache.inlong.sdk.transform.process.operator.OperatorTools;
+
+import lombok.extern.slf4j.Slf4j;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseOr;
+
+import java.math.BigInteger;
+
+/**
+ * BitwiseOrParser
+ * 
+ */
+@Slf4j
+@TransformParser(values = BitwiseOr.class)
+public class BitwiseOrParser implements ValueParser {
+
+    private final ValueParser left;
+
+    private final ValueParser right;
+
+    public BitwiseOrParser(BitwiseOr expr) {
+        this.left = OperatorTools.buildParser(expr.getLeftExpression());
+        this.right = OperatorTools.buildParser(expr.getRightExpression());
+    }
+
+    @Override
+    public Object parse(SourceData sourceData, int rowIndex, Context context) {
+        try {
+            Object leftObj = this.left.parse(sourceData, rowIndex, context);
+            Object rightObj = this.right.parse(sourceData, rowIndex, context);
+            if (leftObj == null || rightObj == null) {
+                return null;
+            }
+            BigInteger leftValue = 
OperatorTools.parseBigDecimal(leftObj).toBigInteger();
+            BigInteger rightValue = 
OperatorTools.parseBigDecimal(rightObj).toBigInteger();
+            return Long.toUnsignedString(leftValue.or(rightValue).longValue());
+        } catch (Exception e) {
+            log.error("Value parsing failed", e);
+            return null;
+        }
+    }
+}
diff --git 
a/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseRightShiftParser.java
 
b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseRightShiftParser.java
new file mode 100644
index 0000000000..7b6085725b
--- /dev/null
+++ 
b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseRightShiftParser.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.inlong.sdk.transform.process.parser;
+
+import org.apache.inlong.sdk.transform.decode.SourceData;
+import org.apache.inlong.sdk.transform.process.Context;
+import org.apache.inlong.sdk.transform.process.operator.OperatorTools;
+
+import lombok.extern.slf4j.Slf4j;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseRightShift;
+
+import java.math.BigInteger;
+
+/**
+ * BitwiseRightShiftParser
+ */
+@Slf4j
+@TransformParser(values = BitwiseRightShift.class)
+public class BitwiseRightShiftParser implements ValueParser {
+
+    private final ValueParser left;
+
+    private final ValueParser right;
+
+    public BitwiseRightShiftParser(BitwiseRightShift expr) {
+        this.left = OperatorTools.buildParser(expr.getLeftExpression());
+        this.right = OperatorTools.buildParser(expr.getRightExpression());
+    }
+
+    @Override
+    public Object parse(SourceData sourceData, int rowIndex, Context context) {
+        try {
+            Object leftObj = this.left.parse(sourceData, rowIndex, context);
+            Object rightObj = this.right.parse(sourceData, rowIndex, context);
+            if (leftObj == null || rightObj == null) {
+                return null;
+            }
+            BigInteger leftValue = 
OperatorTools.parseBigDecimal(leftObj).toBigInteger();
+            String unsignedRight = 
Long.toUnsignedString(OperatorTools.parseBigDecimal(rightObj).longValue());
+            int cmp = new BigInteger(unsignedRight).compareTo(new 
BigInteger("65"));
+            if (cmp >= 0) {
+                return 
Long.toUnsignedString(leftValue.shiftRight(65).longValue());
+            } else {
+                return 
Long.toUnsignedString(leftValue.shiftRight(Integer.parseInt(unsignedRight)).longValue());
+            }
+        } catch (Exception e) {
+            log.error("Value parsing failed", e);
+            return null;
+        }
+    }
+}
diff --git 
a/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseXorParser.java
 
b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseXorParser.java
new file mode 100644
index 0000000000..3277bd91ed
--- /dev/null
+++ 
b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/BitwiseXorParser.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.inlong.sdk.transform.process.parser;
+
+import org.apache.inlong.sdk.transform.decode.SourceData;
+import org.apache.inlong.sdk.transform.process.Context;
+import org.apache.inlong.sdk.transform.process.operator.OperatorTools;
+
+import lombok.extern.slf4j.Slf4j;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseXor;
+
+import java.math.BigInteger;
+
+/**
+ * BitwiseXorParser
+ * 
+ */
+@Slf4j
+@TransformParser(values = BitwiseXor.class)
+public class BitwiseXorParser implements ValueParser {
+
+    private final ValueParser left;
+
+    private final ValueParser right;
+
+    public BitwiseXorParser(BitwiseXor expr) {
+        this.left = OperatorTools.buildParser(expr.getLeftExpression());
+        this.right = OperatorTools.buildParser(expr.getRightExpression());
+    }
+
+    @Override
+    public Object parse(SourceData sourceData, int rowIndex, Context context) {
+        try {
+            Object leftObj = this.left.parse(sourceData, rowIndex, context);
+            Object rightObj = this.right.parse(sourceData, rowIndex, context);
+            if (leftObj == null || rightObj == null) {
+                return null;
+            }
+            BigInteger leftValue = 
OperatorTools.parseBigDecimal(leftObj).toBigInteger();
+            BigInteger rightValue = 
OperatorTools.parseBigDecimal(rightObj).toBigInteger();
+            return 
Long.toUnsignedString(leftValue.xor(rightValue).longValue());
+        } catch (Exception e) {
+            log.error("Value parsing failed", e);
+            return null;
+        }
+    }
+}
diff --git 
a/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/SignParser.java
 
b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/SignParser.java
index ff97aadfdb..7a744f9015 100644
--- 
a/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/SignParser.java
+++ 
b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/SignParser.java
@@ -21,29 +21,43 @@ import org.apache.inlong.sdk.transform.decode.SourceData;
 import org.apache.inlong.sdk.transform.process.Context;
 import org.apache.inlong.sdk.transform.process.operator.OperatorTools;
 
+import lombok.extern.slf4j.Slf4j;
 import net.sf.jsqlparser.expression.SignedExpression;
 
 import java.math.BigDecimal;
 
 /**
  * SignParser
- * 
  */
+@Slf4j
 @TransformParser(values = SignedExpression.class)
 public class SignParser implements ValueParser {
 
-    private final Integer sign;
+    private final char sign;
     private final ValueParser number;
 
     public SignParser(SignedExpression expr) {
-        sign = expr.getSign() == '-' ? -1 : 1;
+        sign = expr.getSign();
         number = OperatorTools.buildParser(expr.getExpression());
     }
 
     @Override
     public Object parse(SourceData sourceData, int rowIndex, Context context) {
-        Object numberObject = number.parse(sourceData, rowIndex, context);
-        BigDecimal numberValue = OperatorTools.parseBigDecimal(numberObject);
-        return numberValue.multiply(new BigDecimal(sign));
+        try {
+            Object numberObject = number.parse(sourceData, rowIndex, context);
+            if (numberObject == null) {
+                return null;
+            }
+            BigDecimal numberValue = 
OperatorTools.parseBigDecimal(numberObject);
+            switch (sign) {
+                case '-':
+                    return numberValue.multiply(new BigDecimal(-1));
+                case '~':
+                    return 
Long.toUnsignedString(numberValue.toBigInteger().not().longValue());
+            }
+        } catch (Exception e) {
+            log.error("Value parsing failed", e);
+        }
+        return null;
     }
 }
diff --git 
a/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/TestTransformArithmeticFunctionsProcessor.java
 
b/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/TestTransformArithmeticFunctionsProcessor.java
index 4007a9a876..dcdb2d61d4 100644
--- 
a/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/TestTransformArithmeticFunctionsProcessor.java
+++ 
b/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/TestTransformArithmeticFunctionsProcessor.java
@@ -320,6 +320,181 @@ public class TestTransformArithmeticFunctionsProcessor {
         Assert.assertEquals("result=null", output4.get(0));
     }
 
+    @Test
+    public void testBitwiseInversionOperator() throws Exception {
+        String transformSql = null, data = null;
+        TransformConfig config = null;
+        TransformProcessor<String, String> processor = null;
+        List<String> output = null;
+
+        // case1: ~-4
+        transformSql = "select ~numeric1 from source";
+        config = new TransformConfig(transformSql);
+        processor = TransformProcessor
+                .create(config, 
SourceDecoderFactory.createCsvDecoder(csvSource),
+                        SinkEncoderFactory.createKvEncoder(kvSink));
+        data = "-4|3|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=3", output.get(0));
+
+        // case2: ~4
+        data = "4|3|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=18446744073709551611", output.get(0));
+
+        // case3: ~0
+        data = "0|3|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=18446744073709551615", output.get(0));
+
+        // case4: ~~-4
+        transformSql = "select ~(~numeric1) from source";
+        config = new TransformConfig(transformSql);
+        processor = TransformProcessor
+                .create(config, 
SourceDecoderFactory.createCsvDecoder(csvSource),
+                        SinkEncoderFactory.createKvEncoder(kvSink));
+        data = "-4|3|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=18446744073709551612", output.get(0));
+
+    }
+    @Test
+    public void testBitwiseAndOperator() throws Exception {
+        String transformSql = null, data = null;
+        TransformConfig config = null;
+        TransformProcessor<String, String> processor = null;
+        List<String> output = null;
+
+        // case1: 18446744073709551615 & -1
+        transformSql = "select numeric1 & numeric2 from source";
+        config = new TransformConfig(transformSql);
+        processor = TransformProcessor
+                .create(config, 
SourceDecoderFactory.createCsvDecoder(csvSource),
+                        SinkEncoderFactory.createKvEncoder(kvSink));
+        data = "18446744073709551615|-1|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=18446744073709551615", output.get(0));
+
+        // case2: 18446744073709551615 & 0
+        data = "18446744073709551615|0|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=0", output.get(0));
+    }
+    @Test
+    public void testBitwiseOrOperator() throws Exception {
+        String transformSql = null, data = null;
+        TransformConfig config = null;
+        TransformProcessor<String, String> processor = null;
+        List<String> output = null;
+
+        // case1: 18446744073709551615 | -1
+        transformSql = "select numeric1 | numeric2 from source";
+        config = new TransformConfig(transformSql);
+        processor = TransformProcessor
+                .create(config, 
SourceDecoderFactory.createCsvDecoder(csvSource),
+                        SinkEncoderFactory.createKvEncoder(kvSink));
+        data = "18446744073709551615|-1|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=18446744073709551615", output.get(0));
+
+        // case2: 4 | 3
+        data = "4|3|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=7", output.get(0));
+    }
+    @Test
+    public void testBitwiseRightShiftOperator() throws Exception {
+        String transformSql = null, data = null;
+        TransformConfig config = null;
+        TransformProcessor<String, String> processor = null;
+        List<String> output = null;
+
+        // case1: 4 >> -1
+        transformSql = "select numeric1 >> numeric2 from source";
+        config = new TransformConfig(transformSql);
+        processor = TransformProcessor
+                .create(config, 
SourceDecoderFactory.createCsvDecoder(csvSource),
+                        SinkEncoderFactory.createKvEncoder(kvSink));
+        data = "4|-1|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=0", output.get(0));
+
+        // case2: 9223372036854775808 >> 2
+        data = "9223372036854775808|2|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=2305843009213693952", output.get(0));
+
+        // case3: 9223372036854775808 >> 9223372036854775808
+        data = "9223372036854775808|9223372036854775808|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=0", output.get(0));
+    }
+    @Test
+    public void testBitwiseLeftShiftOperator() throws Exception {
+        String transformSql = null, data = null;
+        TransformConfig config = null;
+        TransformProcessor<String, String> processor = null;
+        List<String> output = null;
+
+        // case1: 9223372036854775807 << 1
+        transformSql = "select numeric1 << numeric2 from source";
+        config = new TransformConfig(transformSql);
+        processor = TransformProcessor
+                .create(config, 
SourceDecoderFactory.createCsvDecoder(csvSource),
+                        SinkEncoderFactory.createKvEncoder(kvSink));
+        data = "9223372036854775807|1|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=18446744073709551614", output.get(0));
+
+        // case2: 18446744073709551615 << 18446744073709551615
+        data = "18446744073709551615|18446744073709551615|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=0", output.get(0));
+
+        // case3: 9223372036854775807 << -1
+        data = "9223372036854775807|-1|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=0", output.get(0));
+    }
+    @Test
+    public void testBitwiseXorOperator() throws Exception {
+        String transformSql = null, data = null;
+        TransformConfig config = null;
+        TransformProcessor<String, String> processor = null;
+        List<String> output = null;
+
+        // case1: 4 ^ 3
+        transformSql = "select numeric1 ^ numeric2 from source";
+        config = new TransformConfig(transformSql);
+        processor = TransformProcessor
+                .create(config, 
SourceDecoderFactory.createCsvDecoder(csvSource),
+                        SinkEncoderFactory.createKvEncoder(kvSink));
+        data = "4|3|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=7", output.get(0));
+
+        // case2: 4 ^ -1
+        data = "4|-1|3";
+        output = processor.transform(data, new HashMap<>());
+        Assert.assertEquals(1, output.size());
+        Assert.assertEquals("result=18446744073709551611", output.get(0));
+    }
+
     @Test
     public void testRoundFunction() throws Exception {
         String transformSql = "select round(numeric1) from source";

Reply via email to