Browse Source

Parse simple where

master
Dylan Baker 4 years ago
parent
commit
00bd7bb68e
4 changed files with 42 additions and 2 deletions
  1. 1
    0
      src/ast.ts
  2. 3
    0
      src/ast/selectStatement.ts
  3. 16
    2
      src/parser.ts
  4. 22
    0
      test/parser.test.ts

+ 1
- 0
src/ast.ts View File

@@ -11,3 +11,4 @@ export * from "./ast/selectStatement";
11 11
 export type Primary = _Number | Identifier;
12 12
 export type Secondary = Primary | Alias;
13 13
 export type Statement = SelectStatement;
14
+export type Expr = Secondary;

+ 3
- 0
src/ast/selectStatement.ts View File

@@ -3,14 +3,17 @@ import * as AST from "../ast";
3 3
 export interface ISelectStatementOptions {
4 4
   arguments: AST.Secondary[];
5 5
   from?: AST.Secondary | null;
6
+  where?: AST.Expr | null
6 7
 }
7 8
 
8 9
 export class SelectStatement {
9 10
   public arguments: AST.Secondary[];
10 11
   public from: AST.Secondary | null;
12
+  public where: AST.Expr | null;
11 13
 
12 14
   constructor(opts: ISelectStatementOptions) {
13 15
     this.arguments = opts.arguments;
14 16
     this.from = opts.from ? opts.from : null;
17
+    this.where = opts.where ? opts.where : null;
15 18
   }
16 19
 }

+ 16
- 2
src/parser.ts View File

@@ -44,15 +44,20 @@ export default class Parser {
44 44
       return args;
45 45
     }
46 46
 
47
-    const currentToken = this.currentToken();
48
-    const from = currentToken.kind === TokenKind.FROM ? this.from() : null;
47
+    const from = this.currentToken().kind === TokenKind.FROM ? this.from() : null;
49 48
     if (isError(from)) {
50 49
       return from;
51 50
     }
52 51
 
52
+    const where = this.currentToken().kind === TokenKind.WHERE ? this.where() : null;
53
+    if (isError(where)) {
54
+      return where;
55
+    }
56
+
53 57
     return new AST.SelectStatement({
54 58
       arguments: args,
55 59
       from,
60
+      where,
56 61
     });
57 62
   }
58 63
 
@@ -81,6 +86,15 @@ export default class Parser {
81 86
     return this.alias(this.identifier);
82 87
   }
83 88
 
89
+  private where(): AST.Expr | Error {
90
+    this.eat(TokenKind.WHERE);
91
+    return this.expr();
92
+  }
93
+
94
+  private expr(): AST.Expr | Error {
95
+    return this.alias();
96
+  }
97
+
84 98
   private alias(fn: () => AST.Primary | Error = this.primary): AST.Secondary | Error {
85 99
     const primary = fn.bind(this)();
86 100
     if (isError(primary)) {

+ 22
- 0
test/parser.test.ts View File

@@ -91,4 +91,26 @@ describe("Parser", () => {
91 91
     const fn = () => parse("select 1 from 2");
92 92
     expect(fn).to.throw("Unexpected token: { kind: NUMBER, value: 2 }");
93 93
   });
94
+
95
+  it("should parse a where with a number", () => {
96
+    const tree = parse("select a from b where 1");
97
+    expect(tree).to.deep.equal([
98
+      new AST.SelectStatement({
99
+        arguments: [new AST.Identifier("a")],
100
+        from: new AST.Identifier("b"),
101
+        where: new AST.Number(1),
102
+      }),
103
+    ]);
104
+  });
105
+
106
+  it("should parse a where with an identifier", () => {
107
+    const tree = parse("select a from b where c");
108
+    expect(tree).to.deep.equal([
109
+      new AST.SelectStatement({
110
+        arguments: [new AST.Identifier("a")],
111
+        from: new AST.Identifier("b"),
112
+        where: new AST.Identifier("c"),
113
+      }),
114
+    ]);
115
+  });
94 116
 });

Loading…
Cancel
Save