Skip to content

Commit

Permalink
feat: add default_columns property to write op/stmt.
Browse files Browse the repository at this point in the history
  • Loading branch information
ashigeru committed Jul 25, 2024
1 parent 625bbca commit 3a7b120
Show file tree
Hide file tree
Showing 10 changed files with 204 additions and 41 deletions.
1 change: 1 addition & 0 deletions docs/ja/relational-operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ DML系演算子は、リレーションの出力を行わない関係演算子
* `columns*` - 出力する列の一覧
* `source` - 入力リレーション上の列
* `destination` - 出力先テーブル上の列
* `default_columns*` - デフォルト値を出力する対象テーブル上の列の一覧
* その他の特性
* `destination` に指定するインデックスは、 `keys` で指定するキーに対して一意なエントリを持つようなインデックスでなければならない
* 標準的にはプライマリキーをキーとするようなインデックス
Expand Down
23 changes: 21 additions & 2 deletions include/takatori/relation/write.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class write : public expression {
/// @brief column mapping between the input relation and the destination table.
using column = details::mapping_element;

/// @brief column on the destination table.
using default_column = descriptor::variable;

/// @brief the kind of this expression.
static constexpr inline expression_kind tag = expression_kind::write;

Expand All @@ -40,25 +43,29 @@ class write : public expression {
* @param destination the target external relation, must represent an index to distinguish individual entries
* @param keys the column mappings between the input relation and the destination table for identifying target rows
* @param columns the column mappings between the input relation and the destination table for setting row contents
* @param default_columns list of the columns to set each default value
*/
explicit write(
operator_kind_type operator_kind,
descriptor::relation destination,
std::vector<key> keys,
std::vector<column> columns) noexcept;
std::vector<column> columns,
std::vector<default_column> default_columns = {}) noexcept;

/**
* @brief creates a new object.
* @param operator_kind the write operation kind
* @param destination the target external relation, must represent an index to distinguish individual entries
* @param keys the column mappings between the input relation and the destination table for identifying target rows
* @param columns the column mappings between the input relation and the destination table for setting row contents
* @param default_columns list of the columns to set each default value
*/
explicit write(
operator_kind_type operator_kind,
descriptor::relation destination,
std::initializer_list<key> keys,
std::initializer_list<column> columns);
std::initializer_list<column> columns,
std::initializer_list<default_column> default_columns = {});

/**
* @brief creates a new object.
Expand Down Expand Up @@ -129,6 +136,17 @@ class write : public expression {
/// @copydoc columns()
[[nodiscard]] std::vector<column> const& columns() const noexcept;

/**
* @brief returns the columns that should be written each default value.
* @return the columns that should be written each default value.
* @note this only includes the columns explicitly specified to be set to default values (e.g., specified `DEFAULT`).
* @note this may include columns that marked as "read-only."
*/
[[nodiscard]] std::vector<default_column>& default_columns() noexcept;

/// @copydoc default_columns()
[[nodiscard]] std::vector<default_column> const& default_columns() const noexcept;

/**
* @brief returns whether or not the two elements are equivalent.
* @details This operation does not consider which the input/output ports are connected to.
Expand Down Expand Up @@ -167,6 +185,7 @@ class write : public expression {
descriptor::relation destination_;
std::vector<key> keys_;
std::vector<column> columns_;
std::vector<default_column> default_columns_;
};

/**
Expand Down
23 changes: 21 additions & 2 deletions include/takatori/statement/write.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class write final : public statement {
/// @brief tuple of each column value.
using tuple = details::write_tuple;

/// @brief column on the destination table.
using default_column = descriptor::variable;

/// @brief the kind of this statement.
static constexpr inline statement_kind tag = statement_kind::write;

Expand All @@ -41,25 +44,29 @@ class write final : public statement {
* @param destination the target external relation, must represent an index to distinguish individual entries
* @param columns the destination columns
* @param tuples the each row data; must be ordered by `columns`
* @param default_columns list of the columns to set each default value
*/
explicit write(
operator_kind_type operator_kind,
descriptor::relation destination,
std::vector<column> columns,
std::vector<tuple> tuples) noexcept;
std::vector<tuple> tuples,
std::vector<default_column> default_columns = {}) noexcept;

