diff --git a/sql/core/src/main/scala/org/apache/spark/sql/jdbc/DatabricksDialect.scala b/sql/core/src/main/scala/org/apache/spark/sql/jdbc/DatabricksDialect.scala index a56aa90d6d72b..0c606ce71f914 100644 --- a/sql/core/src/main/scala/org/apache/spark/sql/jdbc/DatabricksDialect.scala +++ b/sql/core/src/main/scala/org/apache/spark/sql/jdbc/DatabricksDialect.scala @@ -55,9 +55,12 @@ private case class DatabricksDialect() extends JdbcDialect with NoLegacyJDBCErro case _ => None } - // See https://docs.databricks.com/aws/en/error-messages/sqlstates + // See https://docs.databricks.com/aws/en/error-messages/sqlstates. + // The driver may report syntax errors with a non-class-42 SQLState. override def isSyntaxErrorBestEffort(exception: SQLException): Boolean = { - Option(exception.getSQLState).exists(_.startsWith("42")) + Option(exception.getSQLState).exists(_.startsWith("42")) || + Option(exception.getMessage) + .exists(_.toUpperCase(Locale.ROOT).contains("SYNTAX_ERROR")) } override def quoteIdentifier(colName: String): String = { diff --git a/sql/core/src/test/scala/org/apache/spark/sql/jdbc/JDBCSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/jdbc/JDBCSuite.scala index 58797e68b8ab4..de863b244be8a 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/jdbc/JDBCSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/jdbc/JDBCSuite.scala @@ -18,7 +18,7 @@ package org.apache.spark.sql.jdbc import java.math.BigDecimal -import java.sql.{Connection, Date, DriverManager, ResultSet, Statement, Timestamp} +import java.sql.{Connection, Date, DriverManager, ResultSet, SQLException, Statement, Timestamp} import java.time.{Instant, LocalDate, LocalDateTime} import java.time.format.DateTimeFormatter import java.util.{Calendar, GregorianCalendar, Properties, TimeZone} @@ -2608,6 +2608,13 @@ class JDBCSuite extends SharedSparkSession { .getJDBCType(BinaryType).map(_.databaseTypeDefinition).get == "BINARY") } + test("SPARK-58193: DatabricksDialect syntax error detection") { + val dialect = DatabricksDialect() + assert(dialect.isSyntaxErrorBestEffort( + new SQLException("[parse_syntax_error] Syntax error at or near 'SQL'", "07000"))) + assert(!dialect.isSyntaxErrorBestEffort(new SQLException("Connection reset", "08001"))) + } + test("SPARK-45425: Mapped TINYINT to ShortType for MsSqlServerDialect") { val msSqlServerDialect = JdbcDialects.get("jdbc:sqlserver") val metadata = new MetadataBuilder().putLong("scale", 1)