This is an automated email from the ASF dual-hosted git repository.

dianfu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git


The following commit(s) were added to refs/heads/master by this push:
     new f9220300856 [FLINK-41001][model] Accept compatible string inputs in 
the OpenAI provider (#29486)
f9220300856 is described below

commit f922030085606c220430f97a0efb3254d274b49e
Author: Liu Liu <[email protected]>
AuthorDate: Thu Oct 15 22:23:42 2026 +0800

    [FLINK-41001][model] Accept compatible string inputs in the OpenAI provider 
(#29486)
    
    Generated-by: Codex (GPT-6)
---
 .../model/openai/AbstractOpenAIModelFunction.java  | 15 ++++-
 .../flink/model/openai/OpenAIChatModelTest.java    | 67 ++++++++++++++++++++--
 .../model/openai/OpenAIEmbeddingModelTest.java     | 23 ++++++++
 3 files changed, 98 insertions(+), 7 deletions(-)

diff --git 
a/flink-models/flink-model-openai/src/main/java/org/apache/flink/model/openai/AbstractOpenAIModelFunction.java
 
b/flink-models/flink-model-openai/src/main/java/org/apache/flink/model/openai/AbstractOpenAIModelFunction.java
index 193da8a72e7..fa9cb1ef3a5 100644
--- 
a/flink-models/flink-model-openai/src/main/java/org/apache/flink/model/openai/AbstractOpenAIModelFunction.java
+++ 
b/flink-models/flink-model-openai/src/main/java/org/apache/flink/model/openai/AbstractOpenAIModelFunction.java
@@ -36,6 +36,7 @@ import org.apache.flink.table.functions.AsyncPredictFunction;
 import org.apache.flink.table.functions.FunctionContext;
 import org.apache.flink.table.types.DataType;
 import org.apache.flink.table.types.logical.LogicalType;
+import org.apache.flink.table.types.logical.LogicalTypeFamily;
 import org.apache.flink.table.types.logical.VarCharType;
 import org.apache.flink.util.ExceptionUtils;
 import org.apache.flink.util.Preconditions;
@@ -56,6 +57,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 import java.util.function.Function;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 import static org.apache.flink.configuration.description.TextElement.text;
@@ -95,7 +97,8 @@ public abstract class AbstractOpenAIModelFunction extends 
AsyncPredictFunction {
         validateSingleColumnSchema(
                 factoryContext.getCatalogModel().getResolvedInputSchema(),
                 new VarCharType(VarCharType.MAX_LENGTH),
-                "input");
+                "input",
+                type -> type.is(LogicalTypeFamily.CHARACTER_STRING));
 
         this.outputColumnNames =
                 
factoryContext.getCatalogModel().getResolvedOutputSchema().getColumnNames();
@@ -142,6 +145,14 @@ public abstract class AbstractOpenAIModelFunction extends 
AsyncPredictFunction {
 
     protected void validateSingleColumnSchema(
             ResolvedSchema schema, LogicalType expectedType, String 
inputOrOutput) {
+        validateSingleColumnSchema(schema, expectedType, inputOrOutput, 
expectedType::equals);
+    }
+
+    private void validateSingleColumnSchema(
+            ResolvedSchema schema,
+            LogicalType expectedType,
+            String inputOrOutput,
+            Predicate<LogicalType> supportedType) {
         List<Column> columns = schema.getColumns();
         List<String> physicalColumnNames =
                 columns.stream()
@@ -156,7 +167,7 @@ public abstract class AbstractOpenAIModelFunction extends 
AsyncPredictFunction {
         }
 
         Column column = schema.getColumn(physicalColumnNames.get(0)).get();
-        if (!expectedType.equals(column.getDataType().getLogicalType())) {
+        if (!supportedType.test(column.getDataType().getLogicalType())) {
             throw new IllegalArgumentException(
                     String.format(
                             "%s column %s should be %s, but is a %s.",
diff --git 
a/flink-models/flink-model-openai/src/test/java/org/apache/flink/model/openai/OpenAIChatModelTest.java
 
b/flink-models/flink-model-openai/src/test/java/org/apache/flink/model/openai/OpenAIChatModelTest.java
index 835ac2e7beb..03c0cb24380 100644
--- 
a/flink-models/flink-model-openai/src/test/java/org/apache/flink/model/openai/OpenAIChatModelTest.java
+++ 
b/flink-models/flink-model-openai/src/test/java/org/apache/flink/model/openai/OpenAIChatModelTest.java
@@ -19,13 +19,17 @@ package org.apache.flink.model.openai;
 
 import org.apache.flink.configuration.Configuration;
 import org.apache.flink.table.api.DataTypes;
+import org.apache.flink.table.api.ModelDescriptor;
 import org.apache.flink.table.api.Schema;
+import org.apache.flink.table.api.Table;
 import org.apache.flink.table.api.TableEnvironment;
 import org.apache.flink.table.api.TableResult;
 import org.apache.flink.table.api.internal.TableEnvironmentImpl;
 import org.apache.flink.table.catalog.CatalogManager;
 import org.apache.flink.table.catalog.CatalogModel;
 import org.apache.flink.table.catalog.ObjectIdentifier;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.types.ColumnList;
 import org.apache.flink.types.Row;
 import org.apache.flink.types.variant.Variant;
 
@@ -42,6 +46,8 @@ import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -49,6 +55,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.stream.Stream;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -246,6 +253,46 @@ public class OpenAIChatModelTest {
         assertThat(result).isEmpty();
     }
 
+    @ParameterizedTest
+    @MethodSource("stringInputTypes")
+    public void testStringInputSchema(final DataType inputType) {
+        final Schema inputSchema = Schema.newBuilder().column("input", 
inputType).build();
+        final Table input =
+                tEnv.fromValues(
+                        DataTypes.ROW(DataTypes.FIELD("input", inputType)), 
Row.of("hello"));
+        tEnv.createTemporaryView("TypedInput", input);
+        createModel(inputSchema, OUTPUT_SCHEMA);
+
+        assertThat(
+                        tEnv.sqlQuery(
+                                        String.format(
+                                                "SELECT content FROM 
ML_PREDICT(TABLE TypedInput, MODEL %s, DESCRIPTOR(`input`))",
+                                                MODEL_NAME))
+                                .explain())
+                .isNotBlank();
+
+        final ModelDescriptor.Builder descriptor =
+                ModelDescriptor.forProvider("openai")
+                        .inputSchema(inputSchema)
+                        .outputSchema(OUTPUT_SCHEMA);
+        modelOptions.forEach(descriptor::option);
+        assertThat(
+                        tEnv.fromModel(descriptor.build())
+                                .predict(input, ColumnList.of("input"))
+                                .explain())
+                .isNotBlank();
+    }
+
+    private static Stream<DataType> stringInputTypes() {
+        return Stream.of(
+                DataTypes.CHAR(14),
+                DataTypes.CHAR(14).notNull(),
+                DataTypes.VARCHAR(32),
+                DataTypes.VARCHAR(32).notNull(),
+                DataTypes.STRING(),
+                DataTypes.STRING().notNull());
+    }
+
     @Test
     public void testInvalidInputSchema() {
         Schema inputSchemaWithInvalidColumnType =
@@ -263,10 +310,11 @@ public class OpenAIChatModelTest {
                 .hasMessageContainingAll("input", "DOUBLE", "STRING");
     }
 
-    @Test
-    public void testInvalidOutputSchema() {
-        Schema outputSchemaWithInvalidColumnType =
-                Schema.newBuilder().column("output", 
DataTypes.DOUBLE()).build();
+    @ParameterizedTest
+    @MethodSource("invalidOutputTypes")
+    public void testInvalidOutputSchema(final DataType outputType) {
+        final Schema outputSchemaWithInvalidColumnType =
+                Schema.newBuilder().column("output", outputType).build();
 
         createModel(INPUT_SCHEMA, outputSchemaWithInvalidColumnType);
         assertThatThrownBy(
@@ -277,7 +325,16 @@ public class OpenAIChatModelTest {
                                                 MODEL_NAME)))
                 .rootCause()
                 .isInstanceOf(IllegalArgumentException.class)
-                .hasMessageContainingAll("output", "DOUBLE", "STRING");
+                .hasMessageContainingAll(
+                        "output", 
outputType.getLogicalType().asSummaryString(), "STRING");
+    }
+
+    private static Stream<DataType> invalidOutputTypes() {
+        return Stream.of(
+                DataTypes.DOUBLE(),
+                DataTypes.CHAR(14),
+                DataTypes.VARCHAR(32),
+                DataTypes.STRING().notNull());
     }
 
     private void createModel() {
diff --git 
a/flink-models/flink-model-openai/src/test/java/org/apache/flink/model/openai/OpenAIEmbeddingModelTest.java
 
b/flink-models/flink-model-openai/src/test/java/org/apache/flink/model/openai/OpenAIEmbeddingModelTest.java
index 090e82e4922..ef420a8e873 100644
--- 
a/flink-models/flink-model-openai/src/test/java/org/apache/flink/model/openai/OpenAIEmbeddingModelTest.java
+++ 
b/flink-models/flink-model-openai/src/test/java/org/apache/flink/model/openai/OpenAIEmbeddingModelTest.java
@@ -19,13 +19,17 @@ package org.apache.flink.model.openai;
 
 import org.apache.flink.configuration.Configuration;
 import org.apache.flink.table.api.DataTypes;
+import org.apache.flink.table.api.ModelDescriptor;
 import org.apache.flink.table.api.Schema;
+import org.apache.flink.table.api.Table;
 import org.apache.flink.table.api.TableEnvironment;
 import org.apache.flink.table.api.TableResult;
 import org.apache.flink.table.api.internal.TableEnvironmentImpl;
 import org.apache.flink.table.catalog.CatalogManager;
 import org.apache.flink.table.catalog.CatalogModel;
 import org.apache.flink.table.catalog.ObjectIdentifier;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.types.ColumnList;
 import org.apache.flink.types.Row;
 
 import 
org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.JsonNode;
@@ -229,6 +233,25 @@ public class OpenAIEmbeddingModelTest {
         assertThat(result).isEmpty();
     }
 
+    @Test
+    public void testBoundedNonNullStringInputSchema() {
+        final DataType inputType = DataTypes.VARCHAR(32).notNull();
+        final Table input =
+                tEnv.fromValues(
+                        DataTypes.ROW(DataTypes.FIELD("input", inputType)), 
Row.of("hello"));
+        final ModelDescriptor.Builder descriptor =
+                ModelDescriptor.forProvider("openai")
+                        .inputSchema(Schema.newBuilder().column("input", 
inputType).build())
+                        .outputSchema(OUTPUT_SCHEMA);
+        modelOptions.forEach(descriptor::option);
+
+        assertThat(
+                        tEnv.fromModel(descriptor.build())
+                                .predict(input, ColumnList.of("input"))
+                                .explain())
+                .isNotBlank();
+    }
+
     @Test
     public void testInvalidInputSchema() {
         CatalogManager catalogManager = ((TableEnvironmentImpl) 
tEnv).getCatalogManager();

Reply via email to