Enterprise to opensource. 40 files including Makefil.am and .in from storage, sqllog...
[csql.git] / src / sql / dmlyacc.yxx
blob748b3d485ab6aad48337c96ad457ec1d916e1357
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 AUTO_INCREMENT
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 SIZE
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 auto_increment_key
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         | NULL_VALUE
206         {
207             Expression* exp;
208             exp=parsedData->insertExpression("NULL");
209             free($1);
210             $$=exp;
211         }
212         ;
213      
214 where_clause_opt:  WHERE conditions
215         |
216         ;
217 group_by_opt:  GROUP BY group_field_list
218         |
219         ;
220 group_field_list: group_field_list group_field_list_L
221         | group_field 
222         ;
223 group_field_list_L: ',' group_field
224         ;
225 group_field:   ident
226         {
227             parsedData->insertGroupField((char*)$1);
228             free( $1 );
229         }
230         ;
231 conditions: conditions OR conditions
232         {
233             Predicate *pred;
234             pred = parsedData->insertPredicate((Predicate*) $1, OpOr, (Predicate*) $3);
235             parsedData->setCondition((Predicate*)pred);
236             $$= pred;
238         }
239         | conditions AND conditions
240         {
241             Predicate *pred;
242             pred = parsedData->insertPredicate((Predicate*) $1, OpAnd, (Predicate*) $3);
243             parsedData->setCondition((Predicate*)pred);
244             $$= pred;
245         }
246         | '(' conditions ')' { $$=$2; }
247         | NOT '(' conditions ')'
248         {
249             Predicate *pred;
250             pred = parsedData->insertPredicate((Predicate*) $3, OpNot, NULL);
251             parsedData->setCondition((Predicate*)pred);
252             $$= pred;
254         }
255         | not_opt condition
256         {
257             if( $1 == (char*) 1 )
258             {
259                 Predicate *pred;
260                 pred = parsedData->insertPredicate((Predicate*) $2, OpNot, NULL);
261                 parsedData->setCondition((Predicate*)pred);
262                 $$= pred;
263             }
264             else
265             {
266                 parsedData->setCondition((Predicate*)$2);
267                 $$=$2;
268             }
269         }
270         ;
271 condition: ident OPERATOR value 
272         {
273             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
274                         bool opLike = false;
275             if (op == OpLike) {
276                 char *c = (char *)$3;
277                 while (*c != '\0') {
278                     if (*c == '_') *c = '?';
279                     else if(*c == '%') *c = '*';
280                     c++;
281                             }
282                                 opLike = true;
283             }
284             Predicate *pred;
285             void **ptr = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$3, opLike);
286             pred = parsedData->insertPredicate((char*) $1, op, ptr);
287             free( $1 ); free($2); free( $3 ); 
288             $$=pred;
289         }
290         | ident OPERATOR ident
291         {
292             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
293             Predicate *pred;
294             parsedData->insertCondValue((char*) $1);
295             parsedData->insertCondValue((char*) $3);
296             pred = parsedData->insertPredicate((char*) $1, op, (char*) $3);
297             free( $1 ); free($2); free( $3 );
298             $$=pred;
299         }
301         | ident not_opt BETWEEN value AND value
302         {
303             void **ptr1 = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$4);
304             void **ptr2 = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$6);
305             Predicate *finalPred;
306  //           pred1 = parsedData->insertPredicate((char*) $1, OpGreaterThanEquals, ptr1);
307 //            pred2 = parsedData->insertPredicate((char*) $1, OpLessThanEquals, ptr2);
308             finalPred = parsedData->insertBetPredicate((char*) $1, 
309                         OpGreaterThanEquals, ptr1, OpLessThanEquals, ptr2);
310                         //OpLessThanEquals, ptr2, OpGreaterThanEquals, ptr1);
312             if( $2 == (char*) 1 )
313                 finalPred = parsedData->insertPredicate(finalPred, OpNot, NULL);
314             free( $1 );  free( $4 );  free( $6 );
315             $$= finalPred;
316         }
317         | ident not_opt IN '(' invalue_list ')'
318         {
319             ListIterator valIter = parsedData->getInValueList().getIterator();
320             FieldValue *value1, *value2;
321             Predicate *pred1, *pred2, *finalPred;
322             void **ptr1, **ptr2;
323             if (valIter.hasElement()) {
324                value1 = (FieldValue*) valIter.nextElement();
325                ptr1 = parsedData->insertCondValueAndGetPtr((char*)$1, value1->parsedString);
326                pred1 = parsedData->insertPredicate((char*) $1, OpEquals, ptr1);
327                finalPred=pred1;
328             }
329             while (valIter.hasElement()) {
330                value2 = (FieldValue*) valIter.nextElement();
331                ptr2 = parsedData->insertCondValueAndGetPtr((char*)$1, value2->parsedString);
332                pred2 = parsedData->insertPredicate((char*) $1, OpEquals, ptr2);
333                finalPred = parsedData->insertPredicate(pred1, OpOr, pred2);
334                pred1= finalPred;     
335             }
336             if( $2 == (char*)1)
337                 finalPred = parsedData->insertPredicate(finalPred, OpNot, NULL);
339             free( $1 );  
340             $$= finalPred;
341         }
342         ;
343 not_opt: NOT
344         { $$=(char*) 1;
345         }
346         | 
347         { $$=(char*) 0; }
348         ;
349 table:   ident
350         {
351             parsedData->insertTableName((char*)$1);
352             free( $1 );
353         }
354         ;
355 field:   ident
356         {
357             parsedData->insertField((char*)$1);
358             free( $1 );
359             
360         }
361         | MIN  '(' ident ')'
362         { 
363             parsedData->insertField((char*)$3, AGG_MIN);
364             free( $1 );
365         }
366         | MAX  '(' ident ')'
367         { 
368             parsedData->insertField((char*)$3, AGG_MAX);
369             free( $1 );
370         }
371         | SUM  '(' ident ')'
372         { 
373             parsedData->insertField((char*)$3, AGG_SUM);
374             free( $1 );
375         }
376         | AVG  '(' ident ')'
377         { 
378             parsedData->insertField((char*)$3, AGG_AVG);
379             free( $1 );
380         }
381         | COUNT  '(' ident ')'
382         { 
383             parsedData->insertField((char*)$3, AGG_COUNT);
384             free( $1 );
385         }
386         | COUNT  '(' '*' ')'
387         { 
388             parsedData->insertField("*", AGG_COUNT);
389             free( $1 );
390         }
391         | '*'
392         { 
393             parsedData->insertField("*");
394         }
395         ;
396 ident:    FIELD { $$ = $1; }
397         ;
398 value:    STRING { $$ = $1; }
399         | num_value
400         | BINARY_STRING { $$ = $1; }
401         | doub_value
402         | PARAMETER { $$ = $1; }
403         | NULL_VALUE { $$ = (char*) 0; }
404         ;
405 num_value: NUMBER_STRING { $$ =  $1; }
406         | '-' NUMBER_STRING %prec UMINUS
407         {
408              char *n;
409              n=(char*)malloc(30);
410              strcpy(n,"-");
411              strcat(n,(char*)$2);
412              $$=n;
413              free($2);
414         }
415         | '+' NUMBER_STRING %prec UMINUS{ $$ =  $2; }
416         ;
417 doub_value : DOUBLE { $$ = $1; }
418         | '-' DOUBLE %prec UMINUS
419         {
420              char *d;
421              d=(char*)malloc(30);
422              strcpy(d,"-");
423              strcat(d,(char*)$2);
424              $$=d;
425              free($2);
426         }
427         | '+' DOUBLE %prec UMINUS{ $$ = $2; }
428         ;
430 ddl_statement: CREATE TABLE ident '(' create_defn_list_con ')' semicolon_opt
431         {
432             parsedData->setStmtType(CreateTableStatement);
433             parsedData->setTableName($3); 
434             free($3);
435         }
436         | CREATE INDEX ident ON ident '(' field_list ')' opt_constr_type opt_ind_type  opt_bucket semicolon_opt
437         {
438             parsedData->setStmtType(CreateIndexStatement);
439             parsedData->setIndexName($3); 
440             parsedData->setTableName($5); 
441             free($3);
442             free($5);
443         }
444         | DROP TABLE ident
445         {
446             parsedData->setStmtType(DropTableStatement);
447             parsedData->setTableName($3); 
448             free($3);
449         }
450         | DROP INDEX ident
451         {
452             parsedData->setStmtType(DropIndexStatement);
453             parsedData->setIndexName($3); 
454             free($3);
455         }
456         ;
457 opt_ind_type:
458         | HASH  opt_constr_type
459         {
460             parsedData->setIndexType(hashIndex);
461         }
462         | TREE  opt_constr_type
463         {
464             parsedData->setIndexType(treeIndex);
465         }
466         |
467         {
468             parsedData->setIndexType(hashIndex);
469         }
470         ;
471 opt_constr_type:
472         | UNIQUE 
473         {
474             parsedData->setUnique(true);
475         }
476         | PRIMARY 
477         {
478             parsedData->setUnique(true);
479             parsedData->setPrimary(true);
480         }
481         |
482         {
483             parsedData->setUnique(false);
484             parsedData->setPrimary(false);
485         }
486         ;
487 opt_bucket:
488         | SIZE NUMBER_STRING
489         {
490             parsedData->setBucketSize(atoi($2));
491             free($2);
492         }
493         ;
494 create_defn_list_con:create_defn_list
495         |create_defn_list ',' constraint_defn
496         ;
497 create_defn_list: create_defn_list create_defn_list_L
498         | create_defn
499         ;
501 create_defn_list_L: ',' create_defn
502         ;
504 create_defn: field_defn
505         {
506             parsedData->insertFldDef();
507         }
508         ;
510 field_defn: field_name field_type size_opt null_expr_opt default_expr_opt auto_increment_key
511         ;
513 field_name: ident
514         {
515             parsedData->setFldName($1);
516             free($1);
517         }
518 size_opt:
519         | '(' NUMBER_STRING ')'
520         {
521             DbRetVal rv = parsedData->setFldLength(atoi($2));
522             if (rv != OK) {
523                 yyerror("Binary field length < 256");
524                 free($2);
525                 YYABORT;
526             }
527             free($2);
528         }
529         ;
531 default_expr_opt:
532         | DEFAULT value
533         {
534             parsedData->setDefaultValue($2);
535             free($2);
536         }
537         ;
539 null_expr_opt:
540         | NOT NULL_VALUE
541         {
542             parsedData->setFldNotNull(true);
543         }
544         ;
545 constraint_defn: primary_key_constraint
546         ;
548 primary_key_constraint: PRIMARY KEY '(' field_list ')' opt_bucket
549         {
550            parsedData->setPrimary(true);
551         }
552         ;
553 auto_increment_key:
554         | AUTO_INCREMENT
555         {
556            DataType type = parsedData->getFldType();
557            if(type > 4)
558            {
559                yyerror("AUTO_INCREMENT KEY can't be created other than INTEGER field ");
560                free($1);
561                YYABORT;
562            }
563            DbRetVal ret = parsedData->setAutoIncreament(true);
564            if(ret != OK){
565                yyerror("A table should have only one AUTO_INCREMENT KEY ");
566                free($1);
567                YYABORT;
568            }
569            parsedData->setFldNotNull(true);
570            parsedData->setAutoFldName(parsedData->getFldName());
571            parsedData->setPrimary(true);
572         }
573         ;
574 field_type: INT_TYPE
575         {
576             parsedData->setFldType(typeInt);
577         }
578         | LONG_TYPE
579         {
580             parsedData->setFldType(typeLong);
581         }
582         | SHORT_TYPE
583         {
584             parsedData->setFldType(typeShort);
585         }
586         | BIGINT_TYPE
587         {
588             parsedData->setFldType(typeLongLong);
589         }
590         | TINYINT_TYPE
591         {
592             parsedData->setFldType(typeByteInt);
593         }
594         | FLOAT_TYPE
595         {
596             parsedData->setFldType(typeFloat);
597         }
598         | DOUBLE_TYPE
599         {
600             parsedData->setFldType(typeDouble);
601         }
602         ;
603         | DATE_TYPE
604         {
605             parsedData->setFldType(typeDate);
606         }
607         ;
608         | TIME_TYPE
609         {
610             parsedData->setFldType(typeTime);
611         }
612         ;
613         | TIMESTAMP_TYPE
614         {
615             parsedData->setFldType(typeTimeStamp);
616         }
617         ;
618         | CHAR_TYPE
619         {
620             parsedData->setFldType(typeString);
621             parsedData->setFldLength(2);
622         }
623         ;
624         | BINARY_TYPE
625         {
626             parsedData->setFldType(typeBinary);
627             parsedData->setFldLength(1);
628         }
629         ;
632 extern int lexEof;
633 void yyerror(const char* Msg) { 
634     if( lexEof == 0 )
635         fprintf(stderr, "[Parser: %s] %s\n", Msg, yytext);
637     return;