changes for join table and parser for aggregates
[csql.git] / src / sql / dmlyacc.yxx
blobcc09de53d3a92420d963baf71e5efa624e04b9db
1 %{
2 #include <CSql.h>
3 #include <stdlib.h>
4 #include "Parser.h"
6 class Predicate;
8 ParsedData *parsedData;
9 extern char yytext[];
10 int yylex( void );
11 void yyerror(const char* Msg);
15 %union
17    char *stringval;
18    void *predicate;
21 %token <stringval> STRING FIELD NUMBER_STRING BINARY_STRING DOUBLE OPERATOR PARAMETER
22 %token <stringval> SELECT FROM WHERE BETWEEN IN AND OR NOT
23 %token <stringval> STAR
24 %token <stringval> INSERT INTO VALUES
25 %token <stringval> DELETE UPDATE SET NULL_VALUE
26 %token <stringval> CREATE TABLE PRIMARY KEY DEFAULT INDEX ON HASH TREE UNIQUE DROP
27 %token <stringval> INT_TYPE LONG_TYPE SHORT_TYPE DOUBLE_TYPE TIMESTAMP_TYPE DATE_TYPE CHAR_TYPE TIME_TYPE BIGINT_TYPE FLOAT_TYPE TINYINT_TYPE
28 %token <stringval> MIN MAX AVG SUM COUNT GROUP BY
29 %token ';' ',' '(' ')'
30 %type <stringval> ident field value not_opt
31 %type <predicate> conditions condition
34 command:  select_statement { YYACCEPT; }
35         | insert_statement { YYACCEPT; }
36         | delete_statement { YYACCEPT; }
37         | update_statement { YYACCEPT; }
38         | ddl_statement { YYACCEPT; }
39         ;
40         
41 select_statement: SELECT field_list FROM ident where_clause_opt group_by_opt semicolon_opt
42         {
43             parsedData->setStmtType(SelectStatement);
44             parsedData->setTableName($4); 
45             free($4);
46         }
47         ;
49 field_list: field_list field_list_L
50         | field 
51         ;
52 field_list_L: ',' field
53         ;
54         
55 insert_statement: INSERT INTO ident field_list_opt VALUES '(' value_list ')' semicolon_opt
56         {
57             parsedData->setStmtType(InsertStatement);
58             parsedData->setTableName($3); 
59             free($3);
60         }
61         ;
63 field_list_opt:
64         | '(' field_list ')'
65         ;
67 value_list: value_list value_list_L
68         | value
69         {
70             parsedData->insertValue((char*)$1);
71             free($1);
72         }
73         ;
74 value_list_L: ',' value 
75         {
76             parsedData->insertValue((char*)$2);
77             free($2);
78         }
79         ;
80         
81 invalue_list: invalue_list invalue_list_L
82         | value
83         {
84             parsedData->insertInValue((char*)$1);
85             free($1);
86         }
87         ;
88 invalue_list_L: ',' value 
89         {
90             parsedData->insertInValue((char*)$2);
91             free($2);
92         }
93         ;
94         
95 delete_statement: DELETE FROM ident where_clause_opt semicolon_opt
96         {
97             parsedData->setStmtType(DeleteStatement);
98             parsedData->setTableName($3); 
99             free($3);
100         }
101         ;
102         
103 update_statement: UPDATE ident SET assign_list where_clause_opt semicolon_opt
104         {
105             parsedData->setStmtType(UpdateStatement);
106             parsedData->setTableName($2); 
107             free( $2 );
108         }
109         ;
111 semicolon_opt: ';'
112         |
113         ;
115 assign_list: assign_list assign_list_L
116         | assign_stmt
117         ;
119 assign_list_L: ',' assign_stmt
120         ;
121 assign_stmt: ident OPERATOR value 
122         { 
123             parsedData->insertUpdateValue( (char*) $1, (char*) $3);
124             free( $1 ); free($2);free( $3 ); 
125         }
126         ;
128 where_clause_opt:  WHERE conditions
129         |
130         ;
131 group_by_opt:  GROUP BY group_field_list
132         |
133         ;
134 group_field_list: group_field_list group_field_list_L
135         | group_field 
136         ;
137 group_field_list_L: ',' group_field
138         ;
139 group_field:   ident
140         {
141             parsedData->insertGroupField((char*)$1);
142             free( $1 );
143         }
144         ;
145 conditions: conditions AND conditions
146         {
147             Predicate *pred;
148             pred = parsedData->insertPredicate((Predicate*) $1, OpAnd, (Predicate*) $3);
149             parsedData->setCondition((Predicate*)pred);
150             $$= pred;
152         }
153         | conditions OR conditions
154         {
155             Predicate *pred;
156             pred = parsedData->insertPredicate((Predicate*) $1, OpOr, (Predicate*) $3);
157             parsedData->setCondition((Predicate*)pred);
158             $$= pred;
159         }
160         | NOT conditions
161         {
162             Predicate *pred;
163             pred = parsedData->insertPredicate((Predicate*) $2, OpNot, NULL);
164             parsedData->setCondition((Predicate*)pred);
165             $$= pred;
166         }
167         | '(' conditions ')' { }
168         | condition
169         {
170             parsedData->setCondition((Predicate*)$1);
171             //((Predicate*)$1)->print();
172             $$=$1;
173         }
174         ;
175 condition: ident OPERATOR value 
176         {
177             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
178             Predicate *pred;
179             void **ptr = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$3);
180             pred = parsedData->insertPredicate((char*) $1, op, ptr);
181             free( $1 ); free($2); free( $3 ); 
182             $$=pred;
183         }
184         | ident OPERATOR ident
185         {
186             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
187             Predicate *pred;
188             pred = parsedData->insertPredicate((char*) $1, op, (char*) $3);
189             free( $1 ); free($2); free( $3 );
190             $$=pred;
191         }
193         | ident not_opt BETWEEN value AND value
194         {
195             void **ptr1 = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$4);
196             void **ptr2 = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$6);
197             Predicate *pred1, *pred2, *pred3, *finalPred;
198             pred1 = parsedData->insertPredicate((char*) $1, OpGreaterThanEquals, ptr1);
199             pred2 = parsedData->insertPredicate((char*) $1, OpLessThanEquals, ptr2);
200             finalPred = parsedData->insertPredicate(pred1, OpAnd, pred2);
201             if( $2 == (char*) 1 )
202                 finalPred = parsedData->insertPredicate(finalPred, OpNot, NULL);
203             free( $1 );  free( $4 );  free( $6 );
204             $$= finalPred;
205         }
206         | ident not_opt IN '(' invalue_list ')'
207         {
208             ListIterator valIter = parsedData->getInValueList().getIterator();
209             FieldValue *value1, *value2;
210             Predicate *pred1, *pred2, *finalPred;
211             void **ptr1, **ptr2;
212             if (valIter.hasElement()) {
213                value1 = (FieldValue*) valIter.nextElement();
214                ptr1 = parsedData->insertCondValueAndGetPtr((char*)$1, value1->parsedString);
215                pred1 = parsedData->insertPredicate((char*) $1, OpEquals, ptr1);
216                finalPred=pred1;
217             }
218             while (valIter.hasElement()) {
219                value2 = (FieldValue*) valIter.nextElement();
220                ptr2 = parsedData->insertCondValueAndGetPtr((char*)$1, value2->parsedString);
221                pred2 = parsedData->insertPredicate((char*) $1, OpEquals, ptr2);
222                finalPred = parsedData->insertPredicate(pred1, OpOr, pred2);
223                pred1= finalPred;     
224             }
225             if( $2 == (char*)1)
226                 finalPred = parsedData->insertPredicate(finalPred, OpNot, NULL);
228             free( $1 );  
229             $$= finalPred;
230         }
231         ;
232 not_opt: NOT
233         { $$=(char*) 1;
234         }
235         | 
236         { $$=(char*) 0; }
237         ;
238 field:   ident
239         {
240             parsedData->insertField((char*)$1);
241             free( $1 );
242         }
243         | MIN  '(' ident ')'
244         { 
245             parsedData->insertField((char*)$3, AGG_MIN);
246             free( $1 );
247         }
248         | MAX  '(' ident ')'
249         { 
250             parsedData->insertField((char*)$3, AGG_MAX);
251             free( $1 );
252         }
253         | SUM  '(' ident ')'
254         { 
255             parsedData->insertField((char*)$3, AGG_SUM);
256             free( $1 );
257         }
258         | AVG  '(' ident ')'
259         { 
260             parsedData->insertField((char*)$3, AGG_AVG);
261             free( $1 );
262         }
263         | COUNT  '(' ident ')'
264         { 
265             parsedData->insertField((char*)$3, AGG_COUNT);
266             free( $1 );
267         }
268         | STAR
269         { 
270             parsedData->insertField((char*)$1);
271             free( $1 );
272         }
273         ;
274 ident:    FIELD { $$ = $1; }
275         ;
276 value:    STRING { $$ = $1; }
277         | NUMBER_STRING { $$ = $1; }
278         | BINARY_STRING { $$ = $1; }
279         | DOUBLE { $$ = $1; }
280         | PARAMETER { $$ = $1; }
281         | NULL_VALUE { $$ = (char*) 0; }
282         ;
284 ddl_statement: CREATE TABLE ident '(' create_defn_list ')' semicolon_opt
285         {
286             parsedData->setStmtType(CreateTableStatement);
287             parsedData->setTableName($3); 
288             free($3);
289         }
290         | CREATE INDEX ident ON ident '(' field_list ')' opt_constr_type opt_ind_type  semicolon_opt
291         {
292             parsedData->setStmtType(CreateIndexStatement);
293             parsedData->setIndexName($3); 
294             parsedData->setTableName($5); 
295             free($3);
296             free($5);
297         }
298         | DROP TABLE ident
299         {
300             parsedData->setStmtType(DropTableStatement);
301             parsedData->setTableName($3); 
302             free($3);
303         }
304         | DROP INDEX ident
305         {
306             parsedData->setStmtType(DropIndexStatement);
307             parsedData->setIndexName($3); 
308             free($3);
309         }
310         ;
311 opt_ind_type:
312         | HASH  opt_constr_type
313         {
314             parsedData->setIndexType(hashIndex);
315         }
316         | TREE  opt_constr_type
317         {
318             parsedData->setIndexType(treeIndex);
319         }
320         |
321         {
322             parsedData->setIndexType(hashIndex);
323         }
324         ;
325 opt_constr_type:
326         | UNIQUE 
327         {
328             parsedData->setUnique(true);
329         }
330         | PRIMARY 
331         {
332             parsedData->setUnique(true);
333             parsedData->setPrimary(true);
334         }
335         |
336         {
337             parsedData->setUnique(false);
338             parsedData->setPrimary(false);
339         }
340         ;
341 create_defn_list: create_defn_list create_defn_list_L
342         | create_defn 
343         ;
345 create_defn_list_L: ',' create_defn
346         ;
348 create_defn: field_defn
349         {
350             parsedData->insertFldDef();
351         }
352         | constraint_defn
353         ;
355 field_defn: field_name field_type size_opt null_expr_opt default_expr_opt
356         ;
358 field_name: ident
359         {
360             parsedData->setFldName($1);
361             free($1);
362         }
363 size_opt:
364         | '(' NUMBER_STRING ')'
365         {
366             parsedData->setFldLength(atoi($2)+1);
367             free($2);
368         }
369         ;
371 default_expr_opt:
372         | DEFAULT value
373         {
374             parsedData->setDefaultValue($2);
375             free($2);
376         }
377         ;
379 null_expr_opt:
380         | NOT NULL_VALUE
381         {
382             parsedData->setFldNotNull(true);
383         }
384         ;
385 constraint_defn: primary_key_constraint
386         ;
388 primary_key_constraint: PRIMARY KEY '(' field_list ')'
389         {
390             parsedData->setPrimary(true);
391         }
392         ;
394 field_type: INT_TYPE
395         {
396             parsedData->setFldType(typeInt);
397         }
398         | LONG_TYPE
399         {
400             parsedData->setFldType(typeLong);
401         }
402         | SHORT_TYPE
403         {
404             parsedData->setFldType(typeShort);
405         }
406         | BIGINT_TYPE
407         {
408             parsedData->setFldType(typeLongLong);
409         }
410         | TINYINT_TYPE
411         {
412             parsedData->setFldType(typeByteInt);
413         }
414         | FLOAT_TYPE
415         {
416             parsedData->setFldType(typeFloat);
417         }
418         | DOUBLE_TYPE
419         {
420             parsedData->setFldType(typeDouble);
421         }
422         ;
423         | DATE_TYPE
424         {
425             parsedData->setFldType(typeDate);
426         }
427         ;
428         | TIME_TYPE
429         {
430             parsedData->setFldType(typeTime);
431         }
432         ;
433         | TIMESTAMP_TYPE
434         {
435             parsedData->setFldType(typeTimeStamp);
436         }
437         ;
438         | CHAR_TYPE
439         {
440             parsedData->setFldType(typeString);
441             parsedData->setFldLength(2);
442         }
443         ;
446 extern int lexEof;
447 void yyerror(const char* Msg) { 
448     if( lexEof == 0 )
449         fprintf(stderr, "[Parser: %s] %s\n", Msg, yytext);
451     return;