Skip to content

Commit 4d41c95

Browse files
committed
[FLINK-37913][table] make class field and key fields not nullable
1 parent e36a9bb commit 4d41c95

File tree

3 files changed

+42
-35
lines changed

3 files changed

+42
-35
lines changed

flink-table/flink-table-common/src/main/java/org/apache/flink/table/types/inference/strategies/ObjectOfInputTypeStrategy.java

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,9 @@ private static void validateClassInput(
101101
final LogicalType classArgumentType = firstArgumentDataType.getLogicalType();
102102

103103
final String errorMessage =
104-
"The first argument must be a STRING/VARCHAR type representing the class name.";
105-
if (!classArgumentType.is(LogicalTypeFamily.CHARACTER_STRING)) {
104+
"The first argument must be a non-nullable STRING/VARCHAR type representing the class name.";
105+
if (classArgumentType.isNullable()
106+
|| !classArgumentType.is(LogicalTypeFamily.CHARACTER_STRING)) {
106107
throw new ValidationException(errorMessage);
107108
}
108109

@@ -129,23 +130,25 @@ private static void validateFieldNameArgument(
129130
throw new ValidationException(
130131
"The field key at position "
131132
+ keyIndex
132-
+ " must be a STRING/VARCHAR type, but was "
133+
+ " must be a non-nullable STRING/VARCHAR type, but was "
133134
+ logicalType.asSummaryString()
134135
+ ".");
135136
}
137+
138+
if (logicalType.isNullable()) {
139+
throw new ValidationException(
140+
"The field key at position "
141+
+ keyIndex
142+
+ " must be a non-nullable STRING/VARCHAR type.");
143+
}
144+
136145
final String fieldName =
137146
callContext
138147
.getArgumentValue(idx, String.class)
139-
.orElseThrow(
140-
() ->
141-
new ValidationException(
142-
"Field name at position "
143-
+ keyIndex
144-
+ " must be a non null STRING/VARCHAR type."));
145-
148+
.orElseThrow(IllegalStateException::new);
146149
if (!fieldNames.add(fieldName)) {
147150
throw new ValidationException(
148-
"The field name " + fieldName + " at position " + keyIndex + " is repeated.");
151+
"The field name '" + fieldName + "' at position " + keyIndex + " is repeated.");
149152
}
150153
}
151154

flink-table/flink-table-common/src/test/java/org/apache/flink/table/types/inference/strategies/ObjectOfInputTypeStrategyTest.java

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,43 +40,47 @@ protected Stream<TestSpec> testData() {
4040
return Stream.of(
4141
// Test valid OBJECT_OF with no fields and values
4242
TestSpec.forStrategy("Valid OBJECT_OF with only class", OBJECT_OF_INPUT_STRATEGY)
43-
.calledWithArgumentTypes(DataTypes.STRING())
43+
.calledWithArgumentTypes(DataTypes.STRING().notNull())
4444
.calledWithLiteralAt(0, USER_CLASS_PATH)
4545
.expectSignature("f(STRING, [STRING, ANY]*...)")
46-
.expectArgumentTypes(DataTypes.STRING()),
46+
.expectArgumentTypes(DataTypes.STRING().notNull()),
4747

4848
// Test valid number of arguments (odd number >= 1)
4949
TestSpec.forStrategy(
5050
"Valid OBJECT_OF with class and one field and value",
5151
OBJECT_OF_INPUT_STRATEGY)
5252
.calledWithArgumentTypes(
53-
DataTypes.STRING(), DataTypes.STRING(), DataTypes.INT())
53+
DataTypes.STRING().notNull(),
54+
DataTypes.STRING().notNull(),
55+
DataTypes.INT())
5456
.calledWithLiteralAt(0, USER_CLASS_PATH)
5557
.calledWithLiteralAt(1, "field1")
5658
.expectArgumentTypes(
57-
DataTypes.STRING(), DataTypes.STRING(), DataTypes.INT()),
59+
DataTypes.STRING().notNull(),
60+
DataTypes.STRING().notNull(),
61+
DataTypes.INT()),
5862

5963
// Test with structured fields
6064
TestSpec.forStrategy(
6165
"Valid OBJECT_OF with multiple fields", OBJECT_OF_INPUT_STRATEGY)
6266
.calledWithArgumentTypes(
63-
DataTypes.STRING(), // implementation class
64-
DataTypes.STRING(), // field1 name
67+
DataTypes.STRING().notNull(), // implementation class
68+
DataTypes.STRING().notNull(), // field1 name
6569
DataTypes.STRUCTURED(
6670
"c1",
6771
DataTypes.FIELD("f1", DataTypes.INT())), // field1 value
68-
DataTypes.STRING(), // field2 name
72+
DataTypes.STRING().notNull(), // field2 name
6973
DataTypes.STRUCTURED(
7074
"c2",
7175
DataTypes.FIELD("f1", DataTypes.FLOAT()))) // field2 value
7276
.calledWithLiteralAt(0, USER_CLASS_PATH)
7377
.calledWithLiteralAt(1, "field1")
7478
.calledWithLiteralAt(3, "field2")
7579
.expectArgumentTypes(
76-
DataTypes.STRING(),
77-
DataTypes.STRING(),
80+
DataTypes.STRING().notNull(),
81+
DataTypes.STRING().notNull(),
7882
DataTypes.STRUCTURED("c1", DataTypes.FIELD("f1", DataTypes.INT())),
79-
DataTypes.STRING(),
83+
DataTypes.STRING().notNull(),
8084
DataTypes.STRUCTURED(
8185
"c2", DataTypes.FIELD("f1", DataTypes.FLOAT()))),
8286

