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

huaxingao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg.git


The following commit(s) were added to refs/heads/main by this push:
     new be2528185a Spark 4.0, 4.1: Backport: Forward parseRoutineParam and 
parseQuery to the delegate parser (#18702) (#18718)
be2528185a is described below

commit be2528185a1d37e6590bce193c2760202d90a0cb
Author: Anurag Mantripragada <[email protected]>
AuthorDate: Fri Oct 30 14:03:34 2026 -0700

    Spark 4.0, 4.1: Backport: Forward parseRoutineParam and parseQuery to the 
delegate parser (#18702) (#18718)
---
 .../IcebergSparkSqlExtensionsParser.scala          |  7 +++---
 .../apache/iceberg/spark/TestExtendedParser.java   | 28 ++++++++++++++++++++++
 .../IcebergSparkSqlExtensionsParser.scala          |  7 +++---
 .../apache/iceberg/spark/TestExtendedParser.java   | 27 +++++++++++++++++++++
 4 files changed, 63 insertions(+), 6 deletions(-)

diff --git 
a/spark/v4.0/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/parser/extensions/IcebergSparkSqlExtensionsParser.scala
 
b/spark/v4.0/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/parser/extensions/IcebergSparkSqlExtensionsParser.scala
index 25e056ee2d..4aa1f4af7e 100644
--- 
a/spark/v4.0/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/parser/extensions/IcebergSparkSqlExtensionsParser.scala
+++ 
b/spark/v4.0/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/parser/extensions/IcebergSparkSqlExtensionsParser.scala
@@ -109,8 +109,9 @@ class IcebergSparkSqlExtensionsParser(delegate: 
ParserInterface)
     }.asJava
   }
 
