luchunliang opened a new issue, #12213:
URL: https://github.com/apache/inlong/issues/12213

   ### Description
   
   This feature adds first-class support for the SQL `NULL` literal in 
Transform SDK expressions.
   
   Previously, a `SELECT` expression that used `NULL` directly (e.g. 
`ifnull(null, 3)`, `coalesce(null, col)`) failed during parser construction:
   
   ```
   java.lang.ClassCastException: net.sf.jsqlparser.expression.NullValue cannot 
be cast to net.sf.jsqlparser.schema.Column
        at 
org.apache.inlong.sdk.transform.process.parser.ParserTools.getTransformParser(ParserTools.java:72)
        at 
org.apache.inlong.sdk.transform.process.operator.OperatorTools.buildParser(OperatorTools.java:119)
        at 
org.apache.inlong.sdk.transform.process.function.condition.IfNullFunction.<init>(IfNullFunction.java:57)
   ```
   
   With this feature, the `NULL` literal is resolved to a constant Java `null`, 
enabling `ifnull(null, x)` / `coalesce(null, x)` / `concat_ws(..., null, ...)` 
and similar expressions to work as expected.
   
   
   ### Use case
   
   ### Component
   
   `inlong-sdk / transform-sdk`
   
   - `org.apache.inlong.sdk.transform.process.parser.NullValueParser` *(new)*
   - Test: 
`org.apache.inlong.sdk.transform.process.function.condition.TestIfNullFunction`
   ### Description
   
   This feature adds first-class support for the SQL `NULL` literal in 
Transform SDK expressions.
   
   Previously, a `SELECT` expression that used `NULL` directly (e.g. 
`ifnull(null, 3)`, `coalesce(null, col)`) failed during parser construction:
   
   ```
   java.lang.ClassCastException: net.sf.jsqlparser.expression.NullValue cannot 
be cast to net.sf.jsqlparser.schema.Column
        at 
org.apache.inlong.sdk.transform.process.parser.ParserTools.getTransformParser(ParserTools.java:72)
        at 
org.apache.inlong.sdk.transform.process.operator.OperatorTools.buildParser(OperatorTools.java:119)
        at 
org.apache.inlong.sdk.transform.process.function.condition.IfNullFunction.<init>(IfNullFunction.java:57)
   ```
   
   With this feature, the `NULL` literal is resolved to a constant Java `null`, 
enabling `ifnull(null, x)` / `coalesce(null, x)` / `concat_ws(..., null, ...)` 
and similar expressions to work as expected.
   
   ### Background
   
   `ParserTools.getTransformParser(Expression expr)` resolves parsers through a 
reflective scan that maps `Expression` sub-types to their parser classes 
(`parserMap`). Expression types that are not registered currently fall back to 
a `Column` cast:
   
   ```java
   Class<?> clazz = parserMap.get(expr.getClass());
   if (clazz == null) {
       return new ColumnParser((Column) expr);   // NULL literal hits here and 
crashes
   }
   ```
   
   The SQL `NULL` literal is parsed by JSqlParser as 
`net.sf.jsqlparser.expression.NullValue`, which is not a `Column`. Because no 
parser was registered for it, any `NULL` literal hit the fallback branch and 
raised a `ClassCastException`.
   
   ### Proposed Change
   
   Introduce a `NullValueParser` following the existing `StringParser` pattern:
   
   ```java
   @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;
       }
   }
   ```
   
   `@TransformParser(values = NullValue.class)` registers `NullValue.class` in 
`parserMap`, so `getTransformParser` resolves it through the reflective 
constructor branch, and `NULL` literals evaluate to constant `null`.
   
   ### Resulting Behavior
   
   - `ifnull(null, numeric2)` evaluates its first argument to `null`, so 
`IfNullFunction` falls back to the second argument as expected.
   - Other functions that receive a `NULL` literal as an argument (e.g. 
`coalesce`, `num_nulls`, `concat_ws`) no longer fail during parser construction.
   
   ### Tests
   
   Added a true-`NULL`-literal case to `TestIfNullFunction`:
   
   ```java
   // case6: ifnull(null, numeric2) -- true NULL literal
   transformSql = "select ifnull(null,numeric2) from source";
   data = "5|3|3|5";
   Assert.assertEquals("result=3", output.get(0));
   ```
   
   Verified: `Tests run: 1, Failures: 0, Errors: 0, Skipped: 0`.
   
   ### Backward Compatibility
   
   - Fully backward compatible.
   - No public API or method-signature change; only a new parser class is added.
   - Existing column / function / literal parsers are unaffected.
   
   ### Files Changed
   
   - 
`inlong-sdk/transform-sdk/src/main/java/org/apache/inlong/sdk/transform/process/parser/NullValueParser.java`
 *(new)*
   - 
`inlong-sdk/transform-sdk/src/test/java/org/apache/inlong/sdk/transform/process/function/condition/TestIfNullFunction.java`
   
   
   ### Are you willing to submit PR?
   
   - [x] Yes, I am willing to submit a PR!
   
   ### Code of Conduct
   
   - [x] I agree to follow this project's [Code of 
Conduct](https://www.apache.org/foundation/policies/conduct)
   


-- 
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]

Reply via email to