This is an automated email from the ASF dual-hosted git repository. dockerzhang 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 86635a83ba [INLONG-11123][SDK] Transform SQL supports conv function (#11141) 86635a83ba is described below commit 86635a83ba11cb9996640d277363a37e2ccd10f1 Author: Zkplo <87751516+zk...@users.noreply.github.com> AuthorDate: Fri Sep 20 17:26:55 2024 +0800 [INLONG-11123][SDK] Transform SQL supports conv function (#11141) Co-authored-by: ZKpLo <14148880+zk...@user.noreply.gitee.com> --- .../process/function/RadixConvertFunction.java | 97 ++++++++++++++++++++++ .../arithmetic/testRadixConvertFunction.java | 87 +++++++++++++++++++ 2 files changed, 184 insertions(+) diff --git a/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/function/RadixConvertFunction.java b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/function/RadixConvertFunction.java new file mode 100644 index 0000000000..f9b3cac523 --- /dev/null +++ b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/function/RadixConvertFunction.java @@ -0,0 +1,97 @@ +/* + * 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.function; + +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 org.apache.inlong.sdk.transform.process.parser.ValueParser; + +import lombok.extern.slf4j.Slf4j; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.Function; + +import java.math.BigInteger; +import java.util.List; + +/** + * RadixConvertFunction -> radix_convert(N,from_base,to_base) + * description: Converts numbers between different number bases. The minimum base is 2 and the maximum base is 36. + * If from_base is a negative number, N is regarded as a signed number. Otherwise, N is treated as + * unsigned. This function works with 64-bit precision. + * - returns NULL if any of its arguments are NULL. + * - returns conversion results otherwise. + */ +@Slf4j +@TransformFunction(names = {"radix_convert"}) +public class RadixConvertFunction implements ValueParser { + + private final ValueParser numParser; + private final ValueParser fromBaseParser; + private final ValueParser toBaseParser; + + public RadixConvertFunction(Function expr) { + List<Expression> expressions = expr.getParameters().getExpressions(); + numParser = OperatorTools.buildParser(expressions.get(0)); + fromBaseParser = OperatorTools.buildParser(expressions.get(1)); + toBaseParser = OperatorTools.buildParser(expressions.get(2)); + } + + @Override + public Object parse(SourceData sourceData, int rowIndex, Context context) { + Object numObj = numParser.parse(sourceData, rowIndex, context); + Object fromBaseObj = fromBaseParser.parse(sourceData, rowIndex, context); + Object toBaseObj = toBaseParser.parse(sourceData, rowIndex, context); + if (numObj == null || fromBaseObj == null || toBaseObj == null) { + return null; + } + String num = OperatorTools.parseString(numObj); + int fromBase = Integer.parseInt(fromBaseObj.toString()); + int toBase = Integer.parseInt(toBaseObj.toString()); + return conv(num, fromBase, toBase); + } + + /** + * Converts a number from one base to another. + * + * @param number The number to be converted (as a string or integer). + * @param fromBase The base of the input number. + * @param toBase The base to which the number should be converted. + * @return The converted number as a string, or null if input is invalid. + */ + public static String conv(String number, int fromBase, int toBase) { + if (!checkRange(fromBase) || !checkRange(toBase)) { + return null; + } + try { + BigInteger num = new BigInteger(number, Math.abs(fromBase)); + if (fromBase > 0) { + return num.toString(Math.abs(toBase)).toUpperCase(); + } else { + return new BigInteger(Long.toUnsignedString(num.longValue()), 10) + .toString(Math.abs(toBase)).toUpperCase(); + } + } catch (NumberFormatException e) { + return null; + } + } + + private static boolean checkRange(int base) { + return Math.abs(base) >= 2 && Math.abs(base) <= 36; + } +} diff --git a/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/function/arithmetic/testRadixConvertFunction.java b/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/function/arithmetic/testRadixConvertFunction.java new file mode 100644 index 0000000000..3b7cdef93a --- /dev/null +++ b/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/function/arithmetic/testRadixConvertFunction.java @@ -0,0 +1,87 @@ +/* + * 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.function.arithmetic; + +import org.apache.inlong.sdk.transform.decode.SourceDecoderFactory; +import org.apache.inlong.sdk.transform.encode.SinkEncoderFactory; +import org.apache.inlong.sdk.transform.pojo.TransformConfig; +import org.apache.inlong.sdk.transform.process.TransformProcessor; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.List; + +public class testRadixConvertFunction extends AbstractFunctionArithmeticTestBase { + + @Test + public void testRadixConvertFunction() throws Exception { + String transformSql = null, data = null; + TransformConfig config = null; + TransformProcessor<String, String> processor = null; + List<String> output = null; + + transformSql = "select radix_convert(numeric1,numeric2,numeric3) from source"; + config = new TransformConfig(transformSql); + processor = TransformProcessor + .create(config, SourceDecoderFactory.createCsvDecoder(csvSource), + SinkEncoderFactory.createKvEncoder(kvSink)); + // case1: radix_convert('a',16,2) + data = "a|16|2|5"; + output = processor.transform(data, new HashMap<>()); + Assert.assertEquals(1, output.size()); + Assert.assertEquals("result=1010", output.get(0)); + + // case2: radix_convert('6E',18,8) + data = "6E|18|8|5"; + output = processor.transform(data, new HashMap<>()); + Assert.assertEquals(1, output.size()); + Assert.assertEquals("result=172", output.get(0)); + + // case3: radix_convert(-17,10,-18) + data = "-17|10|-18|5"; + output = processor.transform(data, new HashMap<>()); + Assert.assertEquals(1, output.size()); + Assert.assertEquals("result=-H", output.get(0)); + + // case4: radix_convert(-17,-10,18) + data = "-17|-10|18|5"; + output = processor.transform(data, new HashMap<>()); + Assert.assertEquals(1, output.size()); + Assert.assertEquals("result=2D3FGB0B9CG4BD1H", output.get(0)); + + // case5: radix_convert(-17,-10,18) + data = "-17|-10|18|5"; + output = processor.transform(data, new HashMap<>()); + Assert.assertEquals(1, output.size()); + Assert.assertEquals("result=2D3FGB0B9CG4BD1H", output.get(0)); + + // case6: radix_convert(17,-10,18) + data = "17|-10|18|5"; + output = processor.transform(data, new HashMap<>()); + Assert.assertEquals(1, output.size()); + Assert.assertEquals("result=H", output.get(0)); + + // case7: radix_convert(17,10,18) + data = "17|10|18|5"; + output = processor.transform(data, new HashMap<>()); + Assert.assertEquals(1, output.size()); + Assert.assertEquals("result=H", output.get(0)); + } +}