in backend/schema/updater/schema_updater.cc [1415:1495]
absl::Status SchemaUpdaterImpl::AlterColumnSetDropDefault(
const ddl::AlterTable::AlterColumn& alter_column, const Table* table,
const Column* column, const database_api::DatabaseDialect& dialect,
Column::Editor* editor) {
const ddl::AlterTable::AlterColumn::AlterColumnOp type =
alter_column.operation();
ZETASQL_RET_CHECK(type == ddl::AlterTable::AlterColumn::SET_DEFAULT ||
type == ddl::AlterTable::AlterColumn::DROP_DEFAULT);
const ddl::ColumnDefinition& new_column_def = alter_column.column();
absl::flat_hash_set<const SchemaNode*> dependent_sequences;
if (type == ddl::AlterTable::AlterColumn::SET_DEFAULT) {
if (column->is_generated()) {
return error::CannotSetDefaultValueOnGeneratedColumn(column->FullName());
}
if (column->is_identity_column() &&
(new_column_def.has_column_default() ||
new_column_def.has_generated_column())) {
return error::CannotAlterIdentityColumnToGeneratedOrDefaultColumn(
table->Name(), new_column_def.column_name());
}
std::string expression = new_column_def.column_default().expression();
if (dialect == database_api::DatabaseDialect::POSTGRESQL) {
ZETASQL_ASSIGN_OR_RETURN(expression, TranslatePGExpression(
new_column_def.column_default(), table,
/*ddl_create_table=*/nullptr, *editor));
}
ZETASQL_RET_CHECK(new_column_def.has_column_default() && !expression.empty());
absl::flat_hash_set<const SchemaNode*> udf_dependencies;
absl::Status s = AnalyzeColumnDefaultValue(
expression, column->Name(), column->GetType(), table,
/*ddl_create_table=*/nullptr, &dependent_sequences, &udf_dependencies);
if (!s.ok()) {
return error::ColumnDefaultValueParseError(table->Name(), column->Name(),
s.message());
}
editor->set_postgresql_oid(pg_oid_assigner_->GetNextPostgresqlOid());
editor->set_expression(expression);
editor->set_has_default_value(true);
editor->set_udf_dependencies(udf_dependencies);
const Column* existing_column =
table->FindColumn(alter_column.column().column_name());
if (existing_column == nullptr) {
return error::ColumnNotFound(table->Name(),
alter_column.column().column_name());
}
absl::flat_hash_set<const SchemaNode*> deps;
for (const auto& dep : existing_column->udf_dependencies()) {
deps.insert(dep);
}
// Check for a recursive columns by analyzing the transitive set of
// dependencies, i.e., if the view is a dependency of itself.
auto transitive_deps = GatherTransitiveDependenciesForSchemaNode(deps);
if (std::find_if(transitive_deps.begin(), transitive_deps.end(),
[existing_column](const SchemaNode* dep) {
return (dep->As<const Column>() != nullptr &&
dep->As<const Column>()->Name() ==
existing_column->Name());
}) != transitive_deps.end()) {
return error::ViewReplaceRecursive(existing_column->Name());
}
} else {
if (!column->has_default_value() || column->is_identity_column()) {
return absl::OkStatus();
}
editor->clear_expression();
editor->clear_original_expression();
editor->set_has_default_value(false);
if (!column->is_generated()) {
// Only default and generated columns need an OID. If the default is
// dropped and the column is not generated then unassign the OID.
editor->set_postgresql_oid(std::nullopt);
}
}
// Clear all the old sequence dependencies and set the new ones
editor->set_sequences_used(dependent_sequences);
return absl::OkStatus();
}