Skip to content

Commit c916888

Browse files
committed
Break out query_primary_t parsing
Makes non_join_query_primary_t derive properly from query_primary_t and make sure that parse_query_primary() properly attempts to parse a non_join_query_primary_t first, then a joined_table_t if that failed. Issue #78
1 parent b2dda89 commit c916888

File tree

9 files changed

+125
-26
lines changed

9 files changed

+125
-26
lines changed

libsqltoast/include/sqltoast/print.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,10 @@ std::ostream& operator<< (std::ostream& out, const numeric_term_t& nt);
110110
std::ostream& operator<< (std::ostream& out, const numeric_value_t& nv);
111111
std::ostream& operator<< (std::ostream& out, const position_expression_t& pe);
112112
std::ostream& operator<< (std::ostream& out, const query_expression_t& qe);
113+
std::ostream& operator<< (std::ostream& out, const query_primary_t& primary);
113114
std::ostream& operator<< (std::ostream& out, const query_specification_non_join_query_primary_t& primary);
114115
std::ostream& operator<< (std::ostream& out, const query_specification_t& qs);
115-
std::ostream& operator<< (std::ostream& out, const query_term_t& qt);
116+
std::ostream& operator<< (std::ostream& out, const query_term_t& term);
116117
std::ostream& operator<< (std::ostream& out, const row_value_constructor_element_t& rvce);
117118
std::ostream& operator<< (std::ostream& out, const row_value_constructor_t& rvc);
118119
std::ostream& operator<< (std::ostream& out, const row_value_expression_t& rve);

libsqltoast/include/sqltoast/query.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,10 @@ typedef struct joined_table_query_primary : query_primary_t {
125125
} joined_table_query_primary_t;
126126

127127
typedef struct non_join_query_term : query_term_t {
128-
std::unique_ptr<non_join_query_primary_t> primary;
128+
// Guaranteed to be static_castable to non_join_query_primary_t
129+
std::unique_ptr<query_primary_t> primary;
129130
non_join_query_term(
130-
std::unique_ptr<non_join_query_primary_t>& primary) :
131+
std::unique_ptr<query_primary_t>& primary) :
131132
query_term_t(QUERY_COMPONENT_TYPE_NON_JOIN),
132133
primary(std::move(primary))
133134
{}

