reverting back to 1.12
[csql.git] / src / sql / dmlyacc.yxx
blob2c44a5533d83651b5ce151a2d0b357e890e41984
1 %{
2 #include <CSql.h>
3 #include <stdlib.h>
4 #include "Parser.h"
6 class Predicate;
7 ParsedData *parsedData;
8 extern char yytext[];
9 int yylex( void );
10 void yyerror(const char* Msg);
14 %union
16    char *stringval;
17    void *predicate;
18    void *Expression;
21 %left OR 
22 %left AND
23 %left '+' '-'
24 %left '*' '/' '%'
25 %nonassoc UMINUS
26 %token <stringval> STRING FIELD NUMBER_STRING BINARY_STRING DOUBLE OPERATOR PARAMETER
27 %token <stringval> SELECT FROM WHERE BETWEEN IN AND OR NOT
28 %token <stringval> INSERT INTO VALUES
29 %token <stringval> DELETE UPDATE SET NULL_VALUE
30 %token <stringval> CREATE TABLE PRIMARY KEY DEFAULT INDEX ON HASH TREE UNIQUE DROP
31 %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
32 %token <stringval> MIN MAX AVG SUM COUNT GROUP BY
33 %token ';' ',' '(' ')'
34 %type <stringval> ident field value not_opt doub_value num_value
35 %type <predicate> conditions condition 
36 %type <Expression> stmt_exp atom
38 command:  select_statement { YYACCEPT; }
39         | insert_statement { YYACCEPT; }
40         | delete_statement { YYACCEPT; }
41         | update_statement { YYACCEPT; }
42         | ddl_statement { YYACCEPT; }
43         ;
44         
45 select_statement: SELECT field_list FROM table_list where_clause_opt group_by_opt semicolon_opt
46         {
47             parsedData->setStmtType(SelectStatement);
48             //parsedData->setTableName($4); 
49             //free($4);
50         }
51         ;
53 field_list: field_list field_list_L
54         | field 
55         ;
56 field_list_L: ',' field
57         ;
58 table_list: table_list table_list_L
59         | table 
60         ;
61 table_list_L: ',' table
62         ;
63         
64 insert_statement: INSERT INTO ident field_list_opt VALUES '(' value_list ')' semicolon_opt
65         {
66             parsedData->setStmtType(InsertStatement);
67             parsedData->setTableName($3); 
68             free($3);
69         }
70         ;
72 field_list_opt:
73         | '(' field_list ')'
74         ;
76 value_list: value_list value_list_L
77         | value
78         {
79             parsedData->insertValue((char*)$1);
80             free($1);
81         }
82         ;
83 value_list_L: ',' value 
84         {
85             parsedData->insertValue((char*)$2);
86             free($2);
87         }
88         ;
89         
90 invalue_list: invalue_list invalue_list_L
91         | value
92         {
93             parsedData->insertInValue((char*)$1);
94             free($1);
95         }
96         ;
97 invalue_list_L: ',' value 
98         {
99             parsedData->insertInValue((char*)$2);
100             free($2);
101         }
102         ;
103         
104 delete_statement: DELETE FROM ident where_clause_opt semicolon_opt
105         {
106             parsedData->setStmtType(DeleteStatement);
107             parsedData->setTableName($3); 
108             free($3);
109         }
110         ;
111         
112 update_statement: UPDATE ident SET assign_list where_clause_opt semicolon_opt
113         {
114             parsedData->setStmtType(UpdateStatement);
115             parsedData->setTableName($2); 
116             free( $2 );
117         }
118         ;
120 semicolon_opt: ';'
121         |
122         ;
124 assign_list: assign_list assign_list_L
125         | assign_stmt
126         ;
128 assign_list_L: ',' assign_stmt
129         ;
130 assign_stmt: ident  OPERATOR stmt_exp
131         {
132            parsedData->insertUpdateExpression( (char*) $1, (Expression* ) $3);
133            free( $1 ); free($2);
134         }
135         | ident OPERATOR value 
136         { 
137             parsedData->insertUpdateValue( (char*) $1, (char*) $3);
138             free( $1 ); free($2);free( $3 ); 
139         }
140         | ident OPERATOR NULL_VALUE 
141         {
142             parsedData->insertUpdateValue( (char*) $1, (char*) $3);
143             free( $1 ); free($2);free( $3 );
144         }
145         ; 
146 stmt_exp: stmt_exp '/' stmt_exp
147         {
148             Expression* exp;
149             exp=parsedData->insertExpression((Expression *)$1, division, (Expression *)$3);
150             $$=exp;
151         } 
152         | stmt_exp '%' stmt_exp
153         {
154             Expression* exp;
155             exp=parsedData->insertExpression((Expression *)$1, modulus, (Expression *)$3);
156             $$=exp;
157         }
158         | stmt_exp '*' stmt_exp
159         {
160             Expression* exp;
161             exp=parsedData->insertExpression((Expression *)$1, multiplication, (Expression *)$3);
162             $$=exp;
163         }
164         | stmt_exp '+' stmt_exp
165         {
166             Expression* exp;
167             exp=parsedData->insertExpression((Expression *)$1, addition, (Expression *)$3);
168             $$=exp;
169         }
170         | stmt_exp '-' stmt_exp
171         {
172             Expression* exp;
173             exp=parsedData->insertExpression((Expression *)$1, subtraction, (Expression *)$3);
174             $$=exp;
175         }
176         | '(' stmt_exp ')'
177         {
178             $$=$2;
179         }
180         | '-' stmt_exp %prec UMINUS
181         {
182             $$ = $2;
183         }
184         | '+' stmt_exp %prec UMINUS
185         {
186             $$ = $2;
187         }
188         | atom
189         ;
190 atom    :  ident
191         {
192             Expression* exp;
193             exp=parsedData->insertExpression((char *)$1);
194             free($1);
195             $$=exp;
196         }
197         | value
198         {
199             Expression* exp;
200             bool flag = false;
201             exp=parsedData->insertExpression((char *)$1, flag);
202             free($1);
203             $$=exp;
204         }
205         ;
206      
207 where_clause_opt:  WHERE conditions
208         |
209         ;
210 group_by_opt:  GROUP BY group_field_list
211         |
212         ;
213 group_field_list: group_field_list group_field_list_L
214         | group_field 
215         ;
216 group_field_list_L: ',' group_field
217         ;
218 group_field:   ident
219         {
220             parsedData->insertGroupField((char*)$1);
221             free( $1 );
222         }
223         ;
224 conditions: conditions OR conditions
225         {
226             Predicate *pred;
227             pred = parsedData->insertPredicate((Predicate*) $1, OpOr, (Predicate*) $3);
228             parsedData->setCondition((Predicate*)pred);
229             $$= pred;
231         }
232         | conditions AND conditions
233         {
234             Predicate *pred;
235             pred = parsedData->insertPredicate((Predicate*) $1, OpAnd, (Predicate*) $3);
236             parsedData->setCondition((Predicate*)pred);
237             $$= pred;
238         }
239         | '(' conditions ')' { $$=$2; }
240         | NOT '(' conditions ')'
241         {
242             Predicate *pred;
243             pred = parsedData->insertPredicate((Predicate*) $3, OpNot, NULL);
244             parsedData->setCondition((Predicate*)pred);
245             $$= pred;
247         }
248         | not_opt condition
249         {
250             if( $1 == (char*) 1 )
251             {
252                 Predicate *pred;
253                 pred = parsedData->insertPredicate((Predicate*) $2, OpNot, NULL);
254                 parsedData->setCondition((Predicate*)pred);
255                 $$= pred;
256             }
257             else
258             {
259                 parsedData->setCondition((Predicate*)$2);
260                 $$=$2;
261             }
262         }
263         ;
264 condition: ident OPERATOR value 
265         {
266             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
267                         bool opLike = false;
268             if (op == OpLike) {
269                 char *c = (char *)$3;
270                 while (*c != '\0') {
271                     if (*c == '_') *c = '?';
272                     else if(*c == '%') *c = '*';
273                     c++;
274                             }
275                                 opLike = true;
276             }
277             Predicate *pred;
278             void **ptr = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$3, opLike);
279             pred = parsedData->insertPredicate((char*) $1, op, ptr);
280             free( $1 ); free($2); free( $3 ); 
281             $$=pred;
282         }
283         | ident OPERATOR ident
284         {
285             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
286             Predicate *pred;
287             pred = parsedData->insertPredicate((char*) $1, op, (char*) $3);
288             free( $1 ); free($2); free( $3 );
289             $$=pred;
290         }
292         | ident not_opt BETWEEN value AND value
293         {
294             void **ptr1 = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$4);
295             void **ptr2 = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$6);
296             Predicate *finalPred;
297  //           pred1 = parsedData->insertPredicate((char*) $1, OpGreaterThanEquals, ptr1);
298 //            pred2 = parsedData->insertPredicate((char*) $1, OpLessThanEquals, ptr2);
299             finalPred = parsedData->insertBetPredicate((char*) $1, 
300                         OpGreaterThanEquals, ptr1, OpLessThanEquals, ptr2);
301                         //OpLessThanEquals, ptr2, OpGreaterThanEquals, ptr1);
303             if( $2 == (char*) 1 )
304                 finalPred = parsedData->insertPredicate(finalPred, OpNot, NULL);
305             free( $1 );  free( $4 );  free( $6 );
306             $$= finalPred;
307         }
308         | ident not_opt IN '(' invalue_list ')'
309         {
310             ListIterator valIter = parsedData->getInValueList().getIterator();
311             FieldValue *value1, *value2;
312             Predicate *pred1, *pred2, *finalPred;
313             void **ptr1, **ptr2;
314             if (valIter.hasElement()) {
315                value1 = (FieldValue*) valIter.nextElement();
316                ptr1 = parsedData->insertCondValueAndGetPtr((char*)$1, value1->parsedString);
317                pred1 = parsedData->insertPredicate((char*) $1, OpEquals, ptr1);
318                finalPred=pred1;
319             }
320             while (valIter.hasElement()) {
321                value2 = (FieldValue*) valIter.nextElement();
322                ptr2 = parsedData->insertCondValueAndGetPtr((char*)$1, value2->parsedString);
323                pred2 = parsedData->insertPredicate((char*) $1, OpEquals, ptr2);
324                finalPred = parsedData->insertPredicate(pred1, OpOr, pred2);
325                pred1= finalPred;     
326             }
327             if( $2 == (char*)1)
328                 finalPred = parsedData->insertPredicate(finalPred, OpNot, NULL);
330             free( $1 );  
331             $$= finalPred;
332         }
333         ;
334 not_opt: NOT
335         { $$=(char*) 1;
336         }
337         | 
338         { $$=(char*) 0; }
339         ;
340 table:   ident
341         {
342             parsedData->insertTableName((char*)$1);
343             free( $1 );
344         }
345         ;
346 field:   ident
347         {
348             parsedData->insertField((char*)$1);
349             free( $1 );
350             
351         }
352         | MIN  '(' ident ')'
353         { 
354             parsedData->insertField((char*)$3, AGG_MIN);
355             free( $1 );
356         }
357         | MAX  '(' ident ')'
358         { 
359             parsedData->insertField((char*)$3, AGG_MAX);
360             free( $1 );
361         }
362         | SUM  '(' ident ')'
363         { 
364             parsedData->insertField((char*)$3, AGG_SUM);
365             free( $1 );
366         }
367         | AVG  '(' ident ')'
368         { 
369             parsedData->insertField((char*)$3, AGG_AVG);
370             free( $1 );
371         }
372         | COUNT  '(' ident ')'
373         { 
374             parsedData->insertField((char*)$3, AGG_COUNT);
375             free( $1 );
376         }
377         | COUNT  '(' '*' ')'
378         { 
379             parsedData->insertField("*", AGG_COUNT);
380             free( $1 );
381         }
382         | '*'
383         { 
384             parsedData->insertField("*");
385         }
386         ;
387 ident:    FIELD { $$ = $1; }
388         ;
389 value:    STRING { $$ = $1; }
390         | num_value
391         | BINARY_STRING { $$ = $1; }
392         | doub_value
393         | PARAMETER { $$ = $1; }
394         | NULL_VALUE { $$ = (char*) 0; }
395         ;
396 num_value: NUMBER_STRING { $$ =  $1; }
397         | '-' NUMBER_STRING %prec UMINUS
398         {
399              char *n;
400              n=(char*)malloc(30);
401              strcpy(n,"-");
402              strcat(n,(char*)$2);
403              $$=n;
404              free($2);
405         }
406         | '+' NUMBER_STRING %prec UMINUS{ $$ =  $2; }
407         ;
408 doub_value : DOUBLE { $$ = $1; }
409         | '-' DOUBLE %prec UMINUS
410         {
411              char *d;
412              d=(char*)malloc(30);
413              strcpy(d,"-");
414              strcat(d,(char*)$2);
415              $$=d;
416              free($2);
417         }
418         | '+' DOUBLE %prec UMINUS{ $$ = $2; }
419         ;
421 ddl_statement: CREATE TABLE ident '(' create_defn_list_con ')' semicolon_opt
422         {
423             parsedData->setStmtType(CreateTableStatement);
424             parsedData->setTableName($3); 
425             free($3);
426         }
427         | CREATE INDEX ident ON ident '(' field_list ')' opt_constr_type opt_ind_type  semicolon_opt
428         {
429             parsedData->setStmtType(CreateIndexStatement);
430             parsedData->setIndexName($3); 
431             parsedData->setTableName($5); 
432             free($3);
433             free($5);
434         }
435         | DROP TABLE ident
436         {
437             parsedData->setStmtType(DropTableStatement);
438             parsedData->setTableName($3); 
439             free($3);
440         }
441         | DROP INDEX ident
442         {
443             parsedData->setStmtType(DropIndexStatement);
444             parsedData->setIndexName($3); 
445             free($3);
446         }
447         ;
448 opt_ind_type:
449         | HASH  opt_constr_type
450         {
451             parsedData->setIndexType(hashIndex);
452         }
453         | TREE  opt_constr_type
454         {
455             parsedData->setIndexType(treeIndex);
456         }
457         |
458         {
459             parsedData->setIndexType(hashIndex);
460         }
461         ;
462 opt_constr_type:
463         | UNIQUE 
464         {
465             parsedData->setUnique(true);
466         }
467         | PRIMARY 
468         {
469             parsedData->setUnique(true);
470             parsedData->setPrimary(true);
471         }
472         |
473         {
474             parsedData->setUnique(false);
475             parsedData->setPrimary(false);
476         }
477         ;
478 create_defn_list_con:create_defn_list
479         |create_defn_list ',' constraint_defn
480         ;
481 create_defn_list: create_defn_list create_defn_list_L
482         | create_defn
483         ;
485 create_defn_list_L: ',' create_defn
486         ;
488 create_defn: field_defn
489         {
490             parsedData->insertFldDef();
491         }
492         ;
494 field_defn: field_name field_type size_opt null_expr_opt default_expr_opt
495         ;
497 field_name: ident
498         {
499             parsedData->setFldName($1);
500             free($1);
501         }
502 size_opt:
503         | '(' NUMBER_STRING ')'
504         {
505             DbRetVal rv = parsedData->setFldLength(atoi($2)+1);
506             if (rv != OK) {
507                 yyerror("Binary field length < 256");
508                 free($2);
509                 YYABORT;
510             }
511             free($2);
512         }
513         ;
515 default_expr_opt:
516         | DEFAULT value
517         {
518             parsedData->setDefaultValue($2);
519             free($2);
520         }
521         ;
523 null_expr_opt:
524         | NOT NULL_VALUE
525         {
526             parsedData->setFldNotNull(true);
527         }
528         ;
529 constraint_defn: primary_key_constraint
530         ;
532 primary_key_constraint: PRIMARY KEY '(' field_list ')'
533         {
534            parsedData->setPrimary(true);
535         }
536         ;
538 field_type: INT_TYPE
539         {
540             parsedData->setFldType(typeInt);
541         }
542         | LONG_TYPE
543         {
544             parsedData->setFldType(typeLong);
545         }
546         | SHORT_TYPE
547         {
548             parsedData->setFldType(typeShort);
549         }
550         | BIGINT_TYPE
551         {
552             parsedData->setFldType(typeLongLong);
553         }
554         | TINYINT_TYPE
555         {
556             parsedData->setFldType(typeByteInt);
557         }
558         | FLOAT_TYPE
559         {
560             parsedData->setFldType(typeFloat);
561         }
562         | DOUBLE_TYPE
563         {
564             parsedData->setFldType(typeDouble);
565         }
566         ;
567         | DATE_TYPE
568         {
569             parsedData->setFldType(typeDate);
570         }
571         ;
572         | TIME_TYPE
573         {
574             parsedData->setFldType(typeTime);
575         }
576         ;
577         | TIMESTAMP_TYPE
578         {
579             parsedData->setFldType(typeTimeStamp);
580         }
581         ;
582         | CHAR_TYPE
583         {
584             parsedData->setFldType(typeString);
585             parsedData->setFldLength(2);
586         }
587         ;
588         | BINARY_TYPE
589         {
590             parsedData->setFldType(typeBinary);
591             parsedData->setFldLength(1);
592         }
593         ;
596 extern int lexEof;
597 void yyerror(const char* Msg) { 
598     if( lexEof == 0 )
599         fprintf(stderr, "[Parser: %s] %s\n", Msg, yytext);
601     return;