Skip to content

Commit

Permalink
feat: support INSERT INTO ~ DEFAULT VALUES.
Browse files Browse the repository at this point in the history
  • Loading branch information
ashigeru committed Aug 21, 2024
1 parent e887211 commit 8e03bca
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 18 deletions.
49 changes: 41 additions & 8 deletions src/mizugaki/analyzer/details/analyze_statement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,6 @@ class engine {
auto info = std::move(*info_opt);
auto index = info.primary_index();

auto graph = std::make_unique<::takatori::relation::graph_type>();

auto destination_columns = create_vector<::yugawara::storage::column const*>();
auto columns_context = create_vector<scalar_value_context>();

Expand Down Expand Up @@ -201,14 +199,12 @@ class engine {
}
}

// empty source means "INSERT INTO ~ DEFAULT VALUES"
if (!stmt.expression()) {
// FIXME: impl treat "DEFAULT VALUES" clause
context_.report(
sql_analyzer_code::unsupported_feature,
"DEFAULT VALUES clause is yet not supported",
stmt.region());
return {};
return process_insert_default_values(stmt, info);
}

auto graph = std::make_unique<::takatori::relation::graph_type>();
auto source = analyze_query_expression(
context_,
*graph,
Expand Down Expand Up @@ -305,6 +301,43 @@ class engine {
return graph;
}

[[nodiscard]] result_type process_insert_default_values(
ast::statement::insert_statement const& stmt,
relation_info const& relation) {
auto index = relation.primary_index();
auto write_operator = compute_write_type(stmt);
if (!write_operator) {
return {};
}

if (context_.options()->prefer_write_statement()) {
auto write_tuples = create_vector<tstatement::write::tuple>(1);
write_tuples.emplace_back(::takatori::util::reference_vector<tscalar::expression> {});
return context_.create<tstatement::write>(
stmt.region(),
*write_operator,
factory_(index),
std::vector<tstatement::write::column> {},
std::move(write_tuples));
}

auto graph = std::make_unique<::takatori::relation::graph_type>();
auto rows = create_vector<trelation::values::row>(1);
rows.emplace_back(::takatori::util::reference_vector<tscalar::expression> {});
auto&& op_values = graph->insert(context_.create<trelation::values>(
stmt.table_name()->region(),
std::vector<trelation::values::column> {},
std::move(rows)));
auto&& op_write = graph->insert(context_.create<trelation::write>(
stmt.table_name()->region(),
*write_operator,
factory_(index),
std::vector<trelation::write::key> {},
std::vector<trelation::write::column> {}));
op_write.input().connect_to(op_values.output());
return graph;
}

[[nodiscard]] std::optional<trelation::write_kind> compute_write_type(
ast::statement::insert_statement const& stmt) {
using from = ast::statement::insert_statement_option;
Expand Down
69 changes: 59 additions & 10 deletions test/mizugaki/analyzer/details/analyze_statement_insert_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,65 @@ TEST_F(analyze_statement_insert_test, as_write_statement) {
}
}

TEST_F(analyze_statement_insert_test, default_values) {
options_.prefer_write_statement() = false;
auto table = install_table("testing");

auto r = analyze_statement(context(), ast::statement::insert_statement {
id("testing"),
{},
{},
});
auto alternative = std::get_if<execution_plan_result_type >(&r);
ASSERT_TRUE(alternative) << diagnostics();
expect_no_error();

auto&& graph = **alternative;
ASSERT_EQ(graph.size(), 2);

auto first = find_first<trelation::values>(graph);
ASSERT_TRUE(first);
ASSERT_EQ(first->columns().size(), 0);
ASSERT_EQ(first->rows().size(), 1);
ASSERT_EQ(first->rows()[0].elements().size(), 0);

auto last = find_last<trelation::write>(graph);
ASSERT_TRUE(last);
EXPECT_EQ(find_next(*first).get(), last.get());

EXPECT_EQ(last->operator_kind(), tstatement::write_kind::insert);
EXPECT_EQ(&extract<::yugawara::storage::index>(last->destination()).table(), table.get());

ASSERT_EQ(last->keys().size(), 0);
ASSERT_EQ(last->columns().size(), 0);
}

TEST_F(analyze_statement_insert_test, default_values_as_write_statement) {
options_.prefer_write_statement() = true;
auto table = install_table("testing");

auto r = analyze_statement(context(), ast::statement::insert_statement {
id("testing"),
{},
{},
});
auto alternative = std::get_if<statement_result_type>(&r);
ASSERT_TRUE(alternative) << diagnostics();
expect_no_error();

ASSERT_EQ((*alternative)->kind(), tstatement::statement_kind::write);
auto&& stmt = downcast<tstatement::write>(**alternative);

EXPECT_EQ(stmt.operator_kind(), tstatement::write_kind::insert);
EXPECT_EQ(&extract<::yugawara::storage::index>(stmt.destination()).table(), table.get());

auto&& columns = stmt.columns();
ASSERT_EQ(columns.size(), 0);
auto&& tuples = stmt.tuples();
ASSERT_EQ(tuples.size(), 1);
ASSERT_EQ(tuples[0].elements().size(), 0);
}

TEST_F(analyze_statement_insert_test, values_null) {
options_.prefer_write_statement() = false;
auto table = install_table("testing");
Expand Down Expand Up @@ -422,14 +481,4 @@ TEST_F(analyze_statement_insert_test, inconsistent_query) {
});
}

TEST_F(analyze_statement_insert_test, default_values) {
options_.prefer_write_statement() = false;
auto table = install_table("testing");
invalid(sql_analyzer_code::unsupported_feature, ast::statement::insert_statement {
id("testing"),
{},
{}, // default values
});
}

} // namespace mizugaki::analyzer::details

0 comments on commit 8e03bca

Please sign in to comment.