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 13c437946f [INLONG-12213][SDK][Transform] Support parsing SQL `NULL`
literal via `NullValueParser` (#12214)
13c437946f is described below
commit 13c437946fcf503aa5d9c5cb7d9e3ae135e1911b
Author: ChunLiang Lu <[email protected]>
AuthorDate: Wed Sep 16 15:02:50 2026 +0800
[INLONG-12213][SDK][Transform] Support parsing SQL `NULL` literal via
`NullValueParser` (#12214)
---
.../transform/process/parser/NullValueParser.java | 44 ++++++++++++++++++++++
.../function/condition/TestIfNullFunction.java | 11 ++++++
.../processor/TestJson2RowDataProcessor.java | 6 +--
3 files changed, 58 insertions(+), 3 deletions(-)
diff --git
a/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/NullValueParser.java
b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/NullValueParser.java
new file mode 100644
index 0000000000..62436a606a
--- /dev/null
+++
b/inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/NullValueParser.java
@@ -0,0 +1,44 @@
+/*
+ * 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 net.sf.jsqlparser.expression.NullValue;
+
+/**
+ * NullValueParser
+ * <p>
+ * Parses the SQL {@code NULL} literal (represented by {@link NullValue}) into
a
+ * constant Java {@code null}. This avoids {@code ParserTools} falling back to
+ * the {@code Column} cast, which previously caused a
+ * {@link ClassCastException} for expressions such as {@code ifnull(null, 3)}.
+ */
+@TransformParser(values = NullValue.class)
+public class NullValueParser implements ValueParser {
+
+ public NullValueParser(NullValue expr) {
+ // The NULL literal carries no value; nothing to store.
+ }
+
+ @Override
+ public Object parse(SourceData sourceData, int rowIndex, Context context) {
+ return null;
+ }
+}
diff --git
a/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/function/condition/TestIfNullFunction.java
b/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/function/condition/TestIfNullFunction.java
index 2afed87d43..6d8a1e6779 100644
---
a/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/function/condition/TestIfNullFunction.java
+++
b/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/function/condition/TestIfNullFunction.java
@@ -91,5 +91,16 @@ public class TestIfNullFunction extends
AbstractFunctionConditionTestBase {
output = processor.transform(data, new HashMap<>());
Assert.assertEquals(1, output.size());
Assert.assertEquals("result=", output.get(0));
+
+ // case6: ifnull(null, numeric2) -- true NULL literal
+ transformSql = "select ifnull(null,numeric2) from source";
+ config = new TransformConfig(transformSql);
+ processor = TransformProcessor
+ .create(config,
SourceDecoderFactory.createCsvDecoder(csvSource),
+ SinkEncoderFactory.createKvEncoder(kvSink));
+ data = "5|3|3|5";
+ output = processor.transform(data, new HashMap<>());
+ Assert.assertEquals(1, output.size());
+ Assert.assertEquals("result=3", output.get(0));
}
}
diff --git
a/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/processor/TestJson2RowDataProcessor.java
b/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/processor/TestJson2RowDataProcessor.java
index 4897f75014..2dd4ec495f 100644
---
a/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/processor/TestJson2RowDataProcessor.java
+++
b/inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/processor/TestJson2RowDataProcessor.java
@@ -45,7 +45,7 @@ public class TestJson2RowDataProcessor extends
AbstractProcessorTestBase {
List<FieldInfo> sinkFields = this.getTestFieldList("audit_data_time",
"session_begin_time", "session_id",
"business", "product_id", "channel",
"agent_id", "archive_p1", "archive_p2",
- "archive_p3", "archive_p4", "array_field");
+ "archive_p3", "archive_p4", "array_field", "from");
// sql
String transformSql = "select '' as audit_data_time,"
+ "$root.session_begin_time as session_begin_time,"
@@ -58,7 +58,7 @@ public class TestJson2RowDataProcessor extends
AbstractProcessorTestBase {
+ "$root.archive_p2 as archive_p2,"
+ "$root.archive_p3 as archive_p3,"
+ "$root.archive_p4 as archive_p4,"
- + "$root.array_field as array_field from source";
+ + "$root.array_field as array_field,$root.from as `from` from
source";
// case1
TransformProcessor<String, RowData> processor =
TransformProcessor.create(
new TransformConfig(transformSql),
@@ -67,7 +67,7 @@ public class TestJson2RowDataProcessor extends
AbstractProcessorTestBase {
String strJson =
"{\"session_id\":\"1782780884\",\"session_begin_time\":\"2026-06-30
08:54:56\",\"business\":\"pay\","
+
"\"product_id\":\"1314\",\"channel\":\"todo\",\"agent_id\":\"095d2\",\"archive_p1\":\"money\","
- +
"\"archive_p2\":\"product\",\"archive_p3\":\"short”\",\"archive_p4\":\"\",\"array_field\":[{\"isArray\":true}]}";
+ +
"\"archive_p2\":\"product\",\"archive_p3\":\"short”\",\"archive_p4\":\"\",\"array_field\":[{\"isArray\":true}],\"from\":\"china\"}";
List<RowData> output = processor.transform(strJson, new HashMap<>());
Assert.assertEquals(1, output.size());
Assert.assertEquals(output.get(0).getString(9).toString(), "short”");