libsqltoast/src/parser/parse.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,14 @@ bool parse_non_join_query_term(
143143
parse_context_t& ctx,
144144
token_t& cur_tok,
145145
std::unique_ptr<query_term_t>& out);
146+
bool parse_query_primary(
147+
parse_context_t& ctx,
148+
token_t& cur_tok,
149+
std::unique_ptr<query_primary_t>& out);
146150
bool parse_non_join_query_primary(
147151
parse_context_t& ctx,
148152
token_t& cur_tok,
149-
std::unique_ptr<non_join_query_primary_t>& out);
153+
std::unique_ptr<query_primary_t>& out);
150154
bool parse_joined_table(
151155
parse_context_t& ctx,
152156
token_t& cur_tok,

libsqltoast/src/parser/query.cc

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ namespace sqltoast {
1212
// <query expression> ::=
1313
// <non-join query expression>
1414
// | <joined table>
15-
//
16-
// <query primary> ::=
17-
// <non-join query primary>
18-
// | <joined table>
1915
bool parse_query_expression(
2016
parse_context_t& ctx,
2117
token_t& cur_tok,
@@ -107,14 +103,51 @@ bool parse_non_join_query_term(
107103
parse_context_t& ctx,
108104
token_t& cur_tok,
109105
std::unique_ptr<query_term_t>& out) {
110-
std::unique_ptr<non_join_query_primary_t> njqp;
106+
std::unique_ptr<query_primary_t> query_primary;
111107

112-
if (! parse_non_join_query_primary(ctx, cur_tok, njqp))
108+
if (! parse_non_join_query_primary(ctx, cur_tok, query_primary))
113109
return false;
114110
// TODO(jaypipes): Handle INTERSECT
115111
if (ctx.opts.disable_statement_construction)
116112
return true;
117-
out = std::make_unique<non_join_query_term_t>(njqp);
113+
out = std::make_unique<non_join_query_term_t>(query_primary);
114+
return true;
115+
}
116+
117+
// <query primary> ::=
118+
// <non-join query primary>
119+
// | <joined table>
120+
bool parse_query_primary(
121+
parse_context_t& ctx,
122+
token_t& cur_tok,
123+
std::unique_ptr<query_primary_t>& out) {
124+
lexer_t& lex = ctx.lexer;
125+
parse_position_t start = lex.cursor;
126+
token_t start_tok = lex.current_token;
127+
std::unique_ptr<joined_table_t> joined_table;
128+
if (parse_non_join_query_primary(ctx, cur_tok, out))
129+
return true;
130+
if (ctx.result.code == PARSE_SYNTAX_ERROR)
131+
return false;
132+
133+
// Reset cursor to before parsing of joined table attempt.
134+
lex.cursor = start;
135+
lex.current_token = cur_tok = start_tok;
136+
if (! parse_joined_table(ctx, cur_tok, joined_table))
137+
goto err_expect_joined_table;
138+
goto push_joined_table_primary;
139+
err_expect_joined_table:
140+
{
141+
std::stringstream estr;
142+
estr << "Expected <joined table> but found "
143+
<< cur_tok << std::endl;
144+
create_syntax_error_marker(ctx, estr);
145+
return false;
146+
}
147+
push_joined_table_primary:
148+
if (ctx.opts.disable_statement_construction)
149+
return true;
150+
out = std::make_unique<joined_table_query_primary_t>(joined_table);
118151
return true;
119152
}
120153

@@ -129,7 +162,7 @@ bool parse_non_join_query_term(
129162
bool parse_non_join_query_primary(
130163
parse_context_t& ctx,
131164
token_t& cur_tok,
132-
std::unique_ptr<non_join_query_primary_t>& out) {
165+
std::unique_ptr<query_primary_t>& out) {
133166
lexer_t& lex = ctx.lexer;
134167
parse_position_t start = lex.cursor;
135168
token_t start_tok = lex.current_token;

libsqltoast/src/print/query.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,26 @@ std::ostream& operator<< (std::ostream& out, const non_join_query_term_t& term)
103103
return out;
104104
}
105105

106+
std::ostream& operator<< (std::ostream& out, const query_primary_t& primary) {
107+
switch (primary.query_component_type) {
108+
case QUERY_COMPONENT_TYPE_NON_JOIN:
109+
{
110+
const non_join_query_primary_t& sub =
111+
static_cast<const non_join_query_primary_t&>(primary);
112+
out << sub;
113+
}
114+
break;
115+
case QUERY_COMPONENT_TYPE_JOINED_TABLE:
116+
{
117+
const joined_table_query_primary_t& sub =
118+
static_cast<const joined_table_query_primary_t&>(primary);
119+
out << sub;
120+
}
121+
break;
122+
}
123+
return out;
124+
}
125+
106126
std::ostream& operator<< (std::ostream& out, const non_join_query_primary_t& primary) {
107127
switch (primary.primary_type) {
108128
case NON_JOIN_QUERY_PRIMARY_TYPE_QUERY_SPECIFICATION:

sqltoaster/fill.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ void fill(mapping_t& node, const sqltoast::position_expression_t& expr);
7878
void fill(mapping_t& node, const sqltoast::predicate_t& pred);
7979
void fill(mapping_t& node, const sqltoast::quantified_comparison_predicate_t& pred);
8080
void fill(mapping_t& node, const sqltoast::query_expression_t& qe);
81+
void fill(mapping_t& node, const sqltoast::query_primary_t& primary);
8182
void fill(mapping_t& node, const sqltoast::query_specification_non_join_query_primary_t& primary);
8283
void fill(mapping_t& node, const sqltoast::query_specification_t& query);
8384
void fill(mapping_t& node, const sqltoast::query_term_t& term);

sqltoaster/node/statement.cc

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,29 @@ void fill(mapping_t& node, const sqltoast::table_expression_t& table_exp) {
293293
}
294294
}
295295

296+
void fill(mapping_t& node, const sqltoast::query_expression_t& qe) {
297+
switch (qe.query_component_type) {
298+
case sqltoast::QUERY_COMPONENT_TYPE_NON_JOIN:
299+
{
300+
const sqltoast::non_join_query_expression_t& sub =
301+
static_cast<const sqltoast::non_join_query_expression_t&>(qe);
302+
fill(node, sub);
303+
}
304+
break;
305+
case sqltoast::QUERY_COMPONENT_TYPE_JOINED_TABLE:
306+
{
307+
const sqltoast::joined_table_query_expression_t& sub =
308+
static_cast<const sqltoast::joined_table_query_expression_t&>(qe);
309+
fill(node, sub);
310+
}
311+
break;
312+
}
313+
}
314+
315+
void fill(mapping_t& node, const sqltoast::non_join_query_expression_t& qe) {
316+
fill(node, *qe.term);
317+
}
318+
296319
void fill(mapping_t& node, const sqltoast::query_term_t& term) {
297320
switch (term.query_component_type) {
298321
case sqltoast::QUERY_COMPONENT_TYPE_NON_JOIN:
@@ -312,33 +335,29 @@ void fill(mapping_t& node, const sqltoast::query_term_t& term) {
312335
}
313336
}
314337

315-
void fill(mapping_t& node, const sqltoast::query_expression_t& qe) {
316-
switch (qe.query_component_type) {
338+
void fill(mapping_t& node, const sqltoast::non_join_query_term_t& term) {
339+
fill(node, *term.primary);
340+
}
341+
342+
void fill(mapping_t& node, const sqltoast::query_primary_t& primary) {
343+
switch (primary.query_component_type) {
317344
case sqltoast::QUERY_COMPONENT_TYPE_NON_JOIN:
318345
{
319-
const sqltoast::non_join_query_expression_t& sub =
320-
static_cast<const sqltoast::non_join_query_expression_t&>(qe);
346+
const sqltoast::non_join_query_primary_t& sub =
347+
static_cast<const sqltoast::non_join_query_primary_t&>(primary);
321348
fill(node, sub);
322349
}
323350
break;
324351
case sqltoast::QUERY_COMPONENT_TYPE_JOINED_TABLE:
325352
{
326-
const sqltoast::joined_table_query_expression_t& sub =
327-
static_cast<const sqltoast::joined_table_query_expression_t&>(qe);
353+
const sqltoast::joined_table_query_primary_t& sub =
354+
static_cast<const sqltoast::joined_table_query_primary_t&>(primary);
328355
fill(node, sub);
329356
}
330357
break;
331358
}
332359
}
333360

334-
void fill(mapping_t& node, const sqltoast::non_join_query_expression_t& qe) {
335-
fill(node, *qe.term);
336-
}
337-
338-
void fill(mapping_t& node, const sqltoast::non_join_query_term_t& term) {
339-
fill(node, *term.primary);
340-
}
341-
342361
void fill(mapping_t& node, const sqltoast::non_join_query_primary_t& primary) {
343362
switch (primary.primary_type) {
344363
case sqltoast::NON_JOIN_QUERY_PRIMARY_TYPE_QUERY_SPECIFICATION:

sqltoaster/print/yaml.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,25 @@ void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::non_join_query_t
376376
to_yaml(ptr, out, *term.primary);
377377
}
378378

379+
void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::query_primary_t& primary) {
380+
switch (primary.query_component_type) {
381+
case sqltoast::QUERY_COMPONENT_TYPE_NON_JOIN:
382+
{
383+
const sqltoast::non_join_query_primary_t& sub =
384+
static_cast<const sqltoast::non_join_query_primary_t&>(primary);
385+
to_yaml(ptr, out, sub);
386+
}
387+
break;
388+
case sqltoast::QUERY_COMPONENT_TYPE_JOINED_TABLE:
389+
{
390+
const sqltoast::joined_table_query_primary_t& sub =
391+
static_cast<const sqltoast::joined_table_query_primary_t&>(primary);
392+
to_yaml(ptr, out, sub);
393+
}
394+
break;
395+
}
396+
}
397+
379398
void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::non_join_query_primary_t& primary) {
380399
switch (primary.primary_type) {
381400
case sqltoast::NON_JOIN_QUERY_PRIMARY_TYPE_QUERY_SPECIFICATION:

sqltoaster/print/yaml.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::overlaps_predica
5353
void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::predicate_t& pred);
5454
void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::quantified_comparison_predicate_t& pred);
5555
void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::query_expression_t& qe);
56+
void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::query_primary_t& primary);
5657
void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::query_specification_non_join_query_primary_t& primary);
5758
void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::query_specification_t& query);
5859
void to_yaml(printer_t& ptr, std::ostream& out, const sqltoast::query_term_t& term);

0 commit comments

Comments
 (0)