Maximilian Michels created FLINK-37245: ------------------------------------------
Summary: RowData#createFieldGetter can resurrect null values for non-null fields Key: FLINK-37245 URL: https://issues.apache.org/jira/browse/FLINK-37245 Project: Flink Issue Type: Bug Components: Table SQL / API, Table SQL / Runtime Affects Versions: 1.19.1, 1.20.0 Reporter: Maximilian Michels {{RowData#createFieldGetter}} is the go-to method for creating field getters for a given field type and position. The method {{FieldGetter#getFieldOrNull}} suggests that null is returned if the field has been nulled. But that is not always the case. When using BinaryRowData with a non-null field, which has been set to null, a call to {{FieldGetter#getFieldOrNull}} will return a non-null value, interpreting whatever bytes are backing the field as an actual value instead of null. Example: {noformat} public static void main(String[] args) { IntType nullableIntType = new IntType(true); IntType nonNullableIntType = new IntType(false); RowDataSerializer rowDataSerializer = new RowDataSerializer( nullableIntType, nonNullableIntType ); BinaryRowData binaryRow = rowDataSerializer.toBinaryRow(GenericRowData.of(null, null)); RowData.FieldGetter fieldGetter1 = RowData.createFieldGetter(nullableIntType, 0); RowData.FieldGetter fieldGetter2 = RowData.createFieldGetter(nonNullableIntType, 1); System.out.println(fieldGetter1.getFieldOrNull(binaryRow)); System.out.println(fieldGetter2.getFieldOrNull(binaryRow)); } {noformat} Output is: {noformat} null 0 {noformat} The expected output would be that the second non-null field also returns null, or raises a NullPointerException directly. That's not the case because {{RowData#createFieldGetter}} only checks for null values (via a call to {{{}Rowdata#isNullAt(pos){}}}) when the type is nullable (see [https://github.com/apache/flink/blob/b86fdf906c06af8fc2841bca3d98dd3944bb5031/flink-table/flink-table-common/src/main/java/org/apache/flink/table/data/RowData.java#L289]). It seems fair to always check for null fields, instead of deferring this easy to forget check to the caller. -- This message was sent by Atlassian Jira (v8.20.10#820010)