/**
* @brief creates a new instance.
* @param operator_kind the write operation kind
* @param destination the target external relation, must represent an index to distinguish individual entries
* @param columns the destination columns
* @param tuples the each row data; must be ordered by `columns`
* @param default_columns list of the columns to set each default value
*/
explicit write(
operator_kind_type operator_kind,
descriptor::relation destination,
std::initializer_list<column> columns,
std::initializer_list<std::initializer_list<util::rvalue_reference_wrapper<scalar::expression>>> tuples);
std::initializer_list<std::initializer_list<util::rvalue_reference_wrapper<scalar::expression>>> tuples,
std::initializer_list<default_column> default_columns = {});

/**
* @brief creates a new object.
Expand Down Expand Up @@ -119,6 +126,17 @@ class write final : public statement {
/// @copydoc tuples()
[[nodiscard]] tree::tree_fragment_vector<tuple> const& tuples() const noexcept;

/**
* @brief returns the columns that should be written each default value.
* @return the columns that should be written each default value.
* @note this only includes the columns explicitly specified to be set to default values (e.g., specified `DEFAULT`).
* @note this may include columns that marked as "read-only."
*/
[[nodiscard]] std::vector<default_column>& default_columns() noexcept;

/// @copydoc default_columns()
[[nodiscard]] std::vector<default_column> const& default_columns() const noexcept;

