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

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


The following commit(s) were added to refs/heads/master by this push:
     new 43cab48d7 [SEDONA-636] Support GEOMETRY in Spark SQL table creation 
DDL (#1543)
43cab48d7 is described below

commit 43cab48d73fde648f337bd9d868f7191a7c6863d
Author: Feng Zhang <[email protected]>
AuthorDate: Mon Aug 12 10:58:02 2024 -0700

    [SEDONA-636] Support GEOMETRY in Spark SQL table creation DDL (#1543)
    
    * [SEDONA-636] Support geometry data type in create table DDL statement
    
    * add one more test
    
    * [SEDONA-636] Support GEOMETRY in Spark SQL table creation DDL
    
    * add one more unit test
    
    * temporarily remove spark 3.0.3 build
    
    * Support multiple versions of spark
    
    * clean up files
    
    * undo github workflow changes to java.yaml
    
    * add parser to spark-3.0
    
    * add sedona parser to spark-3.0 profile
---
 .../org/apache/sedona/spark/SedonaContext.scala    |  3 +-
 .../org/apache/sedona/sql/ParserRegistrator.scala  | 60 ++++++++++++++++++++
 .../apache/spark/sql/parser/ParserFactory.scala    | 41 ++++++++++++++
 .../sedona/sql/parser/SedonaSqlAstBuilder.scala    | 40 ++++++++++++++
 .../apache/sedona/sql/parser/SedonaSqlParser.scala | 43 +++++++++++++++
 .../org/apache/sedona/sql/SQLSyntaxTestScala.scala | 64 ++++++++++++++++++++++
 .../sedona/sql/parser/SedonaSqlAstBuilder.scala    | 39 +++++++++++++
 .../org/sedona/sql/parser/SedonaSqlParser.scala    | 42 ++++++++++++++
 .../org/apache/sedona/sql/SQLSyntaxTestScala.scala | 57 +++++++++++++++++++
 .../sedona/sql/parser/SedonaSqlAstBuilder.scala    | 39 +++++++++++++
 .../apache/sedona/sql/parser/SedonaSqlParser.scala | 42 ++++++++++++++
 .../org/apache/sedona/sql/SQLSyntaxTestScala.scala | 57 +++++++++++++++++++
 .../src/main/java/org/apache/sedona/Main.java      | 25 +++++++++
 .../sedona/sql/parser/SedonaSqlAstBuilder.scala    | 39 +++++++++++++
 .../apache/sedona/sql/parser/SedonaSqlParser.scala | 42 ++++++++++++++
 .../org/apache/sedona/sql/SQLSyntaxTestScala.scala | 57 +++++++++++++++++++
 .../sedona/sql/parser/SedonaSqlAstBuilder.scala    | 39 +++++++++++++
 .../apache/sedona/sql/parser/SedonaSqlParser.scala | 42 ++++++++++++++
 .../org/apache/sedona/sql/SQLSyntaxTestScala.scala | 57 +++++++++++++++++++
 .../sedona/sql/parser/SedonaSqlAstBuilder.scala    | 39 +++++++++++++
 .../apache/sedona/sql/parser/SedonaSqlParser.scala | 42 ++++++++++++++
 .../org/apache/sedona/sql/SQLSyntaxTestScala.scala | 57 +++++++++++++++++++
 22 files changed, 965 insertions(+), 1 deletion(-)

diff --git 
a/spark/common/src/main/scala/org/apache/sedona/spark/SedonaContext.scala 
b/spark/common/src/main/scala/org/apache/sedona/spark/SedonaContext.scala
index db266c38f..692fe5f72 100644
--- a/spark/common/src/main/scala/org/apache/sedona/spark/SedonaContext.scala
+++ b/spark/common/src/main/scala/org/apache/sedona/spark/SedonaContext.scala
@@ -20,7 +20,7 @@ package org.apache.sedona.spark
 
 import org.apache.sedona.common.utils.TelemetryCollector
 import org.apache.sedona.core.serde.SedonaKryoRegistrator
-import org.apache.sedona.sql.RasterRegistrator
+import org.apache.sedona.sql.{ParserRegistrator, RasterRegistrator}
 import org.apache.sedona.sql.UDF.UdfRegistrator
 import org.apache.sedona.sql.UDT.UdtRegistrator
 import org.apache.spark.serializer.KryoSerializer
@@ -65,6 +65,7 @@ object SedonaContext {
     RasterRegistrator.registerAll(sparkSession)
     UdtRegistrator.registerAll()
     UdfRegistrator.registerAll(sparkSession)
+    ParserRegistrator.register(sparkSession)
     sparkSession
   }
 
diff --git 
a/spark/common/src/main/scala/org/apache/sedona/sql/ParserRegistrator.scala 
b/spark/common/src/main/scala/org/apache/sedona/sql/ParserRegistrator.scala
new file mode 100644
index 000000000..db3c623a0
--- /dev/null
+++ b/spark/common/src/main/scala/org/apache/sedona/sql/ParserRegistrator.scala
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql
+
+import org.apache.spark.sql.SparkSession
+import org.apache.spark.sql.catalyst.parser.ParserInterface
+import org.apache.spark.sql.parser.ParserFactory
+
+object ParserRegistrator {
+
+  /**
+   * Register the custom Sedona Spark parser
+   * @param sparkSession
+   */
+  def register(sparkSession: SparkSession): Unit = {
+    // try to register the parser with the new constructor for spark 3.1 and 
above
+    try {
+      val parserClassName = "org.apache.sedona.sql.parser.SedonaSqlParser"
+      val delegate: ParserInterface = sparkSession.sessionState.sqlParser
+
+      val parser = ParserFactory.getParser(parserClassName, delegate)
+      val field = 
sparkSession.sessionState.getClass.getDeclaredField("sqlParser")
+      field.setAccessible(true)
+      field.set(sparkSession.sessionState, parser)
+      return // return if the new constructor is available
+    } catch {
+      case _: Exception =>
+    }
+
+    // try to register the parser with the legacy constructor for spark 3.0
+    try {
+      val parserClassName = "org.apache.sedona.sql.parser.SedonaSqlParser"
+      val delegate: ParserInterface = sparkSession.sessionState.sqlParser
+
+      val parser =
+        ParserFactory.getParser(parserClassName, 
sparkSession.sessionState.conf, delegate)
+      val field = 
sparkSession.sessionState.getClass.getDeclaredField("sqlParser")
+      field.setAccessible(true)
+      field.set(sparkSession.sessionState, parser)
+    } catch {
+      case _: Exception =>
+    }
+  }
+}
diff --git 
a/spark/common/src/main/scala/org/apache/spark/sql/parser/ParserFactory.scala 
b/spark/common/src/main/scala/org/apache/spark/sql/parser/ParserFactory.scala
new file mode 100644
index 000000000..e0ee46ba0
--- /dev/null
+++ 
b/spark/common/src/main/scala/org/apache/spark/sql/parser/ParserFactory.scala
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.spark.sql.parser
+
+import org.apache.spark.sql.catalyst.parser.ParserInterface
+import org.apache.spark.sql.execution.SparkSqlParser
+import org.apache.spark.sql.internal.SQLConf
+
+object ParserFactory {
+  def getParser(className: String, delegate: ParserInterface): SparkSqlParser 
= {
+    Class
+      .forName(className)
+      .getConstructor(classOf[ParserInterface])
+      .newInstance(delegate)
+      .asInstanceOf[SparkSqlParser]
+  }
+
+  def getParser(className: String, conf: SQLConf, delegate: ParserInterface): 
SparkSqlParser = {
+    Class
+      .forName(className)
+      .getConstructor(classOf[SQLConf], classOf[ParserInterface])
+      .newInstance(conf, delegate)
+      .asInstanceOf[SparkSqlParser]
+  }
+}
diff --git 
a/spark/spark-3.0/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
 
b/spark/spark-3.0/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
new file mode 100644
index 000000000..9c9f6b674
--- /dev/null
+++ 
b/spark/spark-3.0/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql.parser
+
+import org.apache.spark.sql.catalyst.parser.SqlBaseParser._
+import org.apache.spark.sql.execution.SparkSqlAstBuilder
+import org.apache.spark.sql.internal.SQLConf
+import org.apache.spark.sql.sedona_sql.UDT.GeometryUDT
+import org.apache.spark.sql.types.DataType
+
+class SedonaSqlAstBuilder(conf: SQLConf) extends SparkSqlAstBuilder(conf) {
+
+  /**
+   * Override the method to handle the geometry data type
+   * @param ctx
+   * @return
+   */
+  override def visitPrimitiveDataType(ctx: PrimitiveDataTypeContext): DataType 
= {
+    ctx.getText.toUpperCase() match {
+      case "GEOMETRY" => GeometryUDT
+      case _ => super.visitPrimitiveDataType(ctx)
+    }
+  }
+}
diff --git 
a/spark/spark-3.0/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
 
b/spark/spark-3.0/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
new file mode 100644
index 000000000..2d270eaa4
--- /dev/null
+++ 
b/spark/spark-3.0/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql.parser
+
+import org.apache.spark.sql.catalyst.parser.ParserInterface
+import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
+import org.apache.spark.sql.execution.SparkSqlParser
+import org.apache.spark.sql.internal.SQLConf
+
+class SedonaSqlParser(conf: SQLConf, delegate: ParserInterface) extends 
SparkSqlParser(conf) {
+
+  // The parser builder for the Sedona SQL AST
+  val parserBuilder = new SedonaSqlAstBuilder(conf)
+
+  /**
+   * Parse the SQL text and return the logical plan.
+   * @param sqlText
+   * @return
+   */
+  override def parsePlan(sqlText: String): LogicalPlan = parse(sqlText) { 
parser =>
+    parserBuilder.visit(parser.singleStatement()) match {
+      case plan: LogicalPlan => plan
+      case _ =>
+        delegate.parsePlan(sqlText)
+    }
+  }
+}
diff --git 
a/spark/spark-3.0/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala 
b/spark/spark-3.0/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala
new file mode 100644
index 000000000..22a6aa5c7
--- /dev/null
+++ 
b/spark/spark-3.0/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql
+
+import org.scalatest.matchers.must.Matchers.be
+import org.scalatest.matchers.should.Matchers.convertToAnyShouldWrapper
+import org.scalatest.prop.TableDrivenPropertyChecks
+import org.apache.spark.sql.catalyst.parser.ParserInterface
+import org.apache.spark.sql.AnalysisException
+import org.scalatest.matchers.should.Matchers._
+
+/**
+ * Test suite for testing Sedona SQL support.
+ */
+class SQLSyntaxTestScala extends TestBaseScala with TableDrivenPropertyChecks {
+
+  override def beforeAll(): Unit = {
+    super.beforeAll()
+    sparkSession.conf.set("spark.sql.legacy.createHiveTableByDefault", "false")
+  }
+
+  describe("Table creation DDL tests") {
+
+    it("should be able to create a regular table without geometry column 
should work") {
+      val parser: ParserInterface = sparkSession.sessionState.sqlParser
+      val plan = parser.parsePlan("CREATE TABLE IF NOT EXISTS T_TEST_REGULAR 
(INT_COL INT)")
+
+      plan should not be (null)
+    }
+
+    it(
+      "should be able to create a regular table with geometry column should 
work without a workaround") {
+      val parser: ParserInterface = sparkSession.sessionState.sqlParser
+      val plan = parser.parsePlan("CREATE TABLE T_TEST_EXPLICIT_GEOMETRY 
(GEO_COL GEOMETRY)")
+
+      plan should not be (null)
+    }
+
+    it(
+      "should be able to create a regular table with regular and geometry 
column should work without a workaround") {
+      val parser: ParserInterface = sparkSession.sessionState.sqlParser
+      val plan = parser.parsePlan(
+        "CREATE TABLE T_TEST_EXPLICIT_GEOMETRY_2 (INT_COL INT, GEO_COL 
GEOMETRY)")
+
+      plan should not be (null)
+    }
+  }
+}
diff --git 
a/spark/spark-3.1/src/main/scala/org/sedona/sql/parser/SedonaSqlAstBuilder.scala
 
b/spark/spark-3.1/src/main/scala/org/sedona/sql/parser/SedonaSqlAstBuilder.scala
new file mode 100644
index 000000000..2bdd92bd6
--- /dev/null
+++ 
b/spark/spark-3.1/src/main/scala/org/sedona/sql/parser/SedonaSqlAstBuilder.scala
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql.parser
+
+import org.apache.spark.sql.catalyst.parser.SqlBaseParser._
+import org.apache.spark.sql.execution.SparkSqlAstBuilder
+import org.apache.spark.sql.sedona_sql.UDT.GeometryUDT
+import org.apache.spark.sql.types.DataType
+
+class SedonaSqlAstBuilder extends SparkSqlAstBuilder {
+
+  /**
+   * Override the method to handle the geometry data type
+   * @param ctx
+   * @return
+   */
+  override def visitPrimitiveDataType(ctx: PrimitiveDataTypeContext): DataType 
= {
+    ctx.getText.toUpperCase() match {
+      case "GEOMETRY" => GeometryUDT
+      case _ => super.visitPrimitiveDataType(ctx)
+    }
+  }
+}
diff --git 
a/spark/spark-3.1/src/main/scala/org/sedona/sql/parser/SedonaSqlParser.scala 
b/spark/spark-3.1/src/main/scala/org/sedona/sql/parser/SedonaSqlParser.scala
new file mode 100644
index 000000000..420949ab9
--- /dev/null
+++ b/spark/spark-3.1/src/main/scala/org/sedona/sql/parser/SedonaSqlParser.scala
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql.parser
+
+import org.apache.spark.sql.catalyst.parser.ParserInterface
+import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
+import org.apache.spark.sql.execution.SparkSqlParser
+
+class SedonaSqlParser(delegate: ParserInterface) extends SparkSqlParser {
+
+  // The parser builder for the Sedona SQL AST
+  val parserBuilder = new SedonaSqlAstBuilder
+
+  /**
+   * Parse the SQL text and return the logical plan.
+   * @param sqlText
+   * @return
+   */
+  override def parsePlan(sqlText: String): LogicalPlan = parse(sqlText) { 
parser =>
+    parserBuilder.visit(parser.singleStatement()) match {
+      case plan: LogicalPlan => plan
+      case _ =>
+        delegate.parsePlan(sqlText)
+    }
+  }
+}
diff --git 
a/spark/spark-3.1/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala 
b/spark/spark-3.1/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala
new file mode 100644
index 000000000..72680aacd
--- /dev/null
+++ 
b/spark/spark-3.1/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql
+
+import org.scalatest.matchers.must.Matchers.be
+import org.scalatest.matchers.should.Matchers.convertToAnyShouldWrapper
+import org.scalatest.prop.TableDrivenPropertyChecks
+
+/**
+ * Test suite for testing Sedona SQL support.
+ */
+class SQLSyntaxTestScala extends TestBaseScala with TableDrivenPropertyChecks {
+
+  override def beforeAll(): Unit = {
+    super.beforeAll()
+    sparkSession.conf.set("spark.sql.legacy.createHiveTableByDefault", "false")
+  }
+
+  describe("Table creation DDL tests") {
+
+    it("should be able to create a regular table without geometry column 
should work") {
+      sparkSession.sql("DROP TABLE IF EXISTS T_TEST_REGULAR")
+      sparkSession.sql("CREATE TABLE IF NOT EXISTS T_TEST_REGULAR (INT_COL 
INT)")
+      sparkSession.catalog.tableExists("T_TEST_REGULAR") should be(true)
+      sparkSession.sql("DROP TABLE IF EXISTS T_TEST_REGULAR")
+      sparkSession.catalog.tableExists("T_TEST_REGULAR") should be(false)
+    }
+
+    it(
+      "should be able to create a regular table with geometry column should 
work without a workaround") {
+      sparkSession.sql("CREATE TABLE T_TEST_EXPLICIT_GEOMETRY (GEO_COL 
GEOMETRY)")
+      sparkSession.catalog.tableExists("T_TEST_EXPLICIT_GEOMETRY") should 
be(true)
+    }
+
+    it(
+      "should be able to create a regular table with regular and geometry 
column should work without a workaround") {
+      sparkSession.sql("CREATE TABLE T_TEST_EXPLICIT_GEOMETRY_2 (INT_COL INT, 
GEO_COL GEOMETRY)")
+      sparkSession.catalog.tableExists("T_TEST_EXPLICIT_GEOMETRY_2") should 
be(true)
+    }
+  }
+}
diff --git 
a/spark/spark-3.2/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
 
b/spark/spark-3.2/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
new file mode 100644
index 000000000..2bdd92bd6
--- /dev/null
+++ 
b/spark/spark-3.2/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql.parser
+
+import org.apache.spark.sql.catalyst.parser.SqlBaseParser._
+import org.apache.spark.sql.execution.SparkSqlAstBuilder
+import org.apache.spark.sql.sedona_sql.UDT.GeometryUDT
+import org.apache.spark.sql.types.DataType
+
+class SedonaSqlAstBuilder extends SparkSqlAstBuilder {
+
+  /**
+   * Override the method to handle the geometry data type
+   * @param ctx
+   * @return
+   */
+  override def visitPrimitiveDataType(ctx: PrimitiveDataTypeContext): DataType 
= {
+    ctx.getText.toUpperCase() match {
+      case "GEOMETRY" => GeometryUDT
+      case _ => super.visitPrimitiveDataType(ctx)
+    }
+  }
+}
diff --git 
a/spark/spark-3.2/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
 
b/spark/spark-3.2/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
new file mode 100644
index 000000000..420949ab9
--- /dev/null
+++ 
b/spark/spark-3.2/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql.parser
+
+import org.apache.spark.sql.catalyst.parser.ParserInterface
+import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
+import org.apache.spark.sql.execution.SparkSqlParser
+
+class SedonaSqlParser(delegate: ParserInterface) extends SparkSqlParser {
+
+  // The parser builder for the Sedona SQL AST
+  val parserBuilder = new SedonaSqlAstBuilder
+
+  /**
+   * Parse the SQL text and return the logical plan.
+   * @param sqlText
+   * @return
+   */
+  override def parsePlan(sqlText: String): LogicalPlan = parse(sqlText) { 
parser =>
+    parserBuilder.visit(parser.singleStatement()) match {
+      case plan: LogicalPlan => plan
+      case _ =>
+        delegate.parsePlan(sqlText)
+    }
+  }
+}
diff --git 
a/spark/spark-3.2/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala 
b/spark/spark-3.2/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala
new file mode 100644
index 000000000..72680aacd
--- /dev/null
+++ 
b/spark/spark-3.2/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql
+
+import org.scalatest.matchers.must.Matchers.be
+import org.scalatest.matchers.should.Matchers.convertToAnyShouldWrapper
+import org.scalatest.prop.TableDrivenPropertyChecks
+
+/**
+ * Test suite for testing Sedona SQL support.
+ */
+class SQLSyntaxTestScala extends TestBaseScala with TableDrivenPropertyChecks {
+
+  override def beforeAll(): Unit = {
+    super.beforeAll()
+    sparkSession.conf.set("spark.sql.legacy.createHiveTableByDefault", "false")
+  }
+
+  describe("Table creation DDL tests") {
+
+    it("should be able to create a regular table without geometry column 
should work") {
+      sparkSession.sql("DROP TABLE IF EXISTS T_TEST_REGULAR")
+      sparkSession.sql("CREATE TABLE IF NOT EXISTS T_TEST_REGULAR (INT_COL 
INT)")
+      sparkSession.catalog.tableExists("T_TEST_REGULAR") should be(true)
+      sparkSession.sql("DROP TABLE IF EXISTS T_TEST_REGULAR")
+      sparkSession.catalog.tableExists("T_TEST_REGULAR") should be(false)
+    }
+
+    it(
+      "should be able to create a regular table with geometry column should 
work without a workaround") {
+      sparkSession.sql("CREATE TABLE T_TEST_EXPLICIT_GEOMETRY (GEO_COL 
GEOMETRY)")
+      sparkSession.catalog.tableExists("T_TEST_EXPLICIT_GEOMETRY") should 
be(true)
+    }
+
+    it(
+      "should be able to create a regular table with regular and geometry 
column should work without a workaround") {
+      sparkSession.sql("CREATE TABLE T_TEST_EXPLICIT_GEOMETRY_2 (INT_COL INT, 
GEO_COL GEOMETRY)")
+      sparkSession.catalog.tableExists("T_TEST_EXPLICIT_GEOMETRY_2") should 
be(true)
+    }
+  }
+}
diff --git a/spark/spark-3.3/src/main/java/org/apache/sedona/Main.java 
b/spark/spark-3.3/src/main/java/org/apache/sedona/Main.java
new file mode 100644
index 000000000..acb8e3005
--- /dev/null
+++ b/spark/spark-3.3/src/main/java/org/apache/sedona/Main.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona;
+
+public class Main {
+  public static void main(String[] args) {
+    System.out.println("Hello world!");
+  }
+}
diff --git 
a/spark/spark-3.3/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
 
b/spark/spark-3.3/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
new file mode 100644
index 000000000..2bdd92bd6
--- /dev/null
+++ 
b/spark/spark-3.3/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql.parser
+
+import org.apache.spark.sql.catalyst.parser.SqlBaseParser._
+import org.apache.spark.sql.execution.SparkSqlAstBuilder
+import org.apache.spark.sql.sedona_sql.UDT.GeometryUDT
+import org.apache.spark.sql.types.DataType
+
+class SedonaSqlAstBuilder extends SparkSqlAstBuilder {
+
+  /**
+   * Override the method to handle the geometry data type
+   * @param ctx
+   * @return
+   */
+  override def visitPrimitiveDataType(ctx: PrimitiveDataTypeContext): DataType 
= {
+    ctx.getText.toUpperCase() match {
+      case "GEOMETRY" => GeometryUDT
+      case _ => super.visitPrimitiveDataType(ctx)
+    }
+  }
+}
diff --git 
a/spark/spark-3.3/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
 
b/spark/spark-3.3/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
new file mode 100644
index 000000000..420949ab9
--- /dev/null
+++ 
b/spark/spark-3.3/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql.parser
+
+import org.apache.spark.sql.catalyst.parser.ParserInterface
+import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
+import org.apache.spark.sql.execution.SparkSqlParser
+
+class SedonaSqlParser(delegate: ParserInterface) extends SparkSqlParser {
+
+  // The parser builder for the Sedona SQL AST
+  val parserBuilder = new SedonaSqlAstBuilder
+
+  /**
+   * Parse the SQL text and return the logical plan.
+   * @param sqlText
+   * @return
+   */
+  override def parsePlan(sqlText: String): LogicalPlan = parse(sqlText) { 
parser =>
+    parserBuilder.visit(parser.singleStatement()) match {
+      case plan: LogicalPlan => plan
+      case _ =>
+        delegate.parsePlan(sqlText)
+    }
+  }
+}
diff --git 
a/spark/spark-3.3/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala 
b/spark/spark-3.3/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala
new file mode 100644
index 000000000..72680aacd
--- /dev/null
+++ 
b/spark/spark-3.3/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql
+
+import org.scalatest.matchers.must.Matchers.be
+import org.scalatest.matchers.should.Matchers.convertToAnyShouldWrapper
+import org.scalatest.prop.TableDrivenPropertyChecks
+
+/**
+ * Test suite for testing Sedona SQL support.
+ */
+class SQLSyntaxTestScala extends TestBaseScala with TableDrivenPropertyChecks {
+
+  override def beforeAll(): Unit = {
+    super.beforeAll()
+    sparkSession.conf.set("spark.sql.legacy.createHiveTableByDefault", "false")
+  }
+
+  describe("Table creation DDL tests") {
+
+    it("should be able to create a regular table without geometry column 
should work") {
+      sparkSession.sql("DROP TABLE IF EXISTS T_TEST_REGULAR")
+      sparkSession.sql("CREATE TABLE IF NOT EXISTS T_TEST_REGULAR (INT_COL 
INT)")
+      sparkSession.catalog.tableExists("T_TEST_REGULAR") should be(true)
+      sparkSession.sql("DROP TABLE IF EXISTS T_TEST_REGULAR")
+      sparkSession.catalog.tableExists("T_TEST_REGULAR") should be(false)
+    }
+
+    it(
+      "should be able to create a regular table with geometry column should 
work without a workaround") {
+      sparkSession.sql("CREATE TABLE T_TEST_EXPLICIT_GEOMETRY (GEO_COL 
GEOMETRY)")
+      sparkSession.catalog.tableExists("T_TEST_EXPLICIT_GEOMETRY") should 
be(true)
+    }
+
+    it(
+      "should be able to create a regular table with regular and geometry 
column should work without a workaround") {
+      sparkSession.sql("CREATE TABLE T_TEST_EXPLICIT_GEOMETRY_2 (INT_COL INT, 
GEO_COL GEOMETRY)")
+      sparkSession.catalog.tableExists("T_TEST_EXPLICIT_GEOMETRY_2") should 
be(true)
+    }
+  }
+}
diff --git 
a/spark/spark-3.4/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
 
b/spark/spark-3.4/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
new file mode 100644
index 000000000..2bdd92bd6
--- /dev/null
+++ 
b/spark/spark-3.4/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql.parser
+
+import org.apache.spark.sql.catalyst.parser.SqlBaseParser._
+import org.apache.spark.sql.execution.SparkSqlAstBuilder
+import org.apache.spark.sql.sedona_sql.UDT.GeometryUDT
+import org.apache.spark.sql.types.DataType
+
+class SedonaSqlAstBuilder extends SparkSqlAstBuilder {
+
+  /**
+   * Override the method to handle the geometry data type
+   * @param ctx
+   * @return
+   */
+  override def visitPrimitiveDataType(ctx: PrimitiveDataTypeContext): DataType 
= {
+    ctx.getText.toUpperCase() match {
+      case "GEOMETRY" => GeometryUDT
+      case _ => super.visitPrimitiveDataType(ctx)
+    }
+  }
+}
diff --git 
a/spark/spark-3.4/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
 
b/spark/spark-3.4/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
new file mode 100644
index 000000000..420949ab9
--- /dev/null
+++ 
b/spark/spark-3.4/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql.parser
+
+import org.apache.spark.sql.catalyst.parser.ParserInterface
+import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
+import org.apache.spark.sql.execution.SparkSqlParser
+
+class SedonaSqlParser(delegate: ParserInterface) extends SparkSqlParser {
+
+  // The parser builder for the Sedona SQL AST
+  val parserBuilder = new SedonaSqlAstBuilder
+
+  /**
+   * Parse the SQL text and return the logical plan.
+   * @param sqlText
+   * @return
+   */
+  override def parsePlan(sqlText: String): LogicalPlan = parse(sqlText) { 
parser =>
+    parserBuilder.visit(parser.singleStatement()) match {
+      case plan: LogicalPlan => plan
+      case _ =>
+        delegate.parsePlan(sqlText)
+    }
+  }
+}
diff --git 
a/spark/spark-3.4/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala 
b/spark/spark-3.4/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala
new file mode 100644
index 000000000..72680aacd
--- /dev/null
+++ 
b/spark/spark-3.4/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql
+
+import org.scalatest.matchers.must.Matchers.be
+import org.scalatest.matchers.should.Matchers.convertToAnyShouldWrapper
+import org.scalatest.prop.TableDrivenPropertyChecks
+
+/**
+ * Test suite for testing Sedona SQL support.
+ */
+class SQLSyntaxTestScala extends TestBaseScala with TableDrivenPropertyChecks {
+
+  override def beforeAll(): Unit = {
+    super.beforeAll()
+    sparkSession.conf.set("spark.sql.legacy.createHiveTableByDefault", "false")
+  }
+
+  describe("Table creation DDL tests") {
+
+    it("should be able to create a regular table without geometry column 
should work") {
+      sparkSession.sql("DROP TABLE IF EXISTS T_TEST_REGULAR")
+      sparkSession.sql("CREATE TABLE IF NOT EXISTS T_TEST_REGULAR (INT_COL 
INT)")
+      sparkSession.catalog.tableExists("T_TEST_REGULAR") should be(true)
+      sparkSession.sql("DROP TABLE IF EXISTS T_TEST_REGULAR")
+      sparkSession.catalog.tableExists("T_TEST_REGULAR") should be(false)
+    }
+
+    it(
+      "should be able to create a regular table with geometry column should 
work without a workaround") {
+      sparkSession.sql("CREATE TABLE T_TEST_EXPLICIT_GEOMETRY (GEO_COL 
GEOMETRY)")
+      sparkSession.catalog.tableExists("T_TEST_EXPLICIT_GEOMETRY") should 
be(true)
+    }
+
+    it(
+      "should be able to create a regular table with regular and geometry 
column should work without a workaround") {
+      sparkSession.sql("CREATE TABLE T_TEST_EXPLICIT_GEOMETRY_2 (INT_COL INT, 
GEO_COL GEOMETRY)")
+      sparkSession.catalog.tableExists("T_TEST_EXPLICIT_GEOMETRY_2") should 
be(true)
+    }
+  }
+}
diff --git 
a/spark/spark-3.5/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
 
b/spark/spark-3.5/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
new file mode 100644
index 000000000..2bdd92bd6
--- /dev/null
+++ 
b/spark/spark-3.5/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlAstBuilder.scala
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql.parser
+
+import org.apache.spark.sql.catalyst.parser.SqlBaseParser._
+import org.apache.spark.sql.execution.SparkSqlAstBuilder
+import org.apache.spark.sql.sedona_sql.UDT.GeometryUDT
+import org.apache.spark.sql.types.DataType
+
+class SedonaSqlAstBuilder extends SparkSqlAstBuilder {
+
+  /**
+   * Override the method to handle the geometry data type
+   * @param ctx
+   * @return
+   */
+  override def visitPrimitiveDataType(ctx: PrimitiveDataTypeContext): DataType 
= {
+    ctx.getText.toUpperCase() match {
+      case "GEOMETRY" => GeometryUDT
+      case _ => super.visitPrimitiveDataType(ctx)
+    }
+  }
+}
diff --git 
a/spark/spark-3.5/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
 
b/spark/spark-3.5/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
new file mode 100644
index 000000000..420949ab9
--- /dev/null
+++ 
b/spark/spark-3.5/src/main/scala/org/apache/sedona/sql/parser/SedonaSqlParser.scala
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql.parser
+
+import org.apache.spark.sql.catalyst.parser.ParserInterface
+import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
+import org.apache.spark.sql.execution.SparkSqlParser
+
+class SedonaSqlParser(delegate: ParserInterface) extends SparkSqlParser {
+
+  // The parser builder for the Sedona SQL AST
+  val parserBuilder = new SedonaSqlAstBuilder
+
+  /**
+   * Parse the SQL text and return the logical plan.
+   * @param sqlText
+   * @return
+   */
+  override def parsePlan(sqlText: String): LogicalPlan = parse(sqlText) { 
parser =>
+    parserBuilder.visit(parser.singleStatement()) match {
+      case plan: LogicalPlan => plan
+      case _ =>
+        delegate.parsePlan(sqlText)
+    }
+  }
+}
diff --git 
a/spark/spark-3.5/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala 
b/spark/spark-3.5/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala
new file mode 100644
index 000000000..72680aacd
--- /dev/null
+++ 
b/spark/spark-3.5/src/test/scala/org/apache/sedona/sql/SQLSyntaxTestScala.scala
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sedona.sql
+
+import org.scalatest.matchers.must.Matchers.be
+import org.scalatest.matchers.should.Matchers.convertToAnyShouldWrapper
+import org.scalatest.prop.TableDrivenPropertyChecks
+
+/**
+ * Test suite for testing Sedona SQL support.
+ */
+class SQLSyntaxTestScala extends TestBaseScala with TableDrivenPropertyChecks {
+
+  override def beforeAll(): Unit = {
+    super.beforeAll()
+    sparkSession.conf.set("spark.sql.legacy.createHiveTableByDefault", "false")
+  }
+
+  describe("Table creation DDL tests") {
+
+    it("should be able to create a regular table without geometry column 
should work") {
+      sparkSession.sql("DROP TABLE IF EXISTS T_TEST_REGULAR")
+      sparkSession.sql("CREATE TABLE IF NOT EXISTS T_TEST_REGULAR (INT_COL 
INT)")
+      sparkSession.catalog.tableExists("T_TEST_REGULAR") should be(true)
+      sparkSession.sql("DROP TABLE IF EXISTS T_TEST_REGULAR")
+      sparkSession.catalog.tableExists("T_TEST_REGULAR") should be(false)
+    }
+
+    it(
+      "should be able to create a regular table with geometry column should 
work without a workaround") {
+      sparkSession.sql("CREATE TABLE T_TEST_EXPLICIT_GEOMETRY (GEO_COL 
GEOMETRY)")
+      sparkSession.catalog.tableExists("T_TEST_EXPLICIT_GEOMETRY") should 
be(true)
+    }
+
+    it(
+      "should be able to create a regular table with regular and geometry 
column should work without a workaround") {
+      sparkSession.sql("CREATE TABLE T_TEST_EXPLICIT_GEOMETRY_2 (INT_COL INT, 
GEO_COL GEOMETRY)")
+      sparkSession.catalog.tableExists("T_TEST_EXPLICIT_GEOMETRY_2") should 
be(true)
+    }
+  }
+}


Reply via email to