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

gustavodemorais 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 d6b7fad86b5 [FLINK-39915][table] Reject mixing positional and named 
function arguments
d6b7fad86b5 is described below

commit d6b7fad86b50d88843898adfc3dfc6c0bb52c291
Author: Gustavo de Morais <[email protected]>
AuthorDate: Sat Jun 13 13:48:12 2026 +0200

    [FLINK-39915][table] Reject mixing positional and named function arguments
    
    This closes #28399.
---
 .../planner/calcite/FlinkCalciteSqlValidator.java  | 22 +++++++++++++++
 .../calcite/FlinkCalciteSqlValidatorTest.java      | 32 ++++++++++++++++++++++
 .../plan/stream/sql/ProcessTableFunctionTest.java  |  5 ++++
 3 files changed, 59 insertions(+)

diff --git 
a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidator.java
 
b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidator.java
index 77a1634fa0b..6d8ad8d2591 100644
--- 
a/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidator.java
+++ 
b/flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidator.java
@@ -380,6 +380,7 @@ public final class FlinkCalciteSqlValidator extends 
FlinkSqlParsingValidator {
         }
 
         final SqlBasicCall call = (SqlBasicCall) node;
+        checkNoNamedAndPositionalMixedArgs(call);
 
         // Special case for MODEL
         if (node instanceof SqlExplicitModelCall) {
@@ -432,6 +433,27 @@ public final class FlinkCalciteSqlValidator extends 
FlinkSqlParsingValidator {
         return rewritten;
     }
 
+    /** Mixing positional and named arguments is not supported and crashes 
operand permutation. */
+    private static void checkNoNamedAndPositionalMixedArgs(SqlBasicCall call) {
+        if (!(call.getOperator() instanceof SqlFunction)) {
+            return;
+        }
+        final List<SqlNode> operands = call.getOperandList();
+        final boolean anyNamed =
+                operands.stream()
+                        .anyMatch(op -> op != null && op.getKind() == 
SqlKind.ARGUMENT_ASSIGNMENT);
+        final boolean anyPositional =
+                operands.stream()
+                        .anyMatch(op -> op != null && op.getKind() != 
SqlKind.ARGUMENT_ASSIGNMENT);
+        if (anyNamed && anyPositional) {
+            throw new ValidationException(
+                    "Cannot mix positional and named arguments when calling 
function '"
+                            + call.getOperator().getName()
+                            + "'. Use either all positional arguments or all 
named arguments "
+                            + "(e.g. arg => value).");
+        }
+    }
+
     @Override
     public SqlNode maybeCast(SqlNode node, RelDataType currentType, 
RelDataType desiredType) {
         return super.maybeCast(node, currentType, desiredType);
diff --git 
a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidatorTest.java
 
b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidatorTest.java
index 7da22c97d5e..831b3b6ecc4 100644
--- 
a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidatorTest.java
+++ 
b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/calcite/FlinkCalciteSqlValidatorTest.java
@@ -18,9 +18,13 @@
 
 package org.apache.flink.table.planner.calcite;
 
+import org.apache.flink.table.annotation.ArgumentHint;
+import org.apache.flink.table.annotation.DataTypeHint;
+import org.apache.flink.table.annotation.FunctionHint;
 import org.apache.flink.table.api.DataTypes;
 import org.apache.flink.table.api.Schema;
 import org.apache.flink.table.api.ValidationException;
+import org.apache.flink.table.functions.ScalarFunction;
 import org.apache.flink.table.planner.utils.PlannerMocks;
 
 import org.junit.jupiter.api.Test;
@@ -138,4 +142,32 @@ class FlinkCalciteSqlValidatorTest {
                 .hasMessageContaining(
                         "UPSERT INTO statement is not supported. Please use 
INSERT INTO instead.");
     }
+
+    @Test
+    void testMixedPositionalAndNamedArguments() {
+        plannerMocks
+                .getFunctionCatalog()
+                .registerTemporarySystemFunction("myFunc", new 
NamedArgsScalarFunction(), false);
+
+        assertDoesNotThrow(() -> plannerMocks.getParser().parse("SELECT 
myFunc(1, 2) FROM t1"));
+        assertDoesNotThrow(
+                () -> plannerMocks.getParser().parse("SELECT myFunc(in1 => 1, 
in2 => 2) FROM t1"));
+        assertThatThrownBy(
+                        () -> plannerMocks.getParser().parse("SELECT myFunc(1, 
in2 => 2) FROM t1"))
+                .isInstanceOf(ValidationException.class)
+                .hasMessageContaining("Cannot mix positional and named 
arguments");
+    }
+
+    /** Scalar function with named arguments for the mixed-argument validation 
test. */
+    public static class NamedArgsScalarFunction extends ScalarFunction {
+        @FunctionHint(
+                output = @DataTypeHint("INT"),
+                arguments = {
+                    @ArgumentHint(name = "in1", type = @DataTypeHint("INT")),
+                    @ArgumentHint(name = "in2", type = @DataTypeHint("INT"))
+                })
+        public Integer eval(Integer in1, Integer in2) {
+            return null;
+        }
+    }
 }
diff --git 
a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/stream/sql/ProcessTableFunctionTest.java
 
b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/stream/sql/ProcessTableFunctionTest.java
index 411b6fc2b75..d0d150759ae 100644
--- 
a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/stream/sql/ProcessTableFunctionTest.java
+++ 
b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/stream/sql/ProcessTableFunctionTest.java
@@ -349,6 +349,11 @@ class ProcessTableFunctionTest extends TableTestBase {
 
     private static Stream<ErrorSpec> errorSpecs() {
         return Stream.of(
+                ErrorSpec.ofSelect(
+                        "mixed positional and named arguments",
+                        ScalarArgsFunction.class,
+                        "SELECT * FROM f(1, b => true)",
+                        "Cannot mix positional and named arguments when 
calling function 'f'"),
                 ErrorSpec.ofSelect(
                         "invalid uid",
                         ScalarArgsFunction.class,

Reply via email to