Skip to content

Commit

Permalink
[SPARK-45075][SQL] Fix alter table with invalid default value will no…
Browse files Browse the repository at this point in the history
…t report error

### What changes were proposed in this pull request?
This PR make sure ALTER TABLE ALTER COLUMN with invalid default value on DataSource V2 will report error, before this PR it will alter sucess.

### Why are the changes needed?
Fix the error behavior on DataSource V2 with ALTER TABLE statement.

### Does this PR introduce _any_ user-facing change?
Yes, the invalid default value will report error.

### How was this patch tested?
Add new test.

### Was this patch authored or co-authored using generative AI tooling?
No.

Closes #42810 from Hisoka-X/SPARK-45075_alter_invalid_default_value_on_v2.

Authored-by: Jia Fan <fanjiaeminem@qq.com>
Signed-off-by: Dongjoon Hyun <dhyun@apple.com>
(cherry picked from commit 4dd4737)
Signed-off-by: Dongjoon Hyun <dhyun@apple.com>
  • Loading branch information
Hisoka-X authored and dongjoon-hyun committed Sep 8, 2023
1 parent b2b2ba9 commit 05b57bc
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -696,9 +696,8 @@ public String[] fieldNames() {
/**
* Returns the column default value SQL string (Spark SQL dialect). The default value literal
* is not provided as updating column default values does not need to back-fill existing data.
* Null means dropping the column default value.
* Empty string means dropping the column default value.
*/
@Nullable
public String newDefaultValue() { return newDefaultValue; }

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@

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

import org.apache.spark.sql.catalyst.analysis.{FieldName, FieldPosition}
import org.apache.spark.sql.catalyst.analysis.{FieldName, FieldPosition, ResolvedFieldName}
import org.apache.spark.sql.catalyst.catalog.CatalogTypes.TablePartitionSpec
import org.apache.spark.sql.catalyst.util.TypeUtils
import org.apache.spark.sql.catalyst.util.{ResolveDefaultColumns, TypeUtils}
import org.apache.spark.sql.connector.catalog.{TableCatalog, TableChange}
import org.apache.spark.sql.errors.QueryCompilationErrors
import org.apache.spark.sql.types.DataType
Expand Down Expand Up @@ -228,6 +228,13 @@ case class AlterColumn(
TableChange.updateColumnPosition(colName, newPosition.position)
}
val defaultValueChange = setDefaultExpression.map { newDefaultExpression =>
if (newDefaultExpression.nonEmpty) {
// SPARK-45075: We call 'ResolveDefaultColumns.analyze' here to make sure that the default
// value parses successfully, and return an error otherwise
val newDataType = dataType.getOrElse(column.asInstanceOf[ResolvedFieldName].field.dataType)
ResolveDefaultColumns.analyze(column.name.last, newDataType, newDefaultExpression,
"ALTER TABLE ALTER COLUMN")
}
TableChange.updateColumnDefaultValue(colName, newDefaultExpression)
}
typeChange.toSeq ++ nullabilityChange ++ commentChange ++ positionChange ++ defaultValueChange
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,35 @@ trait AlterTableTests extends SharedSparkSession with QueryErrorsBase {
}
}

test("SPARK-45075: ALTER COLUMN with invalid default value") {
withSQLConf(SQLConf.DEFAULT_COLUMN_ALLOWED_PROVIDERS.key -> s"$v2Format, ") {
withTable("t") {
sql(s"create table t(i boolean) using $v2Format")
// The default value fails to analyze.
checkError(
exception = intercept[AnalysisException] {
sql("alter table t add column s bigint default badvalue")
},
errorClass = "INVALID_DEFAULT_VALUE.UNRESOLVED_EXPRESSION",
parameters = Map(
"statement" -> "ALTER TABLE",
"colName" -> "`s`",
"defaultValue" -> "badvalue"))

sql("alter table t add column s bigint default 3L")
checkError(
exception = intercept[AnalysisException] {
sql("alter table t alter column s set default badvalue")
},
errorClass = "INVALID_DEFAULT_VALUE.UNRESOLVED_EXPRESSION",
parameters = Map(
"statement" -> "ALTER TABLE ALTER COLUMN",
"colName" -> "`s`",
"defaultValue" -> "badvalue"))
}
}
}

test("AlterTable: add complex column") {
val t = fullTableName("table_name")
withTable(t) {
Expand Down

0 comments on commit 05b57bc

Please sign in to comment.