absl::Status SchemaUpdaterImpl::AlterVectorIndex()

in backend/schema/updater/schema_updater.cc [5174:5266]


absl::Status SchemaUpdaterImpl::AlterVectorIndex(
    const ddl::AlterVectorIndex& alter_index) {
  const Index* index = latest_schema_->FindIndex(alter_index.index_name());

  if (index == nullptr || !index->is_vector_index()) {
    return error::IndexNotFound(alter_index.index_name());
  }

  const Table* indexed_table = index->indexed_table();
  const Table* indexed_data_table = index->index_data_table();
  ZETASQL_RET_CHECK(indexed_table != nullptr)
      << "No indexed table found for the index ";
  ZETASQL_RET_CHECK(indexed_data_table != nullptr)
      << "No index data table found for the index ";

  switch (alter_index.alter_type_case()) {
    case ddl::AlterVectorIndex::kAddStoredColumn: {
      const std::string& column_name =
          alter_index.add_stored_column().column().name();

      if (indexed_table->FindColumn(column_name) == nullptr) {
        return error::VectorIndexStoredColumnNotFound(alter_index.index_name(),
                                                      column_name);
      }
      for (const Column* column : index->stored_columns()) {
        if (column->Name() == column_name) {
          return error::VectorIndexStoredColumnAlreadyExists(
              alter_index.index_name(), column_name);
        }
      }
      if (indexed_table->FindKeyColumn(column_name) != nullptr) {
        return error::VectorIndexStoredColumnIsKey(
            alter_index.index_name(), column_name, indexed_table->Name());
      }
      if (indexed_data_table->FindColumn(column_name) != nullptr) {
        return error::VectorIndexStoredColumnAlreadyPrimaryKey(
            alter_index.index_name(), column_name);
      }

      ZETASQL_ASSIGN_OR_RETURN(const Column* new_index_data_table_column,
                       CreateIndexDataTableColumn(indexed_table, column_name,
                                                  indexed_data_table, false));

      ZETASQL_RETURN_IF_ERROR(AlterNode<Table>(
          indexed_data_table,
          [new_index_data_table_column](Table::Editor* editor) -> absl::Status {
            editor->add_column(new_index_data_table_column);
            return absl::OkStatus();
          }));
      ZETASQL_RETURN_IF_ERROR(AlterNode<Index>(
          index,
          [new_index_data_table_column](Index::Editor* editor) -> absl::Status {
            editor->add_stored_column(new_index_data_table_column);
            return absl::OkStatus();
          }));
      break;
    }
    case ddl::AlterVectorIndex::kDropStoredColumn: {
      const std::string& column_name = alter_index.drop_stored_column();
      if (indexed_data_table->FindColumn(column_name) == nullptr) {
        return error::ColumnNotFound(index->Name(), column_name);
      }
      auto stored_columns = index->stored_columns();
      bool is_stored_column = absl::c_any_of(
          stored_columns,
          [column_name](const Column* c) { return c->Name() == column_name; });
      if (!is_stored_column) {
        if (!absl::c_any_of(index->key_columns(),
                            [column_name](const KeyColumn* c) {
                              return c->column()->Name() == column_name;
                            })) {
          return error::ColumnNotFound(index->Name(), column_name);
        }
        return error::VectorIndexNotStoredColumn(alter_index.index_name(),
                                                 column_name);
      }

      const Column* drop_column = indexed_data_table->FindColumn(column_name);
      return DropNode(drop_column);
      break;
    }
    case ddl::AlterVectorIndex::kSetOptions: {
      return error::AlterVectorIndexSetOptionsUnsupported();
    }
    case ddl::AlterVectorIndex::kAlterStoredColumn: {
      return error::AlterVectorIndexStoredColumnUnsupported();
    }
    default:
      ZETASQL_RET_CHECK_FAIL() << "Invalid alter index type: "
                       << absl::StrCat(alter_index);
  }
  return absl::OkStatus();
}