backend/schema/builders/column_builder.h (299 lines of code) (raw):
//
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef THIRD_PARTY_CLOUD_SPANNER_EMULATOR_BACKEND_SCHEMA_BUILDERS_COLUMN_BUILDER_H
#define THIRD_PARTY_CLOUD_SPANNER_EMULATOR_BACKEND_SCHEMA_BUILDERS_COLUMN_BUILDER_H
#include <algorithm>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include "zetasql/public/type.h"
#include "absl/container/flat_hash_set.h"
#include "absl/log/check.h"
#include "absl/memory/memory.h"
#include "absl/strings/match.h"
#include "backend/common/ids.h"
#include "backend/schema/catalog/change_stream.h"
#include "backend/schema/catalog/column.h"
#include "backend/schema/catalog/locality_group.h"
#include "backend/schema/graph/schema_node.h"
#include "backend/schema/validators/column_validator.h"
namespace google {
namespace spanner {
namespace emulator {
namespace backend {
class Table;
class Column::Builder {
public:
Builder()
: instance_(absl::WrapUnique(new Column(
ColumnValidator::Validate, ColumnValidator::ValidateUpdate))) {}
std::unique_ptr<const Column> build() { return std::move(instance_); }
const Column* get() const { return instance_.get(); }
Builder& set_id(const ColumnID id) {
instance_->id_ = id;
return *this;
}
Builder& set_name(const std::string& name) {
instance_->name_ = name;
return *this;
}
Builder& set_type(const zetasql::Type* type) {
instance_->type_ = type;
return *this;
}
Builder& set_nullable(bool is_nullable) {
instance_->is_nullable_ = is_nullable;
return *this;
}
Builder& set_is_placement_key(bool is_placement_key) {
instance_->is_placement_key_ = is_placement_key;
return *this;
}
Builder& set_expression(const std::string& expression) {
instance_->expression_ = expression;
return *this;
}
Builder& set_original_expression(const std::string& expression) {
instance_->original_expression_ = expression;
return *this;
}
Builder& set_has_default_value(bool has_default_value) {
instance_->has_default_value_ = has_default_value;
return *this;
}
Builder& set_is_identity_column(bool is_identity_column) {
instance_->is_identity_column_ = is_identity_column;
return *this;
}
Builder& clear_expression() {
instance_->expression_.reset();
return *this;
}
Builder& clear_original_expression() {
instance_->original_expression_.reset();
return *this;
}
Builder& add_dependent_column_name(const std::string& column_name) {
instance_->dependent_column_names_.push_back(column_name);
return *this;
}
Builder& set_declared_max_length(std::optional<int64_t> length) {
instance_->declared_max_length_ = length;
return *this;
}
Builder& set_vector_length(std::optional<int32_t> vector_length) {
instance_->vector_length_ = vector_length;
return *this;
}
Builder& set_table(const Table* table) {
instance_->table_ = table;
return *this;
}
Builder& set_allow_commit_timestamp(std::optional<bool> allow) {
instance_->allows_commit_timestamp_ = allow;
return *this;
}
Builder& set_source_column(const Column* column) {
instance_->source_column_ = column;
instance_->type_ = column->type_;
instance_->declared_max_length_ = column->declared_max_length_;
instance_->vector_length_ = column->vector_length_;
return *this;
}
Builder& set_hidden(bool hidden) {
instance_->hidden_ = hidden;
return *this;
}
Builder& set_sequences_used(
const absl::flat_hash_set<const SchemaNode*>& sequences_used) {
instance_->sequences_used_.clear();
instance_->sequences_used_.reserve(sequences_used.size());
for (const SchemaNode* node : sequences_used) {
instance_->sequences_used_.push_back(node);
}
return *this;
}
Builder& set_udf_dependencies(
const absl::flat_hash_set<const SchemaNode*>& udf_dependencies) {
instance_->udf_dependencies_.clear();
instance_->udf_dependencies_.reserve(udf_dependencies.size());
for (const SchemaNode* node : udf_dependencies) {
instance_->udf_dependencies_.push_back(node);
}
return *this;
}
Builder& set_stored(bool stored) {
instance_->is_stored_ = stored;
return *this;
}
Builder& set_postgresql_oid(std::optional<uint32_t> postgresql_oid) {
if (postgresql_oid.has_value()) {
instance_->set_postgresql_oid(postgresql_oid.value());
}
return *this;
}
Builder& set_locality_group(const LocalityGroup* locality_group) {
instance_->locality_group_ = locality_group;
return *this;
}
private:
std::unique_ptr<Column> instance_;
};
class Column::Editor {
public:
explicit Editor(Column* instance) : instance_(instance) {}
const Column* get() const { return instance_; }
Editor& set_type(const zetasql::Type* type) {
instance_->type_ = type;
return *this;
}
Editor& set_nullable(bool is_nullable) {
instance_->is_nullable_ = is_nullable;
return *this;
}
Editor& set_expression(const std::string& expression) {
instance_->expression_ = expression;
return *this;
}
Editor& set_original_expression(const std::string& expression) {
instance_->original_expression_ = expression;
return *this;
}
Editor& set_has_default_value(bool has_default_value) {
instance_->has_default_value_ = has_default_value;
return *this;
}
Editor& set_is_identity_column(bool is_identity_column) {
instance_->is_identity_column_ = is_identity_column;
return *this;
}
Editor& clear_expression() {
instance_->expression_.reset();
return *this;
}
Editor& add_change_stream(const ChangeStream* change_stream) {
instance_->change_streams_.push_back(change_stream);
return *this;
}
Editor& add_change_stream_explicitly_tracking_column(
const ChangeStream* change_stream) {
instance_->change_streams_explicitly_tracking_column_.push_back(
change_stream);
return *this;
}
Editor& remove_change_stream(const ChangeStream* change_stream) {
auto itr = std::find_if(
instance_->change_streams_.begin(), instance_->change_streams_.end(),
[change_stream](const auto& change_stream_element) {
return absl::EqualsIgnoreCase(change_stream->Name(),
change_stream_element->Name());
});
ABSL_DCHECK(itr != instance_->change_streams_.end());
instance_->change_streams_.erase(itr);
// Remove the change stream from the list of change streams explicitly
// tracking the column if exists.
auto itr_tracking_columns = std::find_if(
instance_->change_streams_explicitly_tracking_column_.begin(),
instance_->change_streams_explicitly_tracking_column_.end(),
[change_stream](const auto& change_stream_element) {
return absl::EqualsIgnoreCase(change_stream->Name(),
change_stream_element->Name());
});
if (itr_tracking_columns !=
instance_->change_streams_explicitly_tracking_column_.end()) {
instance_->change_streams_explicitly_tracking_column_.erase(
itr_tracking_columns);
}
return *this;
}
Editor& set_locality_group(const LocalityGroup* locality_group) {
instance_->locality_group_ = locality_group;
return *this;
}
Editor& clear_locality_group() {
instance_->locality_group_ = nullptr;
return *this;
}
Editor& clear_original_expression() {
instance_->original_expression_.reset();
return *this;
}
Editor& add_dependent_column_name(const std::string& column_name) {
instance_->dependent_column_names_.push_back(column_name);
return *this;
}
Editor& set_declared_max_length(std::optional<int64_t> length) {
instance_->declared_max_length_ = length;
return *this;
}
Editor& set_vector_length(std::optional<int32_t> vector_length) {
instance_->vector_length_ = vector_length;
return *this;
}
Editor& set_allow_commit_timestamp(std::optional<bool> allow) {
instance_->allows_commit_timestamp_ = allow;
return *this;
}
Editor& set_sequences_used(
const absl::flat_hash_set<const SchemaNode*>& sequences_used) {
instance_->sequences_used_.clear();
instance_->sequences_used_.reserve(sequences_used.size());
for (const SchemaNode* node : sequences_used) {
instance_->sequences_used_.push_back(node);
}
return *this;
}
Editor& set_udf_dependencies(
const absl::flat_hash_set<const SchemaNode*>& udf_dependencies) {
instance_->udf_dependencies_.clear();
instance_->udf_dependencies_.reserve(udf_dependencies.size());
for (const SchemaNode* udf : udf_dependencies) {
instance_->udf_dependencies_.push_back(udf);
}
return *this;
}
Editor& set_stored(bool stored) {
instance_->is_stored_ = stored;
return *this;
}
Editor& set_postgresql_oid(std::optional<uint32_t> postgresql_oid) {
if (postgresql_oid.has_value()) {
instance_->set_postgresql_oid(postgresql_oid.value());
}
return *this;
}
private:
// Not owned.
Column* instance_;
};
class KeyColumn::Builder {
public:
Builder()
: instance_(absl::WrapUnique(
new KeyColumn(KeyColumnValidator::Validate,
KeyColumnValidator::ValidateUpdate))) {}
std::unique_ptr<const KeyColumn> build() { return std::move(instance_); }
const KeyColumn* get() const { return instance_.get(); }
Builder& set_column(const Column* column) {
instance_->column_ = column;
return *this;
}
Builder& set_descending(bool desceding) {
instance_->is_descending_ = desceding;
return *this;
}
Builder& set_nulls_last(bool nulls_last) {
instance_->is_nulls_last_ = nulls_last;
return *this;
}
Builder& set_postgresql_oid(std::optional<uint32_t> postgresql_oid) {
if (postgresql_oid.has_value()) {
instance_->set_postgresql_oid(postgresql_oid.value());
}
return *this;
}
private:
std::unique_ptr<KeyColumn> instance_;
};
} // namespace backend
} // namespace emulator
} // namespace spanner
} // namespace google
#endif // THIRD_PARTY_CLOUD_SPANNER_EMULATOR_BACKEND_SCHEMA_BUILDERS_COLUMN_BUILDER_H