diff --git a/common/utils/src/main/java/org/apache/spark/SparkThrowable.java b/common/utils/src/main/java/org/apache/spark/SparkThrowable.java index 26d66ae3433ad..fc9197bf9bd7c 100644 --- a/common/utils/src/main/java/org/apache/spark/SparkThrowable.java +++ b/common/utils/src/main/java/org/apache/spark/SparkThrowable.java @@ -51,6 +51,7 @@ public interface SparkThrowable { // Portable error identifier across SQL engines // If null, error class or SQLSTATE is not set + // Deprecated: Override this method to provide explicit SQL state instead of relying on error class reader default String getSqlState() { return SparkThrowableHelper.getSqlState(this.getCondition()); } diff --git a/common/utils/src/main/scala/org/apache/spark/SparkException.scala b/common/utils/src/main/scala/org/apache/spark/SparkException.scala index f438c62253475..07b6f60e5584a 100644 --- a/common/utils/src/main/scala/org/apache/spark/SparkException.scala +++ b/common/utils/src/main/scala/org/apache/spark/SparkException.scala @@ -29,7 +29,8 @@ class SparkException( cause: Throwable, errorClass: Option[String], messageParameters: Map[String, String], - context: Array[QueryContext] = Array.empty) + context: Array[QueryContext] = Array.empty, + sqlState: Option[String] = None) extends Exception(message, cause) with SparkThrowable { def this(message: String, cause: Throwable) = @@ -71,6 +72,8 @@ class SparkException( override def getCondition: String = errorClass.orNull + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) + override def getQueryContext: Array[QueryContext] = context } @@ -170,7 +173,8 @@ private[spark] class SparkUpgradeException private( message: String, cause: Option[Throwable], errorClass: Option[String], - messageParameters: Map[String, String]) + messageParameters: Map[String, String], + sqlState: Option[String] = None) extends RuntimeException(message, cause.orNull) with SparkThrowable { def this( @@ -188,6 +192,8 @@ private[spark] class SparkUpgradeException private( override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass.orNull + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) } /** @@ -197,7 +203,8 @@ private[spark] class SparkArithmeticException private( message: String, errorClass: Option[String], messageParameters: Map[String, String], - context: Array[QueryContext]) + context: Array[QueryContext], + sqlState: Option[String] = None) extends ArithmeticException(message) with SparkThrowable { def this( @@ -221,6 +228,9 @@ private[spark] class SparkArithmeticException private( override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass.orNull + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) + override def getQueryContext: Array[QueryContext] = context } @@ -230,7 +240,8 @@ private[spark] class SparkArithmeticException private( private[spark] class SparkUnsupportedOperationException private( message: String, errorClass: Option[String], - messageParameters: Map[String, String]) + messageParameters: Map[String, String], + sqlState: Option[String] = None) extends UnsupportedOperationException(message) with SparkThrowable { def this( @@ -259,6 +270,8 @@ private[spark] class SparkUnsupportedOperationException private( override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass.orNull + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) } private[spark] object SparkUnsupportedOperationException { @@ -281,7 +294,8 @@ private[spark] object SparkUnsupportedOperationException { private[spark] class SparkClassNotFoundException( errorClass: String, messageParameters: Map[String, String], - cause: Throwable = null) + cause: Throwable = null, + sqlState: Option[String] = None) extends ClassNotFoundException( SparkThrowableHelper.getMessage(errorClass, messageParameters), cause) with SparkThrowable { @@ -289,6 +303,8 @@ private[spark] class SparkClassNotFoundException( override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) } /** @@ -297,7 +313,8 @@ private[spark] class SparkClassNotFoundException( private[spark] class SparkConcurrentModificationException( errorClass: String, messageParameters: Map[String, String], - cause: Throwable = null) + cause: Throwable = null, + sqlState: Option[String] = None) extends ConcurrentModificationException( SparkThrowableHelper.getMessage(errorClass, messageParameters), cause) with SparkThrowable { @@ -305,6 +322,8 @@ private[spark] class SparkConcurrentModificationException( override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) } /** @@ -315,7 +334,8 @@ private[spark] class SparkDateTimeException private( errorClass: Option[String], messageParameters: Map[String, String], context: Array[QueryContext], - cause: Option[Throwable]) + cause: Option[Throwable], + sqlState: Option[String] = None) extends DateTimeException(message, cause.orNull) with SparkThrowable { def this( @@ -355,6 +375,9 @@ private[spark] class SparkDateTimeException private( override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass.orNull + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) + override def getQueryContext: Array[QueryContext] = context } @@ -363,7 +386,8 @@ private[spark] class SparkDateTimeException private( */ private[spark] class SparkFileNotFoundException( errorClass: String, - messageParameters: Map[String, String]) + messageParameters: Map[String, String], + sqlState: Option[String] = None) extends FileNotFoundException( SparkThrowableHelper.getMessage(errorClass, messageParameters)) with SparkThrowable { @@ -371,6 +395,8 @@ private[spark] class SparkFileNotFoundException( override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) } /** @@ -380,7 +406,8 @@ private[spark] class SparkNumberFormatException private( message: String, errorClass: Option[String], messageParameters: Map[String, String], - context: Array[QueryContext]) + context: Array[QueryContext], + sqlState: Option[String] = None) extends NumberFormatException(message) with SparkThrowable { @@ -405,6 +432,9 @@ private[spark] class SparkNumberFormatException private( override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass.orNull + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) + override def getQueryContext: Array[QueryContext] = context } @@ -416,7 +446,8 @@ private[spark] class SparkIllegalArgumentException private( cause: Option[Throwable], errorClass: Option[String], messageParameters: Map[String, String], - context: Array[QueryContext]) + context: Array[QueryContext], + sqlState: Option[String] = None) extends IllegalArgumentException(message, cause.orNull) with SparkThrowable { @@ -457,6 +488,9 @@ private[spark] class SparkIllegalArgumentException private( override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass.orNull + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) + override def getQueryContext: Array[QueryContext] = context } @@ -467,7 +501,8 @@ private[spark] class SparkIllegalStateException( errorClass: String, messageParameters: Map[String, String], context: Array[QueryContext] = Array.empty, - cause: Throwable = null) + cause: Throwable = null, + sqlState: Option[String] = None) extends IllegalStateException( SparkThrowableHelper.getMessage(errorClass, messageParameters), cause) with SparkThrowable { @@ -476,6 +511,8 @@ private[spark] class SparkIllegalStateException( override def getCondition: String = errorClass + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) + override def getQueryContext: Array[QueryContext] = context } @@ -484,7 +521,8 @@ private[spark] class SparkRuntimeException private( cause: Option[Throwable], errorClass: Option[String], messageParameters: Map[String, String], - context: Array[QueryContext]) + context: Array[QueryContext], + sqlState: Option[String]) extends RuntimeException(message, cause.orNull) with SparkThrowable { def this( @@ -498,13 +536,17 @@ private[spark] class SparkRuntimeException private( Option(cause), Option(errorClass), messageParameters, - context + context, + None ) } override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass.orNull + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) + override def getQueryContext: Array[QueryContext] = context } @@ -513,7 +555,8 @@ private[spark] class SparkPythonException private( cause: Option[Throwable], errorClass: Option[String], messageParameters: Map[String, String], - context: Array[QueryContext]) + context: Array[QueryContext], + sqlState: Option[String]) extends RuntimeException(message, cause.orNull) with SparkThrowable { def this( @@ -527,13 +570,17 @@ private[spark] class SparkPythonException private( Option(cause), Option(errorClass), messageParameters, - context + context, + None ) } override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass.orNull + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) + override def getQueryContext: Array[QueryContext] = context } @@ -544,7 +591,8 @@ private[spark] class SparkNoSuchElementException( errorClass: String, messageParameters: Map[String, String], context: Array[QueryContext] = Array.empty, - summary: String = "") + summary: String = "", + sqlState: Option[String] = None) extends NoSuchElementException( SparkThrowableHelper.getMessage(errorClass, messageParameters, summary)) with SparkThrowable { @@ -553,6 +601,8 @@ private[spark] class SparkNoSuchElementException( override def getCondition: String = errorClass + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) + override def getQueryContext: Array[QueryContext] = context } @@ -561,7 +611,8 @@ private[spark] class SparkNoSuchElementException( */ private[spark] class SparkSecurityException( errorClass: String, - messageParameters: Map[String, String]) + messageParameters: Map[String, String], + sqlState: Option[String] = None) extends SecurityException( SparkThrowableHelper.getMessage(errorClass, messageParameters)) with SparkThrowable { @@ -569,6 +620,8 @@ private[spark] class SparkSecurityException( override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) } /** @@ -578,7 +631,8 @@ private[spark] class SparkArrayIndexOutOfBoundsException private( message: String, errorClass: Option[String], messageParameters: Map[String, String], - context: Array[QueryContext]) + context: Array[QueryContext], + sqlState: Option[String] = None) extends ArrayIndexOutOfBoundsException(message) with SparkThrowable { @@ -603,6 +657,9 @@ private[spark] class SparkArrayIndexOutOfBoundsException private( override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass.orNull + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) + override def getQueryContext: Array[QueryContext] = context } @@ -611,7 +668,8 @@ private[spark] class SparkArrayIndexOutOfBoundsException private( */ private[spark] class SparkSQLException( errorClass: String, - messageParameters: Map[String, String]) + messageParameters: Map[String, String], + sqlState: Option[String] = None) extends SQLException( SparkThrowableHelper.getMessage(errorClass, messageParameters)) with SparkThrowable { @@ -619,6 +677,8 @@ private[spark] class SparkSQLException( override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) } /** @@ -626,7 +686,8 @@ private[spark] class SparkSQLException( */ private[spark] class SparkSQLFeatureNotSupportedException( errorClass: String, - messageParameters: Map[String, String]) + messageParameters: Map[String, String], + sqlState: Option[String] = None) extends SQLFeatureNotSupportedException( SparkThrowableHelper.getMessage(errorClass, messageParameters)) with SparkThrowable { @@ -634,4 +695,6 @@ private[spark] class SparkSQLFeatureNotSupportedException( override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) } diff --git a/common/utils/src/main/scala/org/apache/spark/sql/streaming/StreamingQueryException.scala b/common/utils/src/main/scala/org/apache/spark/sql/streaming/StreamingQueryException.scala index 1972ef05d8759..b30260b8d6cc1 100644 --- a/common/utils/src/main/scala/org/apache/spark/sql/streaming/StreamingQueryException.scala +++ b/common/utils/src/main/scala/org/apache/spark/sql/streaming/StreamingQueryException.scala @@ -39,7 +39,8 @@ class StreamingQueryException private[sql]( val startOffset: String, val endOffset: String, errorClass: String, - messageParameters: Map[String, String]) + messageParameters: Map[String, String], + sqlState: Option[String] = None) extends Exception(message, cause) with SparkThrowable { private[spark] def this( @@ -86,5 +87,7 @@ class StreamingQueryException private[sql]( override def getCondition: String = errorClass + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) + override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava } diff --git a/connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaExceptions.scala b/connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaExceptions.scala index 156bb71d777d3..9db9f69c54dfe 100644 --- a/connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaExceptions.scala +++ b/connector/kafka-0-10-sql/src/main/scala/org/apache/spark/sql/kafka010/KafkaExceptions.scala @@ -242,14 +242,15 @@ object KafkaExceptions { private[kafka010] class KafkaIllegalStateException( errorClass: String, messageParameters: Map[String, String], - cause: Throwable = null) + cause: Throwable = null, + sqlState: Option[String] = None) extends IllegalStateException( KafkaExceptionsHelper.errorClassesJsonReader.getErrorMessage( errorClass, messageParameters), cause) with SparkThrowable { override def getSqlState: String = - KafkaExceptionsHelper.errorClassesJsonReader.getSqlState(errorClass) + sqlState.getOrElse(KafkaExceptionsHelper.errorClassesJsonReader.getSqlState(errorClass)) override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava @@ -262,14 +263,15 @@ private[kafka010] class KafkaIllegalStateException( private[kafka010] class KafkaIllegalArgumentException( errorClass: String, messageParameters: Map[String, String], - cause: Throwable = null) + cause: Throwable = null, + sqlState: Option[String] = None) extends IllegalArgumentException( KafkaExceptionsHelper.errorClassesJsonReader.getErrorMessage( errorClass, messageParameters), cause) with SparkThrowable { override def getSqlState: String = - KafkaExceptionsHelper.errorClassesJsonReader.getSqlState(errorClass) + sqlState.getOrElse(KafkaExceptionsHelper.errorClassesJsonReader.getSqlState(errorClass)) override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava diff --git a/core/src/main/java/org/apache/spark/memory/SparkOutOfMemoryError.java b/core/src/main/java/org/apache/spark/memory/SparkOutOfMemoryError.java index 0e35ebecfd270..240ca24f4224e 100644 --- a/core/src/main/java/org/apache/spark/memory/SparkOutOfMemoryError.java +++ b/core/src/main/java/org/apache/spark/memory/SparkOutOfMemoryError.java @@ -31,11 +31,17 @@ public final class SparkOutOfMemoryError extends OutOfMemoryError implements SparkThrowable { String errorClass; Map messageParameters; + String sqlState; public SparkOutOfMemoryError(String errorClass, Map messageParameters) { + this(errorClass, messageParameters, null); + } + + public SparkOutOfMemoryError(String errorClass, Map messageParameters, String sqlState) { super(SparkThrowableHelper.getMessage(errorClass, messageParameters)); this.errorClass = errorClass; this.messageParameters = messageParameters; + this.sqlState = sqlState; } @Override @@ -47,4 +53,9 @@ public Map getMessageParameters() { public String getCondition() { return errorClass; } + + @Override + public String getSqlState() { + return sqlState != null ? sqlState : SparkThrowable.super.getSqlState(); + } } diff --git a/core/src/main/scala/org/apache/spark/SparkFileAlreadyExistsException.scala b/core/src/main/scala/org/apache/spark/SparkFileAlreadyExistsException.scala index 82a0261f32ae7..30e82ecffca05 100644 --- a/core/src/main/scala/org/apache/spark/SparkFileAlreadyExistsException.scala +++ b/core/src/main/scala/org/apache/spark/SparkFileAlreadyExistsException.scala @@ -26,7 +26,8 @@ import org.apache.hadoop.fs.FileAlreadyExistsException */ private[spark] class SparkFileAlreadyExistsException( errorClass: String, - messageParameters: Map[String, String]) + messageParameters: Map[String, String], + sqlState: Option[String] = None) extends FileAlreadyExistsException( SparkThrowableHelper.getMessage(errorClass, messageParameters)) with SparkThrowable { @@ -34,4 +35,6 @@ private[spark] class SparkFileAlreadyExistsException( override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava override def getCondition: String = errorClass + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) } diff --git a/core/src/test/scala/org/apache/spark/SparkThrowableSuite.scala b/core/src/test/scala/org/apache/spark/SparkThrowableSuite.scala index d182bd165f1f7..4f461698eb0d5 100644 --- a/core/src/test/scala/org/apache/spark/SparkThrowableSuite.scala +++ b/core/src/test/scala/org/apache/spark/SparkThrowableSuite.scala @@ -693,4 +693,117 @@ class SparkThrowableSuite extends SparkFunSuite { assert(result == "[TEST_CUSTOM_TEMPLATE] Custom error: " + "something occurred with somewhere SQLSTATE: 42S01") } + + test("Custom SQL state takes precedence over error class reader - SparkException") { + // Test with custom SQL state - should return the custom one + val exceptionWithCustomSqlState = new SparkException( + message = getMessage("CANNOT_PARSE_DECIMAL", Map.empty[String, String]), + cause = null, + errorClass = Some("CANNOT_PARSE_DECIMAL"), + messageParameters = Map.empty[String, String], + context = Array.empty, + sqlState = Some("CUSTOM")) + + assert(exceptionWithCustomSqlState.getSqlState == "CUSTOM", + "Custom SQL state should take precedence") + + // Test without custom SQL state - should fall back to error class reader + val exceptionWithoutCustomSqlState = new SparkException( + message = getMessage("CANNOT_PARSE_DECIMAL", Map.empty[String, String]), + cause = null, + errorClass = Some("CANNOT_PARSE_DECIMAL"), + messageParameters = Map.empty[String, String], + context = Array.empty, + sqlState = None) + + assert(exceptionWithoutCustomSqlState.getSqlState == "22018", + "Should fall back to error class reader SQL state") + } + + test("SparkArithmeticException uses error class reader for SQL state") { + // Test that SparkArithmeticException falls back to error class reader + val exception = new SparkArithmeticException( + errorClass = "DIVIDE_BY_ZERO", + messageParameters = Map("config" -> "CONFIG"), + context = Array.empty, + summary = "") + + assert(exception.getSqlState == "22012", + "Should use error class reader SQL state") + } + + test("SparkRuntimeException uses error class reader for SQL state") { + // Test that SparkRuntimeException falls back to error class reader + val exception = new SparkRuntimeException( + errorClass = "INTERNAL_ERROR", + messageParameters = Map("message" -> "test")) + + assert(exception.getSqlState.startsWith("XX"), + "Should use error class reader SQL state") + } + + test("SparkIllegalArgumentException uses error class reader for SQL state") { + // Test that SparkIllegalArgumentException falls back to error class reader + val exception = new SparkIllegalArgumentException( + errorClass = "UNSUPPORTED_SAVE_MODE.EXISTENT_PATH", + messageParameters = Map("saveMode" -> "TEST")) + + assert(exception.getSqlState == "0A000", + "Should use error class reader SQL state") + } + + test("Custom SQL state takes precedence - Multiple exception types") { + // SparkSQLException + val sqlException = new SparkSQLException( + errorClass = "CANNOT_PARSE_DECIMAL", + messageParameters = Map.empty[String, String], + sqlState = Some("CUST1")) + assert(sqlException.getSqlState == "CUST1") + + // SparkSecurityException + val securityException = new SparkSecurityException( + errorClass = "CANNOT_PARSE_DECIMAL", + messageParameters = Map.empty[String, String], + sqlState = Some("CUST2")) + assert(securityException.getSqlState == "CUST2") + + // SparkNumberFormatException + val numberFormatException = new SparkNumberFormatException( + errorClass = "CANNOT_PARSE_DECIMAL", + messageParameters = Map.empty[String, String], + context = Array.empty, + summary = "") + assert(numberFormatException.getSqlState == "22018", + "Should use error class reader SQL state when custom not provided") + } + + test("Custom SQL state takes precedence - Java exception (SparkOutOfMemoryError)") { + import org.apache.spark.memory.SparkOutOfMemoryError + + // Test without custom SQL state - should fall back to error class reader + val errorWithoutCustom = new SparkOutOfMemoryError( + "CANNOT_PARSE_DECIMAL", + Map.empty[String, String].asJava) + + assert(errorWithoutCustom.getSqlState == "22018", + "Should use error class reader SQL state when custom not provided") + + // Test with custom SQL state - should return the custom one + val errorWithCustom = new SparkOutOfMemoryError( + "CANNOT_PARSE_DECIMAL", + Map.empty[String, String].asJava, + "CUSTOM") + + assert(errorWithCustom.getSqlState == "CUSTOM", + "Custom SQL state should take precedence over error class reader") + + // Test with null custom SQL state - should fall back to error class reader + val errorWithNull = new SparkOutOfMemoryError( + "CANNOT_PARSE_DECIMAL", + Map.empty[String, String].asJava, + null) + + assert(errorWithNull.getSqlState == "22018", + "Should fall back to error class reader SQL state when custom is null") + } } diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/exceptions/SqlScriptingException.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/exceptions/SqlScriptingException.scala index 28d8177dbb236..105e1fbe2250c 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/exceptions/SqlScriptingException.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/exceptions/SqlScriptingException.scala @@ -27,13 +27,17 @@ private[sql] class SqlScriptingException ( errorClass: String, cause: Throwable, val origin: Origin, - messageParameters: Map[String, String] = Map.empty) + messageParameters: Map[String, String] = Map.empty, + sqlState: Option[String] = None) extends Exception( errorMessageWithLineNumber(Option(origin), errorClass, messageParameters), cause) with SparkThrowable { override def getCondition: String = errorClass + + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) + override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava } diff --git a/sql/connect/common/src/main/scala/org/apache/spark/sql/connect/common/InvalidPlanInput.scala b/sql/connect/common/src/main/scala/org/apache/spark/sql/connect/common/InvalidPlanInput.scala index 7f16d09b9c420..84ef625fcf453 100644 --- a/sql/connect/common/src/main/scala/org/apache/spark/sql/connect/common/InvalidPlanInput.scala +++ b/sql/connect/common/src/main/scala/org/apache/spark/sql/connect/common/InvalidPlanInput.scala @@ -26,7 +26,8 @@ import org.apache.spark.{SparkThrowable, SparkThrowableHelper} final case class InvalidPlanInput( private val errorCondition: String, private val messageParameters: Map[String, String], - private val causeOpt: Option[Throwable]) + private val causeOpt: Option[Throwable], + private val sqlState: Option[String] = None) extends Exception( SparkThrowableHelper.getMessage(errorCondition, messageParameters), causeOpt.orNull) @@ -34,6 +35,8 @@ final case class InvalidPlanInput( override def getCondition: String = errorCondition + override def getSqlState: String = sqlState.getOrElse(super.getSqlState) + override def getMessageParameters: java.util.Map[String, String] = messageParameters.asJava }