/**
* @brief returns whether or not the two elements are equivalent.
* @param a the first element
Expand Down Expand Up @@ -154,6 +172,7 @@ class write final : public statement {
descriptor::relation destination_;
std::vector<column> columns_;
tree::tree_fragment_vector<tuple> tuples_;
std::vector<default_column> default_columns_;
};

} // namespace takatori::statement
57 changes: 38 additions & 19 deletions src/takatori/relation/write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,50 @@ write::write(
operator_kind_type operator_kind,
descriptor::relation destination,
std::vector<key> keys,
std::vector<column> columns) noexcept
: input_(*this, 0)
, operator_kind_(operator_kind)
, destination_(std::move(destination))
, keys_(std::move(keys))
, columns_(std::move(columns))
std::vector<column> columns,
std::vector<default_column> default_columns) noexcept :
input_ { *this, 0 },
operator_kind_ { operator_kind },
destination_ { std::move(destination) },
keys_ { std::move(keys) },
columns_ { std::move(columns) },
default_columns_ { std::move(default_columns) }
{}

write::write(
operator_kind_type operator_kind,
descriptor::relation destination,
std::initializer_list<key> keys,
std::initializer_list<column> columns)
: write(
std::initializer_list<column> columns,
std::initializer_list<default_column> default_columns) :
write {
operator_kind,
std::move(destination),
{ keys.begin(), keys.end() },
{ columns.begin(), columns.end() })
{ columns.begin(), columns.end() },
{ default_columns.begin(), default_columns.end() },
}
{}


write::write(util::clone_tag_t, write const& other)
: write(
write::write(util::clone_tag_t, write const& other) :
write {
other.operator_kind_,
other.destination_,
{ other.keys_ },
{ other.columns_ })
other.keys_,
other.columns_,
other.default_columns_
}
{}

write::write(util::clone_tag_t, write&& other)
: write(
write::write(util::clone_tag_t, write&& other) :
write {
other.operator_kind_,
std::move(other.destination_),
{ std::move(other.keys_) },
{ std::move(other.columns_) })
std::move(other.keys_),
std::move(other.columns_),
std::move(other.default_columns_)
}
{}

expression_kind write::kind() const noexcept {
Expand Down Expand Up @@ -117,11 +126,20 @@ std::vector<write::column> const& write::columns() const noexcept {
return columns_;
}

std::vector<write::default_column>& write::default_columns() noexcept {
return default_columns_;
}

std::vector<write::default_column> const& write::default_columns() const noexcept {
return default_columns_;
}

bool operator==(write const& a, write const& b) noexcept {
return a.operator_kind() == b.operator_kind()
&& a.destination() == b.destination()
&& a.keys() == b.keys()
&& a.columns() == b.columns();
&& a.columns() == b.columns()
&& a.default_columns() == b.default_columns();
}

bool operator!=(write const& a, write const& b) noexcept {
Expand All @@ -133,7 +151,8 @@ std::ostream& operator<<(std::ostream& out, write const& value) {
<< "operator_kind=" << value.operator_kind() << ", "
<< "destination=" << value.destination() << ", "
<< "keys=" << util::print_support { value.keys() } << ", "
<< "columns=" << util::print_support { value.columns() } << ")";
<< "columns=" << util::print_support { value.columns() } << ", "
<< "default_columns=" << util::print_support { value.default_columns() } << ")";
}

bool write::equals(expression const& other) const noexcept {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ void relation_expression_property_scanner::operator()(relation::write const& ele
acceptor_.property_begin("columns"sv);
accept_foreach(element.columns());
acceptor_.property_end();

acceptor_.property_begin("default_columns"sv);
accept_foreach(element.default_columns());
acceptor_.property_end();
}

void relation_expression_property_scanner::operator()(relation::values const& element) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ void statement_property_scanner::operator()(statement::write const& element) {
acceptor_.property_begin("tuples"sv);
accept_foreach(element.tuples());
acceptor_.property_end();

acceptor_.property_begin("default_columns"sv);
accept_foreach(element.default_columns());
acceptor_.property_end();
}

void statement_property_scanner::operator()(statement::create_table const& element) {
Expand Down
55 changes: 37 additions & 18 deletions src/takatori/statement/write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,53 @@ write::write(
operator_kind_type operator_kind,
descriptor::relation destination,
std::vector<column> columns,
std::vector<tuple> tuples) noexcept
: operator_kind_(operator_kind)
, destination_(std::move(destination))
, columns_(std::move(columns))
, tuples_(*this, std::move(tuples))
std::vector<tuple> tuples,
std::vector<default_column> default_columns) noexcept :
operator_kind_ { operator_kind },
destination_ { std::move(destination) },
columns_ { std::move(columns) },
tuples_ { *this, std::move(tuples) },
default_columns_ { std::move(default_columns) }
{}

write::write(
operator_kind_type operator_kind,
descriptor::relation destination,
std::initializer_list<column> columns,
std::initializer_list<std::initializer_list<util::rvalue_reference_wrapper<scalar::expression>>> tuples)
: write(
std::initializer_list<std::initializer_list<util::rvalue_reference_wrapper<scalar::expression>>> tuples,
std::initializer_list<default_column> default_columns) :
write {
operator_kind,
std::move(destination),
{ columns.begin(), columns.end() },
{})
{},
{ default_columns.begin(), default_columns.end() }
}
{
tuples_.reserve(tuples.size());
for (auto&& tuple : tuples) {
tuples_.emplace_back(tuple);
}
}

write::write(util::clone_tag_t, write const& other) noexcept
: write(
write::write(util::clone_tag_t, write const& other) noexcept :
write {
other.operator_kind_,
other.destination_,
{ other.columns_ },
tree::forward(other.tuples_))
other.columns_,
tree::forward(other.tuples_),
other.default_columns_,
}
{}

write::write(util::clone_tag_t, write&& other) noexcept
: write(
write::write(util::clone_tag_t, write&& other) noexcept :
write {
other.operator_kind_,
std::move(other.destination_),
{ std::move(other.columns_) },
tree::forward(std::move(other.tuples_)))
std::move(other.columns_),
tree::forward(std::move(other.tuples_)),
std::move(other.default_columns_),
}
{}

statement_kind write::kind() const noexcept {
Expand Down Expand Up @@ -96,11 +105,20 @@ tree::tree_fragment_vector<write::tuple> const& write::tuples() const noexcept {
return tuples_;
}

std::vector<write::default_column>& write::default_columns() noexcept {
return default_columns_;
}

std::vector<write::default_column> const& write::default_columns() const noexcept {
return default_columns_;
}

bool operator==(write const& a, write const& b) noexcept {
return a.operator_kind() == b.operator_kind()
&& a.destination() == b.destination()
&& a.columns() == b.columns()
&& a.tuples() == b.tuples();
&& a.tuples() == b.tuples()
&& a.default_columns() == b.default_columns();
}

bool operator!=(write const& a, write const& b) noexcept {
Expand All @@ -112,7 +130,8 @@ std::ostream& operator<<(std::ostream& out, write const& value) {
<< "operator_kind=" << value.operator_kind() << ", "
<< "destination=" << value.destination() << ", "
<< "columns=" << util::print_support { value.columns() } << ", "
<< "tuples=" << value.tuples() << ")";
<< "tuples=" << value.tuples() << ", "
<< "default_columns=" << util::print_support { value.default_columns() } << ")";
}

bool write::equals(statement const& other) const noexcept {
Expand Down
Loading

0 comments on commit 3a7b120

Please sign in to comment.