From b2dda89e600b32bfb127c8d22305e62db25d0187 Mon Sep 17 00:00:00 2001 From: Jay Pipes Date: Mon, 28 May 2018 21:46:21 -0400 Subject: [PATCH] Break out query_term_t parser Makes non_join_query_term_t a derivative of query_term_t and prepares the term parser for upcoming INTERSECTS processing. Issue #78 --- libsqltoast/include/sqltoast/print.h | 1 + libsqltoast/include/sqltoast/query.h | 5 +- libsqltoast/src/parser/parse.h | 6 ++- libsqltoast/src/parser/query.cc | 49 +++++++++++++++---- libsqltoast/src/print/query.cc | 20 ++++++++ sqltoaster/fill.h | 1 + sqltoaster/node/statement.cc | 19 ++++++++ sqltoaster/print/yaml.cc | 19 ++++++++ sqltoaster/print/yaml.h | 72 ++++++++++++++++++++++++++++ 9 files changed, 181 insertions(+), 11 deletions(-) create mode 100644 sqltoaster/print/yaml.h diff --git a/libsqltoast/include/sqltoast/print.h b/libsqltoast/include/sqltoast/print.h index 88c408f..0405504 100644 --- a/libsqltoast/include/sqltoast/print.h +++ b/libsqltoast/include/sqltoast/print.h @@ -112,6 +112,7 @@ std::ostream& operator<< (std::ostream& out, const position_expression_t& pe); std::ostream& operator<< (std::ostream& out, const query_expression_t& qe); std::ostream& operator<< (std::ostream& out, const query_specification_non_join_query_primary_t& primary); std::ostream& operator<< (std::ostream& out, const query_specification_t& qs); +std::ostream& operator<< (std::ostream& out, const query_term_t& qt); std::ostream& operator<< (std::ostream& out, const row_value_constructor_element_t& rvce); std::ostream& operator<< (std::ostream& out, const row_value_constructor_t& rvc); std::ostream& operator<< (std::ostream& out, const row_value_expression_t& rve); diff --git a/libsqltoast/include/sqltoast/query.h b/libsqltoast/include/sqltoast/query.h index 5b1ecfb..218a0be 100644 --- a/libsqltoast/include/sqltoast/query.h +++ b/libsqltoast/include/sqltoast/query.h @@ -143,9 +143,10 @@ typedef struct joined_table_query_term : query_term_t { } joined_table_query_term_t; typedef struct non_join_query_expression : query_expression_t { - std::unique_ptr term; + // Guaranteed to be static_castable to non_join_query_term_t. + std::unique_ptr term; non_join_query_expression( - std::unique_ptr& term) : + std::unique_ptr& term) : query_expression_t(QUERY_COMPONENT_TYPE_NON_JOIN), term(std::move(term)) {} diff --git a/libsqltoast/src/parser/parse.h b/libsqltoast/src/parser/parse.h index c249ed5..3db7998 100644 --- a/libsqltoast/src/parser/parse.h +++ b/libsqltoast/src/parser/parse.h @@ -135,10 +135,14 @@ bool parse_non_join_query_expression( parse_context_t& ctx, token_t& cur_tok, std::unique_ptr& out); +bool parse_query_term( + parse_context_t& ctx, + token_t& cur_tok, + std::unique_ptr& out); bool parse_non_join_query_term( parse_context_t& ctx, token_t& cur_tok, - std::unique_ptr& out); + std::unique_ptr& out); bool parse_non_join_query_primary( parse_context_t& ctx, token_t& cur_tok, diff --git a/libsqltoast/src/parser/query.cc b/libsqltoast/src/parser/query.cc index f5977af..d5a361f 100644 --- a/libsqltoast/src/parser/query.cc +++ b/libsqltoast/src/parser/query.cc @@ -13,10 +13,6 @@ namespace sqltoast { // // | // -// ::= -// -// | -// // ::= // // | @@ -55,14 +51,51 @@ bool parse_non_join_query_expression( parse_context_t& ctx, token_t& cur_tok, std::unique_ptr& out) { - std::unique_ptr njqt; + std::unique_ptr query_term; - if (! parse_non_join_query_term(ctx, cur_tok, njqt)) + if (! parse_non_join_query_term(ctx, cur_tok, query_term)) return false; // TODO(jaypipes): Handle UNION and EXCEPT if (ctx.opts.disable_statement_construction) return true; - out = std::make_unique(njqt); + out = std::make_unique(query_term); + return true; +} + +// ::= +// +// | +bool parse_query_term( + parse_context_t& ctx, + token_t& cur_tok, + std::unique_ptr& out) { + lexer_t& lex = ctx.lexer; + parse_position_t start = lex.cursor; + token_t start_tok = lex.current_token; + std::unique_ptr joined_table; + if (parse_non_join_query_term(ctx, cur_tok, out)) + return true; + if (ctx.result.code == PARSE_SYNTAX_ERROR) + return false; + + // Reset cursor to before parsing of joined table attempt. + lex.cursor = start; + lex.current_token = cur_tok = start_tok; + if (! parse_joined_table(ctx, cur_tok, joined_table)) + goto err_expect_joined_table; + goto push_joined_table_term; +err_expect_joined_table: + { + std::stringstream estr; + estr << "Expected but found " + << cur_tok << std::endl; + create_syntax_error_marker(ctx, estr); + return false; + } +push_joined_table_term: + if (ctx.opts.disable_statement_construction) + return true; + out = std::make_unique(joined_table); return true; } @@ -73,7 +106,7 @@ bool parse_non_join_query_expression( bool parse_non_join_query_term( parse_context_t& ctx, token_t& cur_tok, - std::unique_ptr& out) { + std::unique_ptr& out) { std::unique_ptr njqp; if (! parse_non_join_query_primary(ctx, cur_tok, njqp)) diff --git a/libsqltoast/src/print/query.cc b/libsqltoast/src/print/query.cc index 95a3358..7a5b400 100644 --- a/libsqltoast/src/print/query.cc +++ b/libsqltoast/src/print/query.cc @@ -78,6 +78,26 @@ std::ostream& operator<< (std::ostream& out, const non_join_query_expression_t& return out; } +std::ostream& operator<< (std::ostream& out, const query_term_t& term) { + switch (term.query_component_type) { + case QUERY_COMPONENT_TYPE_NON_JOIN: + { + const non_join_query_term_t& sub = + static_cast(term); + out << sub; + } + break; + case QUERY_COMPONENT_TYPE_JOINED_TABLE: + { + const joined_table_query_term_t& sub = + static_cast(term); + out << sub; + } + break; + } + return out; +} + std::ostream& operator<< (std::ostream& out, const non_join_query_term_t& term) { out << *term.primary; return out; diff --git a/sqltoaster/fill.h b/sqltoaster/fill.h index 13e0bd3..3edb4ec 100644 --- a/sqltoaster/fill.h +++ b/sqltoaster/fill.h @@ -80,6 +80,7 @@ void fill(mapping_t& node, const sqltoast::quantified_comparison_predicate_t& pr void fill(mapping_t& node, const sqltoast::query_expression_t& qe); void fill(mapping_t& node, const sqltoast::query_specification_non_join_query_primary_t& primary); void fill(mapping_t& node, const sqltoast::query_specification_t& query); +void fill(mapping_t& node, const sqltoast::query_term_t& term); void fill(mapping_t& node, const sqltoast::row_value_constructor_element_t& rvce); void fill(mapping_t& node, const sqltoast::row_value_constructor_t& rvc); void fill(mapping_t& node, const sqltoast::row_value_expression_t& rve); diff --git a/sqltoaster/node/statement.cc b/sqltoaster/node/statement.cc index 0d55809..fed3a5a 100644 --- a/sqltoaster/node/statement.cc +++ b/sqltoaster/node/statement.cc @@ -293,6 +293,25 @@ void fill(mapping_t& node, const sqltoast::table_expression_t& table_exp) { } } +void fill(mapping_t& node, const sqltoast::query_term_t& term) { + switch (term.query_component_type) { + case sqltoast::QUERY_COMPONENT_TYPE_NON_JOIN: + { + const sqltoast::non_join_query_term_t& sub = + static_cast(term); + fill(node, sub); + } + break; + case sqltoast::QUERY_COMPONENT_TYPE_JOINED_TABLE: + { + const sqltoast::joined_table_query_term_t& sub = + static_cast(term); + fill(node, sub); + } + break; + } +} + void fill(mapping_t& node, const sqltoast::query_expression_t& qe) { switch (qe.query_component_type) { case sqltoast::QUERY_COMPONENT_TYPE_NON_JOIN: diff --git a/sqltoaster/print/yaml.cc b/sqltoaster/print/yaml.cc index 6c947f3..78d788f 100644 --- a/sqltoaster/print/yaml.cc +++ b/sqltoaster/print/yaml.cc @@ -353,6 +353,25 @@ void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::non_join_query_e to_yaml(ptr, out, *qe.term); } +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::query_term_t& term) { + switch (term.query_component_type) { + case sqltoast::QUERY_COMPONENT_TYPE_NON_JOIN: + { + const sqltoast::non_join_query_term_t& sub = + static_cast(term); + to_yaml(ptr, out, sub); + } + break; + case sqltoast::QUERY_COMPONENT_TYPE_JOINED_TABLE: + { + const sqltoast::joined_table_query_term_t& sub = + static_cast(term); + to_yaml(ptr, out, sub); + } + break; + } +} + void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::non_join_query_term_t& term) { to_yaml(ptr, out, *term.primary); } diff --git a/sqltoaster/print/yaml.h b/sqltoaster/print/yaml.h new file mode 100644 index 0000000..6f07782 --- /dev/null +++ b/sqltoaster/print/yaml.h @@ -0,0 +1,72 @@ +/* + * Use and distribution licensed under the Apache license version 2. + * + * See the COPYING file in the root project directory for full text. + */ + +#ifndef SQLTOASTER_PRINT_YAML_PRINTERS_H +#define SQLTOASTER_PRINT_YAML_PRINTERS_H + +#include + +#include "../printer.h" + +namespace sqltoaster { +namespace print { + +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::add_column_action_t& action); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::add_constraint_action_t& action); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::alter_column_action_t& action); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::alter_table_action_t& action); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::alter_table_statement_t& stmt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::between_predicate_t& pred); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::boolean_factor_t& bf); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::boolean_primary_t& bp); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::boolean_term_t& bt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::comp_op_t& op); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::comp_predicate_t& pred); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::create_schema_statement_t& stmt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::create_table_statement_t& stmt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::create_view_statement_t& stmt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::delete_statement_t& stmt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::drop_column_action_t& action); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::drop_column_action_t& action); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::drop_schema_statement_t& stmt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::drop_table_statement_t& stmt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::drop_view_statement_t& stmt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::exists_predicate_t& pred); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::grant_action_t& action); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::grant_statement_t& stmt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::in_subquery_predicate_t& pred); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::in_values_predicate_t& pred); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::insert_select_statement_t& stmt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::insert_statement_t& stmt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::joined_table_query_expression_t& qe); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::joined_table_t& jt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::like_predicate_t& pred); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::match_predicate_t& pred); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::non_join_query_expression_t& qe); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::non_join_query_primary_t& primary); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::non_join_query_term_t& term); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::null_predicate_t& pred); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::overlaps_predicate_t& pred); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::predicate_t& pred); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::quantified_comparison_predicate_t& pred); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::query_expression_t& qe); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::query_specification_non_join_query_primary_t& primary); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::query_specification_t& query); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::query_term_t& term); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::row_value_constructor_element_t& rvce, bool list_item); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::row_value_constructor_t& rvc); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::row_value_expression_t& rve); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::search_condition_t& sc); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::select_statement_t& stmt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::statement_t& stmt); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::table_expression_t& table_exp); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::unique_predicate_t& pred); +void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::update_statement_t& stmt); + +} // namespace sqltoaster::print +} // namespace sqltoaster + +#endif /* SQLTOASTER_PRINT_YAML_PRINTERS_H */