2031095 select count(*) from t1 is not working
[csql.git] / src / sql / dmlyacc.yxx
blob2f65c457a3a71aff9de996c1438359e68b774ba9
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 BINARY_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                         bool opLike = false;
179             if (op == OpLike) {
180                 char *c = (char *)$3;
181                 while (*c != '\0') {
182                     if (*c == '_') *c = '?';
183                     else if(*c == '%') *c = '*';
184                     c++;
185                             }
186                                 opLike = true;
187             }
188             Predicate *pred;
189             void **ptr = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$3, opLike);
190             pred = parsedData->insertPredicate((char*) $1, op, ptr);
191             free( $1 ); free($2); free( $3 ); 
192             $$=pred;
193         }
194         | ident OPERATOR ident
195         {
196             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
197             Predicate *pred;
198             pred = parsedData->insertPredicate((char*) $1, op, (char*) $3);
199             free( $1 ); free($2); free( $3 );
200             $$=pred;
201         }
203         | ident not_opt BETWEEN value AND value
204         {
205             void **ptr1 = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$4);
206             void **ptr2 = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$6);
207             Predicate *pred1, *pred2, *pred3, *finalPred;
208             pred1 = parsedData->insertPredicate((char*) $1, OpGreaterThanEquals, ptr1);
209             pred2 = parsedData->insertPredicate((char*) $1, OpLessThanEquals, ptr2);
210             finalPred = parsedData->insertPredicate(pred1, OpAnd, pred2);
211             if( $2 == (char*) 1 )
212                 finalPred = parsedData->insertPredicate(finalPred, OpNot, NULL);
213             free( $1 );  free( $4 );  free( $6 );
214             $$= finalPred;
215         }
216         | ident not_opt IN '(' invalue_list ')'
217         {
218             ListIterator valIter = parsedData->getInValueList().getIterator();
219             FieldValue *value1, *value2;
220             Predicate *pred1, *pred2, *finalPred;
221             void **ptr1, **ptr2;
222             if (valIter.hasElement()) {
223                value1 = (FieldValue*) valIter.nextElement();
224                ptr1 = parsedData->insertCondValueAndGetPtr((char*)$1, value1->parsedString);
225                pred1 = parsedData->insertPredicate((char*) $1, OpEquals, ptr1);
226                finalPred=pred1;
227             }
228             while (valIter.hasElement()) {
229                value2 = (FieldValue*) valIter.nextElement();
230                ptr2 = parsedData->insertCondValueAndGetPtr((char*)$1, value2->parsedString);
231                pred2 = parsedData->insertPredicate((char*) $1, OpEquals, ptr2);
232                finalPred = parsedData->insertPredicate(pred1, OpOr, pred2);
233                pred1= finalPred;     
234             }
235             if( $2 == (char*)1)
236                 finalPred = parsedData->insertPredicate(finalPred, OpNot, NULL);
238             free( $1 );  
239             $$= finalPred;
240         }
241         ;
242 not_opt: NOT
243         { $$=(char*) 1;
244         }
245         | 
246         { $$=(char*) 0; }
247         ;
248 field:   ident
249         {
250             parsedData->insertField((char*)$1);
251             free( $1 );
252         }
253         | MIN  '(' ident ')'
254         { 
255             parsedData->insertField((char*)$3, AGG_MIN);
256             free( $1 );
257         }
258         | MAX  '(' ident ')'
259         { 
260             parsedData->insertField((char*)$3, AGG_MAX);
261             free( $1 );
262         }
263         | SUM  '(' ident ')'
264         { 
265             parsedData->insertField((char*)$3, AGG_SUM);
266             free( $1 );
267         }
268         | AVG  '(' ident ')'
269         { 
270             parsedData->insertField((char*)$3, AGG_AVG);
271             free( $1 );
272         }
273         | COUNT  '(' ident ')'
274         { 
275             parsedData->insertField((char*)$3, AGG_COUNT);
276             free( $1 );
277         }
278         | COUNT  '(' STAR ')'
279         { 
280             parsedData->insertField("*", AGG_COUNT);
281             free( $1 );
282         }
283         | STAR
284         { 
285             parsedData->insertField((char*)$1);
286             free( $1 );
287         }
288         ;
289 ident:    FIELD { $$ = $1; }
290         ;
291 value:    STRING { $$ = $1; }
292         | NUMBER_STRING { $$ = $1; }
293         | BINARY_STRING { $$ = $1; }
294         | DOUBLE { $$ = $1; }
295         | PARAMETER { $$ = $1; }
296         | NULL_VALUE { $$ = (char*) 0; }
297         ;
299 ddl_statement: CREATE TABLE ident '(' create_defn_list ')' semicolon_opt
300         {
301             parsedData->setStmtType(CreateTableStatement);
302             parsedData->setTableName($3); 
303             free($3);
304         }
305         | CREATE INDEX ident ON ident '(' field_list ')' opt_constr_type opt_ind_type  semicolon_opt
306         {
307             parsedData->setStmtType(CreateIndexStatement);
308             parsedData->setIndexName($3); 
309             parsedData->setTableName($5); 
310             free($3);
311             free($5);
312         }
313         | DROP TABLE ident
314         {
315             parsedData->setStmtType(DropTableStatement);
316             parsedData->setTableName($3); 
317             free($3);
318         }
319         | DROP INDEX ident
320         {
321             parsedData->setStmtType(DropIndexStatement);
322             parsedData->setIndexName($3); 
323             free($3);
324         }
325         ;
326 opt_ind_type:
327         | HASH  opt_constr_type
328         {
329             parsedData->setIndexType(hashIndex);
330         }
331         | TREE  opt_constr_type
332         {
333             parsedData->setIndexType(treeIndex);
334         }
335         |
336         {
337             parsedData->setIndexType(hashIndex);
338         }
339         ;
340 opt_constr_type:
341         | UNIQUE 
342         {
343             parsedData->setUnique(true);
344         }
345         | PRIMARY 
346         {
347             parsedData->setUnique(true);
348             parsedData->setPrimary(true);
349         }
350         |
351         {
352             parsedData->setUnique(false);
353             parsedData->setPrimary(false);
354         }
355         ;
356 create_defn_list: create_defn_list create_defn_list_L
357         | create_defn 
358         ;
360 create_defn_list_L: ',' create_defn
361         ;
363 create_defn: field_defn
364         {
365             parsedData->insertFldDef();
366         }
367         | constraint_defn
368         ;
370 field_defn: field_name field_type size_opt null_expr_opt default_expr_opt
371         ;
373 field_name: ident
374         {
375             parsedData->setFldName($1);
376             free($1);
377         }
378 size_opt:
379         | '(' NUMBER_STRING ')'
380         {
381             parsedData->setFldLength(atoi($2)+1);
382             free($2);
383         }
384         ;
386 default_expr_opt:
387         | DEFAULT value
388         {
389             parsedData->setDefaultValue($2);
390             free($2);
391         }
392         ;
394 null_expr_opt:
395         | NOT NULL_VALUE
396         {
397             parsedData->setFldNotNull(true);
398         }
399         ;
400 constraint_defn: primary_key_constraint
401         ;
403 primary_key_constraint: PRIMARY KEY '(' field_list ')'
404         {
405             parsedData->setPrimary(true);
406         }
407         ;
409 field_type: INT_TYPE
410         {
411             parsedData->setFldType(typeInt);
412         }
413         | LONG_TYPE
414         {
415             parsedData->setFldType(typeLong);
416         }
417         | SHORT_TYPE
418         {
419             parsedData->setFldType(typeShort);
420         }
421         | BIGINT_TYPE
422         {
423             parsedData->setFldType(typeLongLong);
424         }
425         | TINYINT_TYPE
426         {
427             parsedData->setFldType(typeByteInt);
428         }
429         | FLOAT_TYPE
430         {
431             parsedData->setFldType(typeFloat);
432         }
433         | DOUBLE_TYPE
434         {
435             parsedData->setFldType(typeDouble);
436         }
437         ;
438         | DATE_TYPE
439         {
440             parsedData->setFldType(typeDate);
441         }
442         ;
443         | TIME_TYPE
444         {
445             parsedData->setFldType(typeTime);
446         }
447         ;
448         | TIMESTAMP_TYPE
449         {
450             parsedData->setFldType(typeTimeStamp);
451         }
452         ;
453         | CHAR_TYPE
454         {
455             parsedData->setFldType(typeString);
456             parsedData->setFldLength(2);
457         }
458         ;
459         | BINARY_TYPE
460         {
461             parsedData->setFldType(typeBinary);
462             parsedData->setFldLength(1);
463         }
464         ;
467 extern int lexEof;
468 void yyerror(const char* Msg) { 
469     if( lexEof == 0 )
470         fprintf(stderr, "[Parser: %s] %s\n", Msg, yytext);
472     return;