@@ -87,15 +91,15 @@ protected Stream<TestSpec> testData() {
8791
.calledWithArgumentTypes(DataTypes.NULL())
8892
.calledWithLiteralAt(0, null)
8993
.expectErrorMessage(
90-
"The first argument must be a STRING/VARCHAR type representing the class name."),
94+
"The first argument must be a non-nullable STRING/VARCHAR type representing the class name."),
9195

9296
// Invalid test case - even number of arguments
9397
TestSpec.forStrategy(
9498
"Invalid OBJECT_OF with even number of arguments",
9599
OBJECT_OF_INPUT_STRATEGY)
96100
.calledWithArgumentTypes(
97-
DataTypes.STRING(), // implementation class
98-
DataTypes.STRING()) // only field name, missing value
101+
DataTypes.STRING().notNull(), // implementation class
102+
DataTypes.STRING().notNull()) // only field name, missing value
99103
.calledWithLiteralAt(0, USER_CLASS_PATH)
100104
.expectErrorMessage("Invalid number of arguments."),
101105

@@ -112,38 +116,38 @@ protected Stream<TestSpec> testData() {
112116
.calledWithLiteralAt(0, 72)
113117
.expectArgumentTypes(DataTypes.INT())
114118
.expectErrorMessage(
115-
"The first argument must be a STRING/VARCHAR type representing the class name."),
119+
"The first argument must be a non-nullable STRING/VARCHAR type representing the class name."),
116120

117121
// Invalid test case - field name not a string
118122
TestSpec.forStrategy(
119123
"OBJECT_OF with non-string field name", OBJECT_OF_INPUT_STRATEGY)
120124
.calledWithArgumentTypes(
121-
DataTypes.STRING(), // implementation class
125+
DataTypes.STRING().notNull(), // implementation class
122126
DataTypes.INT(), // field name (not a string)
123127
DataTypes.INT()) // field value
124128
.calledWithLiteralAt(0, USER_CLASS_PATH)
125129
.calledWithLiteralAt(1, 5)
126130
.expectArgumentTypes(DataTypes.STRING(), DataTypes.INT(), DataTypes.INT())
127131
.expectErrorMessage(
128-
"The field key at position 2 must be a STRING/VARCHAR type, but was INT."),
132+
"The field key at position 2 must be a non-nullable STRING/VARCHAR type, but was INT."),
129133

130134
// Invalid test case - repeated field names
131135
TestSpec.forStrategy(
132136
"OBJECT_OF with repeated field names", OBJECT_OF_INPUT_STRATEGY)
133137
.calledWithArgumentTypes(
134-
DataTypes.STRING(),
135-
DataTypes.STRING(),
138+
DataTypes.STRING().notNull(),
139+
DataTypes.STRING().notNull(),
136140
DataTypes.INT(),
137-
DataTypes.STRING(),
141+
DataTypes.STRING().notNull(),
138142
DataTypes.INT())
139143
.calledWithLiteralAt(0, USER_CLASS_PATH)
140144
.calledWithLiteralAt(1, "field1")
141145
.calledWithLiteralAt(3, "field1")
142146
.expectArgumentTypes(
143-
DataTypes.STRING(),
144-
DataTypes.STRING(),
147+
DataTypes.STRING().notNull(),
148+
DataTypes.STRING().notNull(),
145149
DataTypes.INT(),
146-
DataTypes.STRING(),
150+
DataTypes.STRING().notNull(),
147151
DataTypes.INT())
148152
.expectErrorMessage("The field name 'field1' at position 4 is repeated."));
149153
}

flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/StructuredFunctionsITCase.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,11 @@ private static Stream<TestSetSpec> objectOfTestCases() {
142142
"OBJECT_OF('"
143143
+ Type1.class.getName()
144144
+ "', CAST(NULL AS STRING), 42, 'b', 'Bob')",
145-
"Field name at position 2 must be a non null STRING/VARCHAR type.")
145+
"The field key at position 2 must be a non-nullable STRING/VARCHAR type.")
146146
// Invalid Test - first argument is type string but null
147147
.testSqlValidationError(
148148
"OBJECT_OF(CAST(NULL AS STRING), 'a', '12', 'b', 'Alice')",
149-
"The first argument must be a STRING/VARCHAR type representing the class name."));
149+
"The first argument must be a non-nullable STRING/VARCHAR type representing the class name."));
150150
}
151151

152152
// --------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)