-  override def parseRoutineParam(sqlText: String): StructType =
-    throw new UnsupportedOperationException()
+  override def parseRoutineParam(sqlText: String): StructType = {
+    delegate.parseRoutineParam(sqlText)
+  }
 
   /**
    * Parse a string to a LogicalPlan.
@@ -204,7 +205,7 @@ class IcebergSparkSqlExtensionsParser(delegate: 
ParserInterface)
   }
 
   override def parseQuery(sqlText: String): LogicalPlan = {
-    parsePlan(sqlText)
+    delegate.parseQuery(sqlText)
   }
 }
 
diff --git 
a/spark/v4.0/spark-extensions/src/test/java/org/apache/iceberg/spark/TestExtendedParser.java
 
b/spark/v4.0/spark-extensions/src/test/java/org/apache/iceberg/spark/TestExtendedParser.java
index ef4f009029..3c5ec418e0 100644
--- 
a/spark/v4.0/spark-extensions/src/test/java/org/apache/iceberg/spark/TestExtendedParser.java
+++ 
b/spark/v4.0/spark-extensions/src/test/java/org/apache/iceberg/spark/TestExtendedParser.java
@@ -30,9 +30,11 @@ import java.util.List;
 import org.apache.iceberg.NullOrder;
 import org.apache.iceberg.SortDirection;
 import org.apache.iceberg.expressions.Term;
+import org.apache.spark.sql.Row;
 import org.apache.spark.sql.SparkSession;
 import org.apache.spark.sql.catalyst.parser.AbstractSqlParser;
 import org.apache.spark.sql.catalyst.parser.AstBuilder;
+import org.apache.spark.sql.catalyst.parser.ParseException;
 import org.apache.spark.sql.catalyst.parser.ParserInterface;
 import 
org.apache.spark.sql.catalyst.parser.extensions.IcebergSparkSqlExtensionsParser;
 import org.junit.jupiter.api.AfterAll;
@@ -184,6 +186,32 @@ public class TestExtendedParser {
     verify(icebergParser).parseSortOrder("id ASC NULLS FIRST");
   }
 
+  @Test
+  public void parseQueryRejectsNonQuery() {
+    IcebergSparkSqlExtensionsParser parser = new 
IcebergSparkSqlExtensionsParser(originalParser);
+
+    assertThatThrownBy(() -> parser.parseQuery("DROP VIEW v"))
+        .isInstanceOf(ParseException.class)
+        .hasMessageContaining("PARSE_SYNTAX_ERROR");
+  }
+
+  @Test
+  public void createSqlFunctionWithParameters() throws Exception {
+    IcebergSparkSqlExtensionsParser parser = new 
IcebergSparkSqlExtensionsParser(originalParser);
+    setSessionStateParser(spark.sessionState(), parser);
+
+    try {
+      spark.sql("CREATE TEMPORARY FUNCTION f(a INT) RETURNS INT RETURN a");
+
+      List<Row> rows = spark.sql("SELECT f(1)").collectAsList();
+
+      assertThat(rows).hasSize(1);
+      assertThat(rows.get(0).get(0)).isEqualTo(1);
+    } finally {
+      spark.sql("DROP TEMPORARY FUNCTION IF EXISTS f");
+    }
+  }
+
   private static void setSessionStateParser(Object sessionState, 
ParserInterface parser)
       throws Exception {
     Class<?> clazz = sessionState.getClass();
diff --git 
a/spark/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/parser/extensions/IcebergSparkSqlExtensionsParser.scala
 
b/spark/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/parser/extensions/IcebergSparkSqlExtensionsParser.scala
index 7c737f0513..55aeadc52b 100644
--- 
a/spark/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/parser/extensions/IcebergSparkSqlExtensionsParser.scala
+++ 
b/spark/v4.1/spark-extensions/src/main/scala/org/apache/spark/sql/catalyst/parser/extensions/IcebergSparkSqlExtensionsParser.scala
@@ -110,8 +110,9 @@ class IcebergSparkSqlExtensionsParser(delegate: 
ParserInterface)
     }.asJava
   }
 
-  override def parseRoutineParam(sqlText: String): StructType =
-    throw new UnsupportedOperationException()
+  override def parseRoutineParam(sqlText: String): StructType = {
+    delegate.parseRoutineParam(sqlText)
+  }
 
   /**
    * Parse a string to a LogicalPlan.
@@ -226,7 +227,7 @@ class IcebergSparkSqlExtensionsParser(delegate: 
ParserInterface)
   }
 
   override def parseQuery(sqlText: String): LogicalPlan = {
-    parsePlan(sqlText)
+    delegate.parseQuery(sqlText)
   }
 }
 
diff --git 
a/spark/v4.1/spark-extensions/src/test/java/org/apache/iceberg/spark/TestExtendedParser.java
 
b/spark/v4.1/spark-extensions/src/test/java/org/apache/iceberg/spark/TestExtendedParser.java
index 36e7314473..c3791ac815 100644
--- 
a/spark/v4.1/spark-extensions/src/test/java/org/apache/iceberg/spark/TestExtendedParser.java
+++ 
b/spark/v4.1/spark-extensions/src/test/java/org/apache/iceberg/spark/TestExtendedParser.java
@@ -38,6 +38,7 @@ import org.apache.spark.sql.SparkSession;
 import org.apache.spark.sql.catalyst.parser.AbstractSqlParser;
 import org.apache.spark.sql.catalyst.parser.AstBuilder;
 import org.apache.spark.sql.catalyst.parser.ParameterContext;
+import org.apache.spark.sql.catalyst.parser.ParseException;
 import org.apache.spark.sql.catalyst.parser.ParserInterface;
 import 
org.apache.spark.sql.catalyst.parser.extensions.IcebergSparkSqlExtensionsParser;
 import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan;
@@ -232,6 +233,32 @@ public class TestExtendedParser {
     assertThat(rows.get(0).get(0)).isEqualTo(42);
   }
 
+  @Test
+  public void parseQueryRejectsNonQuery() {
+    IcebergSparkSqlExtensionsParser parser = new 
IcebergSparkSqlExtensionsParser(originalParser);
+
+    assertThatThrownBy(() -> parser.parseQuery("DROP VIEW v"))
+        .isInstanceOf(ParseException.class)
+        .hasMessageContaining("PARSE_SYNTAX_ERROR");
+  }
+
+  @Test
+  public void createSqlFunctionWithParameters() throws Exception {
+    IcebergSparkSqlExtensionsParser parser = new 
IcebergSparkSqlExtensionsParser(originalParser);
+    setSessionStateParser(spark.sessionState(), parser);
+
+    try {
+      spark.sql("CREATE TEMPORARY FUNCTION f(a INT) RETURNS INT RETURN a");
+
+      List<Row> rows = spark.sql("SELECT f(1)").collectAsList();
+
+      assertThat(rows).hasSize(1);
+      assertThat(rows.get(0).get(0)).isEqualTo(1);
+    } finally {
+      spark.sql("DROP TEMPORARY FUNCTION IF EXISTS f");
+    }
+  }
+
   private static void setSessionStateParser(Object sessionState, 
ParserInterface parser)
       throws Exception {
     Class<?> clazz = sessionState.getClass();

Reply via email to