Skip to content

Commit

Permalink
feat: support SELECT relation.* syntax.
Browse files Browse the repository at this point in the history
  • Loading branch information
ashigeru committed Jul 7, 2024
1 parent f75f029 commit a51b50b
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 21 deletions.
35 changes: 24 additions & 11 deletions src/mizugaki/analyzer/details/analyze_query_expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ class engine {
// GROUP BY ...
set_function_processor set_functions { context_, graph_ };
optional_ptr<output_port> set_function_entry { output };
if (expr.group_by()) {
if (auto&& group_by = expr.group_by()) {
set_functions.activate();
for (auto&& element : expr.group_by()->elements()) {
for (auto&& element : group_by->elements()) {
auto r = dispatch(*element, set_functions, scope);
if (!r) {
return {};
Expand Down Expand Up @@ -192,13 +192,13 @@ class engine {
}

// SELECT DISTINCT
if (expr.quantifier() == ast::query::set_quantifier::distinct) {
if (auto&& quantifier = expr.quantifier(); quantifier == ast::query::set_quantifier::distinct) {
auto keys = create_vector<tdescriptor::variable>(info.columns().size());
for (auto&& column : info.columns()) {
keys.emplace_back(column.variable());
}
auto&& distinct = graph_.emplace<trelation::intermediate::distinct>(std::move(keys));
distinct.region() = context_.convert(expr.quantifier()->region());
distinct.region() = context_.convert(quantifier->region());
if (!context_.resolve(distinct)) {
return {};
}
Expand Down Expand Up @@ -655,13 +655,26 @@ class engine {
query_scope const& scope,
trelation::project&,
relation_info& info) {
if (elem.qualifier()) {
// FIXME: impl qualified asterisk
context_.report(
sql_analyzer_code::unsupported_feature,
"relation.* in select clause is not yet supported",
elem.region());
return {};
if (auto&& qualifier = elem.qualifier()) {
if (qualifier->node_kind() != ast::scalar::variable_reference::tag) {
context_.report(
sql_analyzer_code::unsupported_feature,
"qualifier must be a plain name",
qualifier->region());
return {};
}
auto&& name = unsafe_downcast<ast::scalar::variable_reference>(*qualifier).name();
auto found = analyze_relation_info_name(context_, *name, scope);
if (!found) {
return {}; // error already reported
}
for (auto&& column : found->columns()) {
if (!column.exported()) {
continue;
}
info.add(column);
}
return { true };
}
for (auto&& relation : scope.references()) {
for (auto&& column : relation.columns()) {
Expand Down
2 changes: 1 addition & 1 deletion src/mizugaki/ast/query/select_asterisk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ select_asterisk::select_asterisk(
scalar::expression&& qualifier,
region_type region) :
select_asterisk {
clone_unique(qualifier),
clone_unique(std::move(qualifier)),
region,
}
{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ class analyze_query_expression_select_test : public test_parent {
EXPECT_FALSE(r) << diagnostics();
EXPECT_NE(count_error(), 0);
}

void invalid(sql_analyzer_code code, ast::query::expression const& expression) {
invalid(expression);
EXPECT_TRUE(find_error(code)) << diagnostics();
}
};

TEST_F(analyze_query_expression_select_test, simple) {
Expand Down Expand Up @@ -177,6 +182,79 @@ TEST_F(analyze_query_expression_select_test, select_asterisk_simple) {
EXPECT_EQ(relation_columns[3].variable(), scan_columns[3].destination());
}

TEST_F(analyze_query_expression_select_test, select_asterisk_qualified) {
auto table = install_table("testing");
trelation::graph_type graph {};

auto r = analyze_query_expression(
context(),
graph,
ast::query::query {
{
ast::query::select_asterisk { vref(id("testing")) },
},
{
ast::table::table_reference {
id("testing"),
}
},
},
{},
{});
ASSERT_TRUE(r) << diagnostics();
expect_no_error();

EXPECT_EQ(graph.size(), 2);
EXPECT_FALSE(r.output().opposite());

auto&& relation = r.relation();
EXPECT_EQ(relation.identifier(), "");

auto relation_columns = relation.columns();
ASSERT_EQ(relation_columns.size(), 4);
{
auto&& column = relation_columns[0];
EXPECT_EQ(column.identifier(), "k");
EXPECT_EQ(column.declaration(), table->columns()[0]);
EXPECT_TRUE(column.exported());
}
{
auto&& column = relation_columns[1];
EXPECT_EQ(column.identifier(), "v");
EXPECT_EQ(column.declaration(), table->columns()[1]);
EXPECT_TRUE(column.exported());
}
{
auto&& column = relation_columns[2];
EXPECT_EQ(column.identifier(), "w");
EXPECT_EQ(column.declaration(), table->columns()[2]);
EXPECT_TRUE(column.exported());
}
{
auto&& column = relation_columns[3];
EXPECT_EQ(column.identifier(), "x");
EXPECT_EQ(column.declaration(), table->columns()[3]);
EXPECT_TRUE(column.exported());
}

// scan - project -
auto&& project = downcast<trelation::project>(r.output().owner());
auto&& scan = *find_prev<trelation::scan>(project);

EXPECT_EQ(extract<::yugawara::storage::index>(scan.source()).table(), *table);

auto&& scan_columns = scan.columns();
ASSERT_EQ(scan_columns.size(), 4);

auto&& project_columns = project.columns();
ASSERT_EQ(project_columns.size(), 0);

EXPECT_EQ(relation_columns[0].variable(), scan_columns[0].destination());
EXPECT_EQ(relation_columns[1].variable(), scan_columns[1].destination());
EXPECT_EQ(relation_columns[2].variable(), scan_columns[2].destination());
EXPECT_EQ(relation_columns[3].variable(), scan_columns[3].destination());
}

TEST_F(analyze_query_expression_select_test, select_multiple_select_element) {
auto table = install_table("testing");
trelation::graph_type graph {};
Expand Down Expand Up @@ -937,7 +1015,7 @@ TEST_F(analyze_query_expression_select_test, order_by_limit) {

TEST_F(analyze_query_expression_select_test, invalid_select_column) {
auto table = install_table("testing");
invalid(ast::query::query {
invalid(sql_analyzer_code::variable_not_found, ast::query::query {
{
ast::query::select_column { vref(id("MISSING")) },
},
Expand All @@ -951,9 +1029,9 @@ TEST_F(analyze_query_expression_select_test, invalid_select_column) {

TEST_F(analyze_query_expression_select_test, invalid_select_asterisk_table) {
auto table = install_table("testing");
invalid(ast::query::query {
invalid(sql_analyzer_code::table_not_found, ast::query::query {
{
ast::query::select_asterisk { vref(id("testing")) },
ast::query::select_asterisk { vref(id("MISSING")) },
},
{
ast::table::table_reference {
Expand All @@ -965,7 +1043,7 @@ TEST_F(analyze_query_expression_select_test, invalid_select_asterisk_table) {

TEST_F(analyze_query_expression_select_test, invalid_from_table) {
auto table = install_table("testing");
invalid(ast::query::query {
invalid(sql_analyzer_code::table_not_found, ast::query::query {
{
ast::query::select_asterisk {},
},
Expand All @@ -979,7 +1057,7 @@ TEST_F(analyze_query_expression_select_test, invalid_from_table) {

TEST_F(analyze_query_expression_select_test, invalid_where_predicate) {
auto table = install_table("testing");
invalid(ast::query::query {
invalid(sql_analyzer_code::variable_not_found, ast::query::query {
{
ast::query::select_asterisk {},
},
Expand All @@ -1000,7 +1078,7 @@ TEST_F(analyze_query_expression_select_test, invalid_where_predicate) {

TEST_F(analyze_query_expression_select_test, invalid_group_by_column) {
auto table = install_table("testing");
invalid(ast::query::query {
invalid(sql_analyzer_code::variable_not_found, ast::query::query {
{
ast::query::select_column { vref(id("v")) },
},
Expand All @@ -1019,7 +1097,7 @@ TEST_F(analyze_query_expression_select_test, invalid_group_by_column) {

TEST_F(analyze_query_expression_select_test, invalid_having_predicate) {
auto table = install_table("testing");
invalid(ast::query::query {
invalid(sql_analyzer_code::variable_not_found, ast::query::query {
{
ast::query::select_column { vref(id("v")) },
},
Expand All @@ -1044,7 +1122,7 @@ TEST_F(analyze_query_expression_select_test, invalid_having_predicate) {

TEST_F(analyze_query_expression_select_test, invalid_order_by_column) {
auto table = install_table("testing");
invalid(ast::query::query {
invalid(sql_analyzer_code::variable_not_found, ast::query::query {
{
ast::query::select_asterisk {},
},
Expand All @@ -1066,7 +1144,7 @@ TEST_F(analyze_query_expression_select_test, invalid_order_by_column) {

TEST_F(analyze_query_expression_select_test, invalid_limit_expression) {
auto table = install_table("testing");
invalid(ast::query::query {
invalid(sql_analyzer_code::variable_not_found, ast::query::query {
{
ast::query::select_asterisk {},
},
Expand Down

0 comments on commit a51b50b

Please sign in to comment.