in backend/schema/parser/ddl_parser.cc [1022:1137]
void VisitColumnNodeAlter(const std::string& table_name,
const std::string& column_name,
const SimpleNode* node, absl::string_view ddl_text,
DDLStatement* statement,
std::vector<std::string>* errors) {
CheckNode(node, JJTCOLUMN_DEF_ALTER);
const SimpleNode* child = GetChildNode(node, 0);
AlterTable* alter_table = statement->mutable_alter_table();
if (child->getId() == JJTOPTIONS_CLAUSE) {
// "ALTER COLUMN c SET OPTIONS (...)" does not contain the
// column TYPE or NOT NULL attributes. Translate this into a
// SetColumnOptions statement which does not take these
// attributes as input, and the schema change code will keep
// these attributes unchanged.
SetColumnOptions* set_options = statement->mutable_set_column_options();
SetColumnOptions::ColumnPath* path = set_options->add_column_path();
path->set_table_name(table_name);
path->set_column_name(column_name);
VisitColumnOptionListNode(child, 0 /* option_list_offset */,
set_options->mutable_options(), errors);
return;
}
if (child->getId() == JJTCOLUMN_DEF_ALTER_ATTRS) {
// For "ALTER COLUMN c TYPE NOT NULL"
alter_table->set_table_name(table_name);
ColumnDefinition* column =
alter_table->mutable_alter_column()->mutable_column();
VisitColumnNodeAlterAttrs(child, column_name, column, ddl_text, errors);
return;
}
alter_table->set_table_name(table_name);
AlterTable::AlterColumn* alter_column = alter_table->mutable_alter_column();
ColumnDefinition* column = alter_column->mutable_column();
column->set_column_name(column_name);
// `type` is required in ColumnDefinition, so set it to NONE here.
column->set_type(ColumnDefinition::NONE);
switch (child->getId()) {
case JJTCOLUMN_DEFAULT_CLAUSE: {
// "ALTER COLUMN c SET DEFAULT " does not contain the column TYPE or
// NOT NULL attributes.
alter_column->set_operation(AlterTable::AlterColumn::SET_DEFAULT);
VisitColumnDefaultClauseNode(child, column, ddl_text);
break;
}
case JJTDROP_COLUMN_DEFAULT: {
// "ALTER COLUMN c DROP DEFAULT " does not contain the column TYPE or
// NOT NULL attributes.
alter_column->set_operation(AlterTable::AlterColumn::DROP_DEFAULT);
column->clear_column_default();
break;
}
case JJTSET_NOT_NULL: {
errors->push_back(
"ALTER COLUMN SET NOT NULL not supported without a column type");
break;
}
case JJTDROP_NOT_NULL: {
errors->push_back(
"ALTER COLUMN DROP NOT NULL not supported without a column type");
break;
}
case JJTRESTART_COUNTER: {
if (!EmulatorFeatureFlags::instance().flags().enable_identity_columns) {
errors->push_back("Identity columns are not supported.");
return;
}
// The reason to use two separate fields is because we would like to have
// the capability to support updating multiple properties in a single
// statement. Also, if we supported RESTART COUNTER without WITH, we can
// set this bool to true but not set the start_with_counter field.
alter_column->set_operation(AlterTable::AlterColumn::ALTER_IDENTITY);
alter_column->set_identity_alter_start_with_counter(true);
column->mutable_identity_column()->set_start_with_counter(
child->image_as_int64());
break;
}
case JJTSKIP_RANGE_MIN: {
if (!EmulatorFeatureFlags::instance().flags().enable_identity_columns) {
errors->push_back("Identity columns are not supported.");
return;
}
if (node->jjtGetNumChildren() != 2) {
// It should theoretically never happen.
errors->push_back(
"skip_range_max is missing in ALTER IDENTITY SET SKIP RANGE.");
return;
}
const SimpleNode* next_child = GetChildNode(node, 1);
CheckNode(next_child, JJTSKIP_RANGE_MAX);
alter_column->set_operation(AlterTable::AlterColumn::ALTER_IDENTITY);
alter_column->set_identity_alter_skip_range(true);
column->mutable_identity_column()->set_skip_range_min(
child->image_as_int64());
column->mutable_identity_column()->set_skip_range_max(
next_child->image_as_int64());
break;
}
case JJTNO_SKIP_RANGE: {
if (!EmulatorFeatureFlags::instance().flags().enable_identity_columns) {
errors->push_back("Identity columns are not supported.");
return;
}
alter_column->set_operation(AlterTable::AlterColumn::ALTER_IDENTITY);
alter_column->set_identity_alter_skip_range(true);
column->mutable_identity_column()->clear_skip_range_min();
column->mutable_identity_column()->clear_skip_range_max();
break;
}
default:
ABSL_LOG(FATAL) << "Unexpected alter column type: "
<< GetChildNode(node, 1)->toString();
}
}