-
Notifications
You must be signed in to change notification settings - Fork 28.5k
[SPARK-52095][SQL] Alter table alter column to pass V2Expression to DSV2 #50864
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
ba2accb
3539dd0
dbd29ee
f53ecec
0877f02
e8ea5ad
e176c62
ec5c930
d5a3b0c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -232,8 +232,28 @@ static TableChange updateColumnPosition(String[] fieldNames, ColumnPosition newP | |
* @param fieldNames field names of the column to update | ||
* @param newDefaultValue the new default value SQL string (Spark SQL dialect). | ||
* @return a TableChange for the update | ||
* | ||
* @deprecated Please use {@link #updateColumnDefaultValue(String[], DefaultValue)} instead. | ||
*/ | ||
@Deprecated(since = "4.1.0") | ||
static TableChange updateColumnDefaultValue(String[] fieldNames, String newDefaultValue) { | ||
return new UpdateColumnDefaultValue(fieldNames, new ColumnDefaultValue(newDefaultValue, null)); | ||
} | ||
|
||
/** | ||
* Create a TableChange for updating the default value of a field. | ||
* <p> | ||
* The name is used to find the field to update. | ||
* <p> | ||
* If the field does not exist, the change will result in an {@link IllegalArgumentException}. | ||
* | ||
* @param fieldNames field names of the column to update | ||
* @param newDefaultValue the new default value SQL (Spark SQL dialect and | ||
* V2 expression representation if it can be converted). | ||
* Null indicates dropping column default value | ||
* @return a TableChange for the update | ||
*/ | ||
static TableChange updateColumnDefaultValue(String[] fieldNames, DefaultValue newDefaultValue) { | ||
return new UpdateColumnDefaultValue(fieldNames, newDefaultValue); | ||
} | ||
|
||
|
@@ -709,11 +729,11 @@ public int hashCode() { | |
*/ | ||
final class UpdateColumnDefaultValue implements ColumnChange { | ||
private final String[] fieldNames; | ||
private final String newDefaultValue; | ||
private final DefaultValue newCurrentDefault; | ||
|
||
private UpdateColumnDefaultValue(String[] fieldNames, String newDefaultValue) { | ||
private UpdateColumnDefaultValue(String[] fieldNames, DefaultValue newCurrentDefault) { | ||
this.fieldNames = fieldNames; | ||
this.newDefaultValue = newDefaultValue; | ||
this.newCurrentDefault = newCurrentDefault; | ||
} | ||
|
||
@Override | ||
|
@@ -725,22 +745,33 @@ 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. | ||
* Empty string means dropping the column default value. | ||
* | ||
* @deprecated Use {@link #newCurrentDefault()} instead. | ||
*/ | ||
@Deprecated(since = "4.1.0") | ||
public String newDefaultValue() { | ||
return newCurrentDefault == null ? "" : newCurrentDefault.getSql(); | ||
} | ||
|
||
/** | ||
* Returns the column default value as {@link DefaultValue}. 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. | ||
*/ | ||
public String newDefaultValue() { return newDefaultValue; } | ||
public DefaultValue newCurrentDefault() { return newCurrentDefault; } | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
szehon-ho marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. did you generate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, whats the recommendation? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah sorry i used wrong template in Intellij, fixed |
||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
UpdateColumnDefaultValue that = (UpdateColumnDefaultValue) o; | ||
return Arrays.equals(fieldNames, that.fieldNames) && | ||
newDefaultValue.equals(that.newDefaultValue()); | ||
Objects.equals(newCurrentDefault, that.newCurrentDefault); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
int result = Objects.hash(newDefaultValue); | ||
result = 31 * result + Arrays.hashCode(fieldNames); | ||
int result = Arrays.hashCode(fieldNames); | ||
result = 31 * result + Objects.hashCode(newCurrentDefault); | ||
return result; | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,7 +25,8 @@ import org.apache.spark.sql.catalyst.trees.TreePattern.{ANALYSIS_AWARE_EXPRESSIO | |
import org.apache.spark.sql.catalyst.util.{GeneratedColumn, IdentityColumn, V2ExpressionBuilder} | ||
import org.apache.spark.sql.catalyst.util.ResolveDefaultColumns.validateDefaultValueExpr | ||
import org.apache.spark.sql.catalyst.util.ResolveDefaultColumnsUtils.{CURRENT_DEFAULT_COLUMN_METADATA_KEY, EXISTS_DEFAULT_COLUMN_METADATA_KEY} | ||
import org.apache.spark.sql.connector.catalog.{Column => V2Column, ColumnDefaultValue, IdentityColumnSpec} | ||
import org.apache.spark.sql.connector.catalog.{Column => V2Column, ColumnDefaultValue, DefaultValue, IdentityColumnSpec} | ||
import org.apache.spark.sql.connector.catalog.CatalogV2Implicits.MultipartIdentifierHelper | ||
import org.apache.spark.sql.connector.expressions.LiteralValue | ||
import org.apache.spark.sql.errors.QueryCompilationErrors | ||
import org.apache.spark.sql.internal.connector.ColumnImpl | ||
|
@@ -184,6 +185,23 @@ object ColumnDefinition { | |
} | ||
} | ||
|
||
case cmd: AlterColumns if cmd.specs.exists(_.newDefaultExpression.isDefined) => | ||
// Wrap analysis errors for default values in a more user-friendly message. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not related to this PR but we can probably do the same error message improvement for |
||
cmd.specs.foreach { c => | ||
c.newDefaultExpression.foreach { d => | ||
if (!d.resolved) { | ||
throw QueryCompilationErrors.defaultValuesUnresolvedExprError( | ||
"ALTER TABLE ALTER COLUMN", c.column.name.quoted, d.originalSQL, null) | ||
} | ||
validateDefaultValueExpr(d, "ALTER TABLE ALTER COLUMN", | ||
c.column.name.quoted, d.dataType) | ||
if (!d.deterministic) { | ||
throw QueryCompilationErrors.defaultValueNonDeterministicError( | ||
"ALTER TABLE ALTER COLUMN", c.column.name.quoted, d.originalSQL) | ||
} | ||
} | ||
} | ||
|
||
case _ => | ||
} | ||
} | ||
|
@@ -241,4 +259,13 @@ case class DefaultValueExpression( | |
case _ => | ||
throw QueryCompilationErrors.defaultValueNotConstantError(statement, colName, originalSQL) | ||
} | ||
|
||
// Convert the default expression to DefaultValue, which is required by DS v2 APIs. | ||
def toV2CurrentDefault(statement: String, colName: String): DefaultValue = child match { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Alter table alter column" doesnt change 'exists default', so we can use the narrower 'DefaultValue' class here that doesnt have that field. |
||
case Literal(_, _) => | ||
val currentDefault = analyzedChild.flatMap(new V2ExpressionBuilder(_).build()) | ||
new DefaultValue(originalSQL, currentDefault.orNull) | ||
case _ => | ||
throw QueryCompilationErrors.defaultValueNotConstantError(statement, colName, originalSQL) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shall we mark this function as deprecated and encourage users to call
newCurrentDefault
?