tomarrell/lbadd

parser: single table selects should not be considered join statements

Closed this issue · 2 comments

Describe the bug
When parsing a select statement that selects over a single table, that table name is wrapped in the join clause in the AST. It should however be contained in the TableOrSubquery part of the SelectCore.

To Reproduce
Parse SELECT col FROM users WHERE otherColumn IS someValue.
This will yield a SelectCore like follows.

(*ast.SelectCore)(0xc00015aa00)({
 Select: (token.tok) KeywordSelect(SELECT),
 Distinct: (token.Token) <nil>,
 All: (token.Token) <nil>,
 ResultColumn: ([]*ast.ResultColumn) (len=1 cap=1) {
  (*ast.ResultColumn)(0xc0001266c0)({
   Expr: (*ast.Expr)(0xc00017e840)({
    LiteralValue: (token.tok) Literal(col),
    ...
   }),
   ...
  })
 },
 From: (token.tok) KeywordFrom(FROM),
 JoinClause: (*ast.JoinClause)(0xc00011b0e0)({
  TableOrSubquery: (*ast.TableOrSubquery)(0xc0001a0100)({
   ...
   TableName: (token.tok) Literal(users),
   ...
  }),
  ...
 }),
 TableOrSubquery: ([]*ast.TableOrSubquery) <nil>,
 Where: (token.tok) KeywordWhere(WHERE),

Expected behavior
The TableOrSubquery must not be wrapped into the JoinClause.

Additional context
The fix must be implemented inside the parser package, internal/parser/simple_parser.go to be exact.

  • If there is no JOIN specified, the tables must be in the TableOrSubquery of the SelectCore
  • If there is a JOIN specified, all joined tables must be inside the JoinClause

Additionally,

I'm not sure if you remember but this is the case because TableOrSubquery and JoinClause were exactly the same.

But we can have the condition of JOIN and figure out where we can put the statement into.

The statement belongs inside the select core's TableOrSubquery, because a simple SELECT * FROM table has no join clause, even though it allows that production.