Skip to content

Commit

Permalink
Add user facing exception message
Browse files Browse the repository at this point in the history
  • Loading branch information
urosstan-db committed Jun 3, 2024
1 parent ebbfb4b commit 5dcdae8
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 8 deletions.
6 changes: 6 additions & 0 deletions common/utils/src/main/resources/error/error-conditions.json
Original file line number Diff line number Diff line change
Expand Up @@ -1387,6 +1387,12 @@
],
"sqlState" : "42623"
},
"COLUMN_DEFAULT_VALUE_IS_NOT_FOLDABLE_OR_RESOLVED" : {
"message" : [
"The existence default value must be a simple SQL string that is resolved and foldable, but column <colName> has default value: (<defaultValue>)"
],
"sqlState" : "42624"
},
"GET_TABLES_BY_TYPE_UNSUPPORTED_BY_HIVE_VERSION" : {
"message" : [
"Hive 2.2 and lower versions don't support getTablesByType. Please use Hive 2.3 or higher version."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.spark.sql.catalyst.plans.logical

import org.apache.spark.sql.AnalysisException
import org.apache.spark.sql.catalyst.analysis.{FieldName, FieldPosition}
import org.apache.spark.sql.catalyst.expressions.Attribute
import org.apache.spark.sql.catalyst.trees.{LeafLike, UnaryLike}
Expand Down Expand Up @@ -142,9 +143,16 @@ case class QualifiedColType(
def getV2Default: ColumnDefaultValue = {
default.map { sql =>
val e = ResolveDefaultColumns.analyze(colName, dataType, sql, "ALTER TABLE")
assert(e.resolved && e.foldable,
"The existence default value must be a simple SQL string that is resolved and foldable, " +
"but got: " + sql)
if (!e.resolved || !e.foldable) {
throw new AnalysisException(
errorClass = "COLUMN_DEFAULT_VALUE_IS_NOT_FOLDABLE_OR_RESOLVED",
messageParameters = Map(
"colName" -> colName,
"defaultValue" -> sql,
)
)
}

new ColumnDefaultValue(sql, LiteralValue(e.eval(), dataType))
}.orNull
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,10 +525,21 @@ private[sql] object CatalogV2Util {
}

if (isDefaultColumn) {
val e = analyze(f, statementType = "", metadataKey = EXISTS_DEFAULT_COLUMN_METADATA_KEY)
assert(e.resolved && e.foldable,
"The existence default value must be a simple SQL string that is resolved and foldable, " +
"but got: " + f.getExistenceDefaultValue().get)
val e = analyze(
f,
statementType = "",
metadataKey = EXISTS_DEFAULT_COLUMN_METADATA_KEY)

if (!e.resolved || !e.foldable) {
throw new AnalysisException(
errorClass = "COLUMN_DEFAULT_VALUE_IS_NOT_FOLDABLE_OR_RESOLVED",
messageParameters = Map(
"colName" -> f.name,
"defaultValue" -> f.getExistenceDefaultValue().get,
)
)
}

val defaultValue = new ColumnDefaultValue(
f.getCurrentDefaultValue().get, LiteralValue(e.eval(), f.dataType))
val cleanedMetadata = metadataWithKeysRemoved(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,19 @@ class InMemoryTableSessionCatalog extends TestV2SessionCatalogBase[InMemoryTable
Option(tables.get(ident)) match {
case Some(table) =>
val properties = CatalogV2Util.applyPropertiesChanges(table.properties, changes)
val schema = CatalogV2Util.applySchemaChanges(table.schema, changes, None, "ALTER TABLE")
val provider =
if (properties.containsKey("provider")) {
Some(properties.get("provider"))
} else {
None
}

val schema = CatalogV2Util.applySchemaChanges(
table.schema,
changes,
provider,
"ALTER TABLE"
)

// fail if the last column in the schema was dropped
if (schema.fields.isEmpty) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3488,6 +3488,23 @@ class DataSourceV2SQLSuiteV1Filter
}
}

test("SPARK-48286: Add new column with default value which is not foldable") {
withSQLConf(
SQLConf.DEFAULT_COLUMN_ALLOWED_PROVIDERS.key -> v2Source) {
withTable("tab") {
spark.sql(s"CREATE TABLE tab (col1 INT DEFAULT 100) USING $v2Source")
val exception = intercept[AnalysisException] {
// Rand function is not foldable
spark.sql(s"ALTER TABLE tab ADD COLUMN col2 DOUBLE DEFAULT rand()")
}
assert(exception.getSqlState == "42624")
assert(exception.errorClass.get == "COLUMN_DEFAULT_VALUE_IS_NOT_FOLDABLE_OR_RESOLVED")
assert(exception.messageParameters("colName") == "col2")
assert(exception.messageParameters("defaultValue") == "rand()")
}
}
}

private def testNotSupportedV2Command(
sqlCommand: String,
sqlParams: String,
Expand Down

0 comments on commit 5dcdae8

Please sign in to comment.