5 TODO: simplify, it captures many unnecessary details
18 %token <string> IDENT COMMENT
19 %token <Stmt.Raw.parameter> PARAM
20 %token LPAREN RPAREN COMMA EOF DOT
21 %token IGNORE REPLACE ABORT FAIL ROLLBACK
22 %token SELECT INSERT OR INTO CREATE_TABLE UPDATE TABLE VALUES WHERE FROM ASTERISK DISTINCT ALL
23 LIMIT ORDER_BY DESC ASC EQUAL DELETE_FROM DEFAULT OFFSET SET JOIN LIKE_OP
24 EXCL TILDE NOT FUNCTION TEST_NULL BETWEEN AND ESCAPE
25 %token NOT_NULL UNIQUE PRIMARY_KEY AUTOINCREMENT ON_CONFLICT
26 %token PLUS MINUS DIVIDE PERCENT
27 %token T_INTEGER T_BLOB T_TEXT
34 input: statement EOF { $1 } ;
37 input: collection EOF { List.rev $1 } ;
39 collection: statement { [$1] }
40 | collection statement { $2::$1 } ;
43 statement: CREATE_TABLE IDENT LPAREN column_defs RPAREN
44 { Tables.add ($2,List.rev $4) }
45 | select_core maybe_order maybe_limit
46 { RA.Scheme.print $1 }
47 /*| insert_cmd IDENT LPAREN columns RPAREN VALUES
48 { Raw.Insert (Raw.Cols (List.rev $4)), $2, [] }
49 | insert_cmd IDENT VALUES
50 { Raw.Insert Raw.All, $2, [] }
51 | UPDATE IDENT SET set_columns maybe_where
52 { Raw.Update $4, $2, List.filter_valid [$5] }
53 | DELETE_FROM IDENT maybe_where
54 { Raw.Delete, $2, List.filter_valid [$3] }*/ ;
56 select_core: SELECT select_type results FROM table_list maybe_where
57 { Syntax.resolve $3 $5 } ;
59 table_list: table { [$1] }
60 | table_list join_op table join_args { $3::$1 } ;
62 table: IDENT { Tables.get $1 } ;
67 insert_cmd: INSERT OR conflict_algo INTO {}
72 | UPDATE OR conflict_algo {} ;
74 select_type: /* */ { }
78 maybe_limit: LIMIT PARAM { [Some ("limit",Type.Int)] }
79 | LIMIT INTEGER { [None] }
80 | LIMIT PARAM COMMA PARAM { [Some ("offset",Type.Int); Some ("limit",Type.Int)] }
81 | LIMIT INTEGER COMMA PARAM { [Some ("limit",Type.Int)] }
82 | LIMIT PARAM COMMA INTEGER { [Some ("offset",Type.Int)] }
83 | LIMIT INTEGER COMMA INTEGER { [None] }
84 | LIMIT PARAM OFFSET PARAM { [Some ("limit",Type.Int); Some ("offset",Type.Int)] }
85 | LIMIT INTEGER OFFSET PARAM { [Some ("offset",Type.Int)] }
86 | LIMIT PARAM OFFSET INTEGER { [Some ("limit",Type.Int)] }
87 | LIMIT INTEGER OFFSET INTEGER { [None] }
90 maybe_order: ORDER_BY IDENT order_type { }
97 maybe_where: WHERE IDENT EQUAL PARAM { Some ($2,Type.Int) }
100 results: columns { List.rev $1 } ;
102 columns: column1 { [$1] }
103 | columns COMMA column1 { $3::$1 } ;
105 column1: IDENT { One $1 }
106 | IDENT DOT IDENT { OneOf ($3,$1) }
107 | IDENT DOT ASTERISK { AllOf $1 }
109 /* | IDENT LPAREN IDENT RPAREN { $1 } ; */
111 column_defs: column_def1 { [$1] }
112 | column_defs COMMA column_def1 { $3::$1 } ;
114 column_def1: IDENT sql_type { RA.Scheme.attr $1 $2 }
115 | IDENT sql_type column_def_extra { RA.Scheme.attr $1 $2 } ;
117 column_def_extra: column_def_extra1 { [$1] }
118 | column_def_extra column_def_extra1 { $2::$1 } ;
120 column_def_extra1: PRIMARY_KEY { Some Constraint.PrimaryKey }
121 | NOT_NULL { Some Constraint.NotNull }
122 | UNIQUE { Some Constraint.Unique }
123 | AUTOINCREMENT { Some Constraint.Autoincrement }
124 | ON_CONFLICT conflict_algo { Some (Constraint.OnConflict $2) } ;
125 | DEFAULT INTEGER { None }
127 set_columns: set_columns1 { Raw.Cols (List.filter_valid (List.rev $1)) } ;
129 set_columns1: set_column { [$1] }
130 | set_columns1 COMMA set_column { $3::$1 } ;
132 set_column: IDENT EQUAL expr { match $3 with | 1 -> Some $1 | x -> assert (0=x); None } ;
136 expr binary_op expr { $1 @ $3 }
137 | expr LIKE_OP expr maybe_escape { $1 @ $3 @ $4 }
138 | unary_op expr { $2 }
139 | LPAREN expr RPAREN { $2 }
141 | IDENT DOT IDENT { [] }
142 | IDENT DOT IDENT DOT IDENT { [] }
145 | FUNCTION LPAREN func_params RPAREN { $3 }
146 | expr TEST_NULL { $1 }
147 | expr BETWEEN expr AND expr { $1 @ $3 @ $5 }
149 expr_list_rev: expr { [$1] }
150 | expr_list_rev COMMA expr { $3::$1 } ;
151 expr_list: expr_list_rev { $1 >> List.rev >> List.flatten } ;
152 func_params: expr_list { $1 }
155 | ESCAPE expr { $2 } ;
166 conflict_algo: IGNORE { Constraint.Ignore }
167 | REPLACE { Constraint.Replace }
168 | ABORT { Constraint.Abort }
169 | FAIL { Constraint.Fail }
170 | ROLLBACK { Constraint.Rollback } ;
172 sql_type: T_INTEGER { Type.Int }
173 | T_BLOB { Type.Blob }
174 | T_TEXT { Type.Text } ;