windows changes
[csql.git] / src / sql / dmlyacc.yxx
blob0b932198c88377de28b7383f86e416ec7f490584
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;
19    void *FunctionType;
22 %left OR 
23 %left AND
24 %left '+' '-'
25 %left '*' '/' '%'
26 %nonassoc UMINUS
27 %token <stringval> STRING FIELD NUMBER_STRING BINARY_STRING DOUBLE OPERATOR PARAMETER ALLTABLE DESCRIBE PRIMARYINFO AUTO_INCREMENT GETCATALOGS GETDATATYPES GETTABLETYPES IMPORTEDKEY EXPORTEDKEY
28 %token <stringval> SELECT FROM WHERE BETWEEN IN AND OR NOT AS LIMIT OFFSET INNER OUTER CROSS JOIN LEFT IS
29 %token <stringval> INSERT INTO VALUES EXPLAIN PLAN
30 %token <stringval> DELETE UPDATE SET NULL_VALUE
31 %token <stringval> CREATE TABLE PRIMARY KEY DEFAULT INDEX ON HASH TREE UNIQUE DROP SIZE FOREIGN REFERENCES COMPACT TRUNCATE 
32 %token <stringval> CACHE CONDITION FIELDLIST PK DIRECT DSN UNCACHE NOSCHEMA
33 %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 VARCHAR_TYPE
34 %token <stringval> DATE_DIFF DATE_ADD DATE_SUB HOUR MINUTE SECOND YEAR MONTH DAY INTERVAL TIME_DIFF TIME_ADD TIME_SUB TIMESTAMP_DIFF TIMESTAMP_ADD TIMESTAMP_SUB EXTRACT NOW
35 %token <stringval> USER PASSWORD ALTER FLUSH ADD COLUMN MODIFY RENAME TO
36 %token <stringval> MIN MAX AVG SUM COUNT GROUP BY HAVING ORDER ASC DESC DISTINCT
37 %token ';' ',' '(' ')'
38 %type <stringval> ident field value not_opt doub_value num_value 
39 /*%type <stringval> foreign_key_constraint foreign_key_create foreign_key_constraint_L*/
40 %type <predicate> conditions condition hconditions hcondition 
41 %type <Expression> stmt_exp atom function_opt
42 %type <FunctionType> date_opt time_opt datetime_opt
44 command:  select_statement { YYACCEPT; }
45         | insert_statement { YYACCEPT; }
46         | delete_statement { YYACCEPT; }
47         | update_statement { YYACCEPT; }
48         | ddl_statement { YYACCEPT; }
49         | internal_statement { YYACCEPT; }
50         | cache_statement { YYACCEPT; }
51         | copy_table_statement { YYACCEPT; }
52         | user_manager_statement { YYACCEPT; }
53         | management_statement { YYACCEPT; }
54         | alter_statement { YYACCEPT; }
55         | other {YYACCEPT;}
56         ;
57 alter_statement: ALTER TABLE ident ADD '(' create_defn_list_con ')' semicolon_opt
58         {
59             parsedData->setStmtType(AlterStatement);
60             parsedData->setAlterType(ALTERADD);
61             parsedData->setTableName($3);
62             free($3); 
63         }
64         | ALTER TABLE ident DROP COLUMN ident semicolon_opt
65         {
66             parsedData->setStmtType(AlterStatement);
67             parsedData->setAlterType(ALTERDROP);
68             parsedData->setTableName($3);
69             parsedData->setIndexName($6); 
70             free($3);
71         }
72         | ALTER TABLE ident MODIFY '(' create_defn ')' semicolon_opt
73         {
74             printf(" Not Implemented\n");
75             free($3);
76             YYABORT;
77         }
78         | RENAME TABLE ident TO ident semicolon_opt
79         {
80             parsedData->setStmtType(AlterStatement);
81             parsedData->setAlterType(ALTERTABLERENAME);
82             parsedData->setTableName($3);
83             parsedData->setIndexName($5); 
84             free($3); free($5);
86         }
87         | ALTER TABLE ident RENAME COLUMN ident TO ident semicolon_opt
88         {
89             parsedData->setStmtType(AlterStatement);
90             parsedData->setAlterType(ALTERFIELDRENAME);
91             parsedData->setTableName($3);
92             parsedData->setIndexName($6);
93             parsedData->setPKTableName($8);
94             free($3); free($5); free($8);
95         }
96         | ALTER INDEX ident RENAME TO ident semicolon_opt
97         {
98             parsedData->setStmtType(AlterStatement);
99             parsedData->setAlterType(ALTERINDEXRENAME);
100             parsedData->setTableName($3);
101             parsedData->setIndexName($6); 
102             free($3); free($5);
103         }
104         ;
105 management_statement: FLUSH CACHE semicolon_opt
106         {
107            parsedData->setStmtType(MgmtStatement);
108         }
109         ;
110 user_manager_statement: CREATE USER ident PASSWORD STRING semicolon_opt
111         {
112             parsedData->setStmtType(UserStatement);
113             parsedData->createUserNode((char*)$3,(char*)$5);
114             free($3);
115             free($5);
116         }
117         |DROP USER ident semicolon_opt
118         {
119             parsedData->setStmtType(UserStatement);
120             parsedData->dropUserNode((char*)$3);
121             free($3);
122         }
123         | ALTER USER ident SET PASSWORD STRING semicolon_opt
124         {
125             parsedData->setStmtType(UserStatement);
126             parsedData->alterUserNode((char*)$3,(char*)$6);
127             free($3);
128             free($6);
129         }
130         ;
131 copy_table_statement: CREATE TABLE ident AS SELECT opt_distinct field_list FROM table_list where_clause_opt group_by_opt having_opt order_by_opt limit_opt semicolon_opt
132         {
133             parsedData->setStmtType(CopyTableStatement);
134             parsedData->setPKTableName($3);
135             parsedData->setCreateTbl();
136             free($3);
137         }
138         | INSERT  INTO ident AS SELECT opt_distinct field_list FROM table_list where_clause_opt group_by_opt having_opt order_by_opt limit_opt semicolon_opt
139         {
140             parsedData->setStmtType(CopyTableStatement);
141             parsedData->setPKTableName($3);
142             free($3);
143         }
144         ;
145 internal_statement: COMPACT TABLE ident
146         {
147             parsedData->setStmtType(CompactTableStatement);
148             parsedData->setTableName($3);
149             free($3);
150         }
151         ;
152 other: ALLTABLE
153         {
154             parsedData->setStmtType(MetaStatement);
155             parsedData->setResultSetPlan(GetTables);
156         }
157         | DESCRIBE table 
158         {
159             parsedData->setStmtType(MetaStatement);
160             parsedData->setResultSetPlan(GetColumns);
161         }
162         | DESCRIBE INDEX table
163         {
164             parsedData->setStmtType(MetaStatement);
165             parsedData->setResultSetPlan(GetIndexes);
166                    
167         }
168         | PRIMARYINFO table
169         {
170             parsedData->setStmtType(MetaStatement);
171             parsedData->setResultSetPlan(GetPriIndex);
172         }
173         | GETCATALOGS
174         {
175             parsedData->setStmtType(MetaStatement);
176             parsedData->setResultSetPlan(GetCatalogs);
177         }
178         | GETTABLETYPES
179         {
180             parsedData->setStmtType(MetaStatement);
181             parsedData->setResultSetPlan(GetTableType);
182         }
183         | GETDATATYPES 
184         {
185             parsedData->setStmtType(MetaStatement);
186             parsedData->setResultSetPlan(GetDataType);
187         }
188         | IMPORTEDKEY table
189         {
190             parsedData->setStmtType(MetaStatement);
191             parsedData->setResultSetPlan(GetImportKey);
192         }
193         | EXPORTEDKEY table
194         {
195             parsedData->setStmtType(MetaStatement);
196             parsedData->setResultSetPlan(GetExportKey);
197         }
198         ;
199 select_statement: opt_explain SELECT opt_distinct field_list FROM table_list where_clause_opt group_by_opt having_opt order_by_opt limit_opt semicolon_opt
200         {
201             parsedData->setStmtType(SelectStatement);
202             parsedData->setCacheWorthy(true);
203         }
204         ;
205 opt_explain: EXPLAIN PLAN
206         {
207            parsedData->setExplain();
208         }
209         |
210         ;
211 opt_distinct: DISTINCT 
212         { 
213             parsedData->setDistinct();
214         }
215         |
216         ;
217 field_list: field_list field_list_L
218         | field_with_as
219         ;
220 field_list_L: ',' field_with_as 
221         ;
222 field_with_as: field
223         | field AS ident
224         {
225             parsedData->insertFieldAlias((char*)$3);
226             free((char*)$3);
227         }
228         ;
229 table_list: table_list table_list_L
230         | table 
231         | table join_exp
232         ;
233 join_exp: INNER opt_join table ON conditions join_exp
234         {
235            parsedData->insertJoinType(INNER_JOIN);
236            Condition *cond = parsedData->getCondition();
237            Predicate *pred = cond->getPredicate();
238            if (pred == NULL) {
239                parsedData->setCondition((Predicate*)$5);
240            } else {
241                Predicate *newPred;
242                newPred = parsedData->insertPredicate(pred, OpAnd, (Predicate*)$5);
243                parsedData->setCondition(newPred);
244            }
246         }
247         | LEFT opt_outer opt_join table ON conditions join_exp
248         {
249            parsedData->insertJoinType(LEFT_JOIN);
250            Condition *cond = parsedData->getCondition();
251            Predicate *pred = cond->getPredicate();
252            if (pred == NULL) {
253                parsedData->setCondition((Predicate*)$6);
254            } else {
255                Predicate *newPred;
256                newPred = parsedData->insertPredicate(pred, OpAnd, (Predicate*)$6);
257                parsedData->setCondition(newPred);
258            }
259         }
260         | CROSS opt_join table join_exp
261         {
262             parsedData->insertJoinType(INNER_JOIN);
263         }
264         |
265         ;
266 opt_outer: 
267        |OUTER
268        ;
269 opt_join: 
270        |JOIN
271        ;
272 table_list_L: ',' table
273         {
274             parsedData->insertJoinType(INNER_JOIN);
275         }
276         ;
277         
278 insert_statement: INSERT INTO ident field_list_opt VALUES '(' value_list ')' semicolon_opt
279         {
280             parsedData->setStmtType(InsertStatement);
281             parsedData->setTableName($3); 
282             free($3);
283         }
284         ;
286 field_list_opt:
287         | '(' field_list ')'
288         ;
290 value_list: value_list value_list_L
291         | value
292         {
293             parsedData->insertValue((char*)$1);
294             free($1);
295         }
296         ;
297 value_list_L: ',' value 
298         {
299             parsedData->insertValue((char*)$2);
300             free($2);
301         }
302         ;
303         
304 invalue_list: invalue_list invalue_list_L
305         | value
306         {
307             parsedData->insertInValue((char*)$1);
308             free($1);
309         }
310         ;
311 invalue_list_L: ',' value 
312         {
313             parsedData->insertInValue((char*)$2);
314             free($2);
315         }
316         ;
317         
318 delete_statement: DELETE FROM ident where_clause_opt semicolon_opt
319         {
320             parsedData->setStmtType(DeleteStatement);
321             parsedData->setTableName($3); 
322             free($3);
323         }
324         ;
325         
326 update_statement: UPDATE ident SET assign_list where_clause_opt semicolon_opt
327         {
328             parsedData->setStmtType(UpdateStatement);
329             parsedData->setTableName($2); 
330             free( $2 );
331         }
332         ;
334 semicolon_opt: ';'
335         |
336         ;
338 assign_list: assign_list assign_list_L
339         | assign_stmt
340         ;
342 assign_list_L: ',' assign_stmt
343         ;
344 assign_stmt: ident  OPERATOR stmt_exp
345         {
346            parsedData->insertUpdateExpression( (char*) $1, (Expression* ) $3);
347            free( $1 ); free($2);
348         }
349         | ident OPERATOR value 
350         { 
351             parsedData->insertUpdateValue( (char*) $1, (char*) $3);
352             free( $1 ); free($2);free( $3 ); 
353         }
354         | ident OPERATOR NULL_VALUE 
355         {
356             parsedData->insertUpdateValue( (char*) $1, (char*) $3);
357             free( $1 ); free($2);free( $3 );
358         }
359         ; 
360 stmt_exp: stmt_exp '/' stmt_exp
361         {
362             Expression* exp;
363             exp=parsedData->insertExpression((Expression *)$1, division, (Expression *)$3);
364             $$=exp;
365         } 
366         | stmt_exp '%' stmt_exp
367         {
368             Expression* exp;
369             exp=parsedData->insertExpression((Expression *)$1, modulus, (Expression *)$3);
370             $$=exp;
371         }
372         | stmt_exp '*' stmt_exp
373         {
374             Expression* exp;
375             exp=parsedData->insertExpression((Expression *)$1, multiplication, (Expression *)$3);
376             $$=exp;
377         }
378         | stmt_exp '+' stmt_exp
379         {
380             Expression* exp;
381             exp=parsedData->insertExpression((Expression *)$1, addition, (Expression *)$3);
382             $$=exp;
383         }
384         | stmt_exp '-' stmt_exp
385         {
386             Expression* exp;
387             exp=parsedData->insertExpression((Expression *)$1, subtraction, (Expression *)$3);
388             $$=exp;
389         }
390         | '(' stmt_exp ')'
391         {
392             $$=$2;
393         }
394         | '-' stmt_exp %prec UMINUS
395         {
396             $$ = $2;
397         }
398         | '+' stmt_exp %prec UMINUS
399         {
400             $$ = $2;
401         }
402         | function_opt
403         | atom
404         ;
405 function_opt: DATE_DIFF '(' atom ',' atom ')'
406         {
407               Expression* exp;
408               parsedData->setFunctionType(DATEDIFF);
409               exp=parsedData->insertExpression((Expression *)$3, DATEDIFF, (Expression *)$5);
410             $$=exp;
411         }
412             | DATE_ADD '(' atom  INTERVAL atom date_opt ')'
413             {
414                  Expression* exp;
415              parsedData->setFunctionType((*(FunctionType *)$6));
416              exp=parsedData->insertExpression((Expression *)$3, (*(FunctionType *)$6), (Expression *)$5);
417              $$=exp;
418             }
419         | DATE_SUB '(' atom  INTERVAL atom date_opt ')'
420         {
421              Expression* exp;
422              //parsedData->setFunctionType((*(FunctionType *)$6));
423              parsedData->setFunctionType((FunctionType)((int)(*(FunctionType *)$6)+3));
424              exp=parsedData->insertExpression((Expression *)$3, (FunctionType)((int)(*(FunctionType *)$6)+3), (Expression *)$5);
425              $$=exp;
426         }
427         | TIME_DIFF '(' atom ',' atom ')'
428         {
429               Expression* exp;
430               parsedData->setFunctionType(TIMEDIFF);
431               exp=parsedData->insertExpression((Expression *)$3, TIMEDIFF, (Expression *)$5);
432             $$=exp;
433         }
434         | TIME_ADD '(' atom  INTERVAL atom time_opt ')'
435         {
436              Expression* exp;
437              parsedData->setFunctionType((*(FunctionType *)$6));
438              exp=parsedData->insertExpression((Expression *)$3, (*(FunctionType *)$6), (Expression *)$5);
439              $$=exp;
440         }
441         | TIME_SUB '(' atom  INTERVAL atom time_opt ')'
442         {
443              Expression* exp;
444              parsedData->setFunctionType((FunctionType)((int)(*(FunctionType *)$6)+3));
445              exp=parsedData->insertExpression((Expression *)$3, (FunctionType)((int)(*(FunctionType *)$6)+3), (Expression *)$5);
446              $$=exp;
447         }
448             | TIMESTAMP_DIFF '(' datetime_opt ','  atom ',' atom ')'
449         {
450               Expression* exp;
451               int diff=0;
452               FunctionType val = (*(FunctionType *)$3);
453               if( val == DATEADDWITHYEAR || val == DATEADDWITHMON || val == DATEADDWITHDAY ) diff = 24;
454               else diff = 21;
455               parsedData->setFunctionType((FunctionType)((int)(*(FunctionType *)$3+diff)));
456               exp=parsedData->insertExpression((Expression *)$5, (FunctionType)((int)(*(FunctionType *)$3)+diff), (Expression *)$7);
457             $$=exp;
458         }
459         | TIMESTAMP_ADD '(' atom  INTERVAL atom datetime_opt ')'
460         {
461              Expression* exp;
462              parsedData->setFunctionType((FunctionType)((int)(*(FunctionType *)$6)+12));
463              exp=parsedData->insertExpression((Expression *)$3, (FunctionType)((int)(*(FunctionType *)$6)+12), (Expression *)$5);
464              $$=exp;
465         }
466         | TIMESTAMP_SUB '(' atom  INTERVAL atom datetime_opt ')'
467         {
468              Expression* exp;
469              parsedData->setFunctionType((FunctionType)((int)(*(FunctionType *)$6)+15));
470              exp=parsedData->insertExpression((Expression *)$3, (FunctionType)((int)(*(FunctionType *)$6)+15), (Expression *)$5);
471              $$=exp;
472         }
473         | EXTRACT '(' datetime_opt FROM atom ')'
474             {
475             FunctionType val = UNKNOWN_FUNCTION;
476             //if((*(FunctionType *)$3) >=8)
477               // val = (FunctionType)((int)(*(FunctionType *)$3)+36);
478             //else
479                val = (FunctionType)((int)(*(FunctionType *)$3)+30);
480             Expression* exp;
481             parsedData->setFunctionType(val);
482             exp=parsedData->insertExpression((Expression *)$5, val,NULL);
483             $$=exp;
484             }
485                 | DATE_TYPE '(' atom  ')'
486         {
487             Expression* exp;
488             parsedData->setFunctionType(DATEFROMTIMESTAMP);
489             exp=parsedData->insertExpression((Expression *)$3, DATEFROMTIMESTAMP, NULL);
490             $$=exp;
492         }
493         | TIME_TYPE '(' atom  ')'
494         {
495             Expression* exp;
496             parsedData->setFunctionType(TIMEFROMTIMESTAMP);
497             exp=parsedData->insertExpression((Expression *)$3, TIMEFROMTIMESTAMP, NULL);
498             $$=exp;
499         }
500         ;
501 datetime_opt: time_opt
502         {
503            FunctionType val = *(FunctionType *)$1;
504            $$ = &val;
505         }
506             | date_opt
507         {
508            FunctionType val = *(FunctionType *)$1;
509            $$ = &val;
510         }
511             ;
512 time_opt: HOUR 
513             { 
514              FunctionType val = TIMEADDWITHHOUR;
515              $$ = &val;
516         }
517             | MINUTE  
518         {
519              FunctionType val = TIMEADDWITHMIN;
520              $$ = &val;
521         }
522             | SECOND  
523         {
524              FunctionType val = TIMEADDWITHSEC;
525              $$ = &val;
526         }
527             ;
528 date_opt: YEAR    
529             {
530                 FunctionType val = DATEADDWITHYEAR;
531             $$ = &val;
532             }
533             | MONTH   
534         {
535                 FunctionType val = DATEADDWITHMON;
536             $$ = &val;
537         }
538             | DAY  
539         {
540             FunctionType val = DATEADDWITHDAY;
541             $$ = &val;
542         }
543             ;
544 atom    :  ident
545         {
546             Expression* exp;
547             exp=parsedData->insertExpression((char *)$1);
548             free($1);
549             $$=exp;
550         }
551         | value
552         {
553             Expression* exp;
554             bool flag = false;
555             exp=parsedData->insertExpression((char *)$1, flag);
556             free($1);
557             $$=exp;
558         }
559         | NULL_VALUE
560         {
561             Expression* exp;
562             exp=parsedData->insertExpression("NULL");
563             free($1);
564             $$=exp;
565         }
566         ;
568 where_clause_opt:  WHERE conditions
569         {
570            Condition *cond = parsedData->getCondition();
571            Predicate *pred = cond->getPredicate();
572            if (pred == NULL) {
573                parsedData->setCondition((Predicate*)$2);
574            } else {
575                 Predicate *newPred;
576                 newPred = parsedData->insertPredicate(pred, OpAnd, (Predicate*)$2);
577                 parsedData->setCondition(newPred);
578            }
580         }
581         |
582         ;
583 group_by_opt:  GROUP BY group_field_list
584         |
585         ;
586 order_by_opt:  ORDER BY order_field_list
587         |
588         ;
589 limit_opt:  LIMIT NUMBER_STRING
590         {
591             parsedData->setLimit(atoi($2), 0);
592         }
593         | LIMIT NUMBER_STRING OFFSET NUMBER_STRING
594         {
595             parsedData->setLimit(atoi($2), atoi($4));
596         }
597         |
598         ;
599 having_opt:  HAVING hconditions
600         |
601         ;
602 group_field_list: group_field_list group_field_list_L
603         | group_field 
604         ;
605 group_field_list_L: ',' group_field
606         ;
607 group_field:   ident
608         {
609             parsedData->insertGroupField((char*)$1);
610             free( $1 );
611         }
612         ;
613 order_field_list: order_field_list order_field_list_L
614         | order_field
615         ;
616 order_field_list_L: ',' order_field
617         ;
618 order_field:   ident
619         {
620             parsedData->insertOrderByField((char*)$1);
621             free( $1 );
622         }
623         | ident ASC
624         {
625             parsedData->insertOrderByField((char*)$1);
626             free( $1 );
627         }
628         | ident DESC
629         {
630             parsedData->insertOrderByField((char*)$1, true);
631             free( $1 );
632         }
633         ;
634 conditions: conditions OR conditions
635         {
636             Predicate *pred;
637             pred = parsedData->insertPredicate((Predicate*) $1, OpOr, (Predicate*) $3);
638             //parsedData->setCondition((Predicate*)pred);
639             $$= pred;
641         }
642         | conditions AND conditions
643         {
644             Predicate *pred;
645             pred = parsedData->insertPredicate((Predicate*) $1, OpAnd, (Predicate*) $3);
646             //parsedData->setCondition((Predicate*)pred);
647             $$= pred;
648         }
649         | '(' conditions ')' { $$=$2; }
650         | NOT '(' conditions ')'
651         {
652             Predicate *pred;
653             pred = parsedData->insertPredicate((Predicate*) $3, OpNot, NULL);
654             //parsedData->setCondition((Predicate*)pred);
655             $$= pred;
657         }
658         | not_opt condition
659         {
660             if( $1 == (char*) 1 )
661             {
662                 Predicate *pred;
663                 pred = parsedData->insertPredicate((Predicate*) $2, OpNot, NULL);
664                 //parsedData->setCondition((Predicate*)pred);
665                 $$= pred;
666             }
667             else
668             {
669                 //parsedData->setCondition((Predicate*)$2);
670                 $$=$2;
671             }
672         }
673         ;
674 hconditions: hconditions OR hconditions
675         {
676             Predicate *pred;
677             pred = parsedData->insertPredicate((Predicate*) $1, OpOr, (Predicate*) $3);
678             parsedData->setHavingCondition((Predicate*)pred);
679             $$= pred;
681         }
682         | hconditions AND hconditions
683         {
684             Predicate *pred;
685             pred = parsedData->insertPredicate((Predicate*) $1, OpAnd, (Predicate*) $3);
686             parsedData->setHavingCondition((Predicate*)pred);
687             $$= pred;
688         }
689         | '(' hconditions ')' { $$=$2; }
690         | NOT '(' hconditions ')'
691         {
692             Predicate *pred;
693             pred = parsedData->insertPredicate((Predicate*) $3, OpNot, NULL);
694             parsedData->setHavingCondition((Predicate*)pred);
695             $$= pred;
697         }
698         | not_opt hcondition
699         {
700             if( $1 == (char*) 1 )
701             {
702                 Predicate *pred;
703                 pred = parsedData->insertPredicate((Predicate*) $2, OpNot, NULL);
704                 parsedData->setHavingCondition((Predicate*)pred);
705                 $$= pred;
706             }
707             else
708             {
709                 parsedData->setHavingCondition((Predicate*)$2);
710                 $$=$2;
711             }
712         }
713         ;
714 hcondition: MIN  '(' ident ')' OPERATOR value
715         {
716             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$5);
717             Predicate *pred;
718             void **ptr = parsedData->insertCondValueAndGetPtr((char*)$3, (char*)$6, false, AGG_MIN, true);
719             pred = parsedData->insertPredicate((char*) $3, op, ptr, AGG_MIN);
720             free( $1 ); free ($3); free ($5); free ($6);
721             $$=pred;
722         }
723         | MAX  '(' ident ')' OPERATOR value
724         {
725             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$5);
726             Predicate *pred;
727             void **ptr = parsedData->insertCondValueAndGetPtr((char*)$3, (char*)$6, false, AGG_MAX, true);
728             pred = parsedData->insertPredicate((char*) $3, op, ptr, AGG_MAX);
729             free( $1 ); free ($3); free ($5); free ($6);
730             $$=pred;
731         }
732         | SUM  '(' ident ')' OPERATOR value
733         {
734             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$5);
735             Predicate *pred;
736             void **ptr = parsedData->insertCondValueAndGetPtr((char*)$3, (char*)$6, false, AGG_SUM, true);
737             pred = parsedData->insertPredicate((char*) $3, op, ptr, AGG_SUM);
738             free( $1 ); free ($3); free ($5); free ($6);
739             $$=pred;
740         }
741         | AVG  '(' ident ')' OPERATOR value
742         {
743             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$5);
744             Predicate *pred;
745             void **ptr = parsedData->insertCondValueAndGetPtr((char*)$3, (char*)$6, false, AGG_AVG, true);
746             pred = parsedData->insertPredicate((char*) $3, op, ptr, AGG_AVG);
747             free( $1 ); free ($3); free ($5); free ($6);
748             $$=pred;
749         }
750         | COUNT  '(' ident ')' OPERATOR value
751         {
752             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$5);
753             Predicate *pred;
754             void **ptr = parsedData->insertCondValueAndGetPtr((char*)$3, (char*)$6, false, AGG_COUNT, true);
755             pred = parsedData->insertPredicate((char*) $3, op, ptr, AGG_COUNT);
756             free( $1 ); free ($3); free ($5); free ($6);
757             $$=pred;
758         }
759         ;
761 condition: ident OPERATOR value 
762         {
763             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
764                         bool opLike = false;
765             if (op == OpLike) opLike = true;
766             Predicate *pred;
767             void **ptr = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$3, opLike);
768             pred = parsedData->insertPredicate((char*) $1, op, ptr);
769             free( $1 ); free($2); free( $3 ); 
770             $$=pred;
771         }
772         | ident OPERATOR ident
773         {
774             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
775             Predicate *pred;
776             parsedData->insertCondValue((char*) $1);
777             parsedData->insertCondValue((char*) $3);
778             pred = parsedData->insertPredicate((char*) $1, op, (char*) $3);
779             free( $1 ); free($2); free( $3 );
780             $$=pred;
781         }
783         | ident not_opt BETWEEN value AND value
784         {
785             void **ptr1 = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$4);
786             void **ptr2 = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$6);
787             Predicate *finalPred;
788  //           pred1 = parsedData->insertPredicate((char*) $1, OpGreaterThanEquals, ptr1);
789 //            pred2 = parsedData->insertPredicate((char*) $1, OpLessThanEquals, ptr2);
790             finalPred = parsedData->insertBetPredicate((char*) $1, 
791                         OpGreaterThanEquals, ptr1, OpLessThanEquals, ptr2);
792                         //OpLessThanEquals, ptr2, OpGreaterThanEquals, ptr1);
794             if( $2 == (char*) 1 )
795                 finalPred = parsedData->insertPredicate(finalPred, OpNot, NULL);
796             free( $1 );  free( $4 );  free( $6 );
797             $$= finalPred;
798         }
799         | ident not_opt IN '(' invalue_list ')'
800         {
801             ListIterator valIter = parsedData->getInValueList().getIterator();
802             FieldValue *value1, *value2;
803             Predicate *pred1, *pred2, *finalPred;
804             void **ptr1, **ptr2;
805             if (valIter.hasElement()) {
806                value1 = (FieldValue*) valIter.nextElement();
807                ptr1 = parsedData->insertCondValueAndGetPtr((char*)$1, value1->parsedString);
808                pred1 = parsedData->insertPredicate((char*) $1, OpEquals, ptr1);
809                finalPred=pred1;
810             }
811             while (valIter.hasElement()) {
812                value2 = (FieldValue*) valIter.nextElement();
813                ptr2 = parsedData->insertCondValueAndGetPtr((char*)$1, value2->parsedString);
814                pred2 = parsedData->insertPredicate((char*) $1, OpEquals, ptr2);
815                finalPred = parsedData->insertPredicate(pred1, OpOr, pred2);
816                pred1= finalPred;     
817             }
818             parsedData->resetInValueList();
819             if( $2 == (char*)1)
820                 finalPred = parsedData->insertPredicate(finalPred, OpNot, NULL);
822             free( $1 );  
823             $$= finalPred;
824         }
825         | ident IS NOT NULL_VALUE
826         {
827             Predicate *pred;
828             parsedData->insertCondValue((char*) $1);
829             pred = parsedData->insertNullPredicate((char*) $1, OpIsNull, false);
830             free( $1 ); free($2); free( $3 );
831             $$=pred;  
832         }
833         | ident IS NULL_VALUE
834         {
835             Predicate *pred;
836             parsedData->insertCondValue((char*) $1);
837             pred = parsedData->insertNullPredicate((char*) $1, OpIsNull, true);
838             free( $1 ); free($2); free( $3 );
839             $$=pred;  
840         }
841         | function_opt OPERATOR function_opt
842         {
843             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
844             Predicate *pred;
845             pred = parsedData->insertPredicate(((Expression*)$1), op, ((Expression*)$3));
846             $$=pred;
848         }
849         | function_opt OPERATOR ident
850         {
852             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
853             parsedData->insertCondValue((char*) $3);
854             Predicate *pred;
855             pred = parsedData->insertPredicate(((Expression*)$1), op, (char*) $3);
856             $$=pred;
857             
858         }
859         | function_opt OPERATOR value 
860         {
861             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
862             void **ptr = parsedData->insertCondValueAndGetPtr((char*)"dummy", (char*)$3, false, AGG_UNKNOWN, false, true);
863             Predicate *pred;
864             pred = parsedData->insertPredicate(((Expression*)$1), op, ptr);
865             $$=pred;
866         }
867         ;
868 not_opt: NOT
869         { $$=(char*) 1;
870         }
871         | 
872         { $$=(char*) 0; }
873         ;
874 table:   ident
875         {
876             parsedData->insertTableName((char*)$1);
877             free( $1 );
878         }
879         | ident AS ident
880         {
881             parsedData->insertTableName((char*)$1, (char*)$3);
882             free( $1 ); free($3);
883         }
884         | ident ident
885         {
886             parsedData->insertTableName((char*)$1, (char*)$2);
887             free( $1 ); free($2);
888         }
889         ;
890 field:   ident
891         {
892             parsedData->insertField((char*)$1);
893             free( $1 );
894             
895         }
896         | MIN  '(' ident ')'
897         { 
898             parsedData->insertField((char*)$3, AGG_MIN);
899             free( $1 );
900         }
901         | MAX  '(' ident ')'
902         { 
903             parsedData->insertField((char*)$3, AGG_MAX);
904             free( $1 );
905         }
906         | SUM  '(' ident ')'
907         { 
908             parsedData->insertField((char*)$3, AGG_SUM);
909             free( $1 );
910         }
911         | AVG  '(' ident ')'
912         { 
913             parsedData->insertField((char*)$3, AGG_AVG);
914             free( $1 );
915         }
916         | COUNT  '(' ident ')'
917         { 
918             parsedData->insertField((char*)$3, AGG_COUNT);
919             free( $1 );
920         }
921         | COUNT  '(' '*' ')'
922         { 
923             parsedData->insertField("*", AGG_COUNT);
924             free( $1 );
925         }
926         | '*'
927         { 
928             parsedData->insertField("*");
929         }
930         |ident'*'
931         {
932             parsedData->insertField("*");
933         }
934         ;
935 ident:    FIELD { $$ = $1; }
936         | '`'FIELD'`' { $$ = $2; }
937         ;
938 value:    STRING { $$ = $1; }
939         | num_value
940         | BINARY_STRING { $$ = $1; }
941         | doub_value
942         | PARAMETER { $$ = $1; }
943         | NULL_VALUE { $$ = (char*) 0; }
944         | NOW '(' ')'
945         {
946               char *str=(char*)malloc(20);
947               time_t rawtime;
948               struct tm * timeinfo;
949               time ( &rawtime );
950               timeinfo = localtime ( &rawtime );
951               sprintf(str,"%d-%d-%d %d:%d:%d",timeinfo->tm_year+1900,timeinfo->tm_mon+1,timeinfo->tm_mday,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
952               $$=str;
955         }
956         ;
957 num_value: NUMBER_STRING { $$ =  $1; }
958         | '-' NUMBER_STRING %prec UMINUS
959         {
960              char *n;
961              n=(char*)malloc(30);
962              strcpy(n,"-");
963              strcat(n,(char*)$2);
964              $$=n;
965              free($2);
966         }
967         | '+' NUMBER_STRING %prec UMINUS{ $$ =  $2; }
968         ;
969 doub_value : DOUBLE { $$ = $1; }
970         | '-' DOUBLE %prec UMINUS
971         {
972              char *d;
973              d=(char*)malloc(30);
974              strcpy(d,"-");
975              strcat(d,(char*)$2);
976              $$=d;
977              free($2);
978         }
979         | '+' DOUBLE %prec UMINUS{ $$ = $2; }
980         ;
981 cache_statement: CACHE TABLE ident cache_opt semicolon_opt
982         {
983             if (!Conf::config.useCache())
984             {
985               printf("CACHE_TABLE is set to FALSE in csql.conf file.\n");
986               free($3);
987               YYABORT;
988             }
989             parsedData->setStmtType(CacheTableStatement);
990             parsedData->setTableName($3); 
991         }
992         | UNCACHE TABLE ident semicolon_opt
993         {
994             parsedData->setStmtType(CacheTableStatement);
995             parsedData->setUnCache(true);
996             parsedData->setTableName($3); 
997         }
998         ; 
999 cache_opt: hcond_cache vcond_cache pk_cache direct_opt dsn_opt no_schema
1000          ;
1001 hcond_cache: 
1002          | CONDITION value 
1003          {
1004             parsedData->setHCondFld(true);
1005             parsedData->setHCondition((char*)$2);
1006          }
1007          ;
1008 vcond_cache:
1009          | FIELDLIST value
1010          {
1011             parsedData->setVCondFld(true);
1012             parsedData->setVCondition((char*)$2);
1013             free($2);
1014          }
1015          ;
1016 pk_cache:
1017          | PK ident
1018          {
1019             parsedData->setPkFld(true);
1020             parsedData->setIndexName((char*)$2);
1021             free($2);
1022          }
1023          ;
1024 direct_opt:
1025          | DIRECT
1026          {
1027             parsedData->setDirect(true);
1028          }
1029          ;
1030 dsn_opt:
1031          | DSN value
1032          {
1033              parsedData->setDSN(true);
1034              parsedData->setPKTableName((char*)$2);
1035              free($2);
1036          }
1037 no_schema:
1038          | NOSCHEMA
1039          {
1040              parsedData->setNoSchema(true);
1041          }
1042          ;
1043 ddl_statement: CREATE TABLE ident '(' create_defn_list_con ')' semicolon_opt
1044         {
1045             parsedData->setStmtType(CreateTableStatement);
1046             parsedData->setTableName($3); 
1047             free($3);
1048         }
1049         | CREATE INDEX ident ON ident '(' field_list ')' opt_constr_type opt_ind_type opt_bucket semicolon_opt
1050         {
1051             parsedData->setStmtType(CreateIndexStatement);
1052             parsedData->setIndexName($3); 
1053             parsedData->setTableName($5); 
1054             free($3);
1055             free($5);
1056         }
1057         | DROP TABLE ident
1058         {
1059             parsedData->setStmtType(DropTableStatement);
1060             parsedData->setTableName($3); 
1061             free($3);
1062         }
1063         | DROP INDEX ident
1064         {
1065             parsedData->setStmtType(DropIndexStatement);
1066             parsedData->setIndexName($3); 
1067             free($3);
1068         }
1069         | TRUNCATE TABLE ident semicolon_opt
1070         {
1071             parsedData->setStmtType(TruncateStatement);
1072             parsedData->setTableName($3); 
1073             free($3);
1074         }
1075         ;
1076 opt_ind_type:
1077         | HASH  opt_constr_type
1078         {
1079             parsedData->setIndexType(hashIndex);
1080         }
1081         | TREE  opt_constr_type
1082         {
1083             parsedData->setIndexType(treeIndex);
1084         }
1085         |
1086         {
1087             parsedData->setIndexType(hashIndex);
1088         }
1089         ;
1090 opt_constr_type:
1091         | UNIQUE 
1092         {
1093             parsedData->setUnique(true);
1094         }
1095         | PRIMARY 
1096         {
1097             parsedData->setUnique(true);
1098             parsedData->setPrimary(true);
1099         }
1100         |
1101         {
1102             parsedData->setUnique(false);
1103             parsedData->setPrimary(false);
1104         }
1105         ;
1106 opt_bucket:
1107         | SIZE NUMBER_STRING
1108         {
1109             parsedData->setBucketSize(atoi($2));
1110             free($2);
1111         }
1112         ;
1113 create_defn_list_con:create_defn_list
1114         |create_defn_list ',' constraint_defn
1115         ;
1116 create_defn_list: create_defn_list create_defn_list_L
1117         | create_defn
1118         ;
1120 create_defn_list_L: ',' create_defn
1121         ;
1123 create_defn: field_defn
1124         {
1125             parsedData->insertFldDef();
1126         }
1127         ;
1129 field_defn: field_name field_type size_opt null_expr_opt default_expr_opt auto_increment_key 
1130         ;
1132 field_name: ident
1133         {
1134             parsedData->setFldName($1);
1135             free($1);
1136         }
1137 size_opt:
1138         | '(' NUMBER_STRING ')'
1139         {
1140             DbRetVal rv = parsedData->setFldLength(atoi($2));
1141             if (rv != OK) {
1142                 yyerror("Binary field length < 256");
1143                 free($2);
1144                 YYABORT;
1145             }
1146             free($2);
1147         }
1148         ;
1150 default_expr_opt:
1151         | DEFAULT value
1152         {
1153             DbRetVal rv = parsedData->setDefaultValue($2);
1154             if(rv != OK){
1155                 yyerror("Invalid Default value.");
1156                 free($2);
1157                 YYABORT;
1158             }
1159             free($2);
1160         }
1161         ;
1163 null_expr_opt:
1164         | NOT NULL_VALUE
1165         {
1166             parsedData->setFldNotNull(true);
1167         }
1168         ;
1169 constraint_defn : primary_key_constraint
1170         | foreign_key_constraint
1171         | primary_key_constraint ',' foreign_key_constraint
1172         ;
1173 foreign_key_constraint: foreign_key_constraint foreign_key_constraint_L
1174         | foreign_key_create
1175         ;
1176 foreign_key_constraint_L: ',' foreign_key_create
1177         ;
1178 foreign_key_create: FOREIGN KEY '(' fkField_list ')' REFERENCES ident'(' pkField_list ')'
1179         {
1180             parsedData->setForeign(true);
1181             parsedData->setPKTableName((char*)$7);
1182             parsedData->insertForeignKeyList();
1183         }
1184         ;
1185 fkField_list: fkField_list fkField_list_L
1186         | fkField
1187         ;
1188 fkField_list_L: ',' fkField
1189         ;
1190 fkField: ident
1191         {
1192            parsedData->insertFKField((char*)$1);
1193            free($1);
1194         }
1195         ;
1196 pkField_list: pkField_list pkField_list_L
1197         | pkField
1198         ;
1199 pkField_list_L: ',' pkField
1200         ;
1201 pkField: ident
1202         {
1203            parsedData->insertPKField((char*)$1);
1204            free($1);
1205         }
1206         ;
1208 primary_key_constraint: PRIMARY KEY '(' field_list ')' opt_bucket
1209         {
1210            parsedData->setPrimary(true);
1211         }
1212         ;
1213 auto_increment_key:
1214         | AUTO_INCREMENT
1215         {
1216            DataType type = parsedData->getFldType();
1217            if(type > 4)
1218            {
1219                yyerror("AUTO_INCREMENT KEY can't be created other than INTEGER field ");
1220                free($1);
1221                YYABORT;
1222            }
1223            DbRetVal ret = parsedData->setAutoIncreament(true);
1224            if(ret != OK){
1225                yyerror("A table should have ony one AUTO_INCREMENT KEY ");
1226                free($1);
1227                YYABORT;
1228            }
1229            parsedData->setFldNotNull(true);
1230            parsedData->setAutoFldName(parsedData->getFldName());
1231            parsedData->setPrimary(true);
1232         }
1233         ;
1235 field_type: INT_TYPE
1236         {
1237             parsedData->setFldType(typeInt);
1238         }
1239         | LONG_TYPE
1240         {
1241             parsedData->setFldType(typeLong);
1242         }
1243         | SHORT_TYPE
1244         {
1245             parsedData->setFldType(typeShort);
1246         }
1247         | BIGINT_TYPE
1248         {
1249             parsedData->setFldType(typeLongLong);
1250         }
1251         | TINYINT_TYPE
1252         {
1253             parsedData->setFldType(typeByteInt);
1254         }
1255         | FLOAT_TYPE
1256         {
1257             parsedData->setFldType(typeFloat);
1258         }
1259         | DOUBLE_TYPE
1260         {
1261             parsedData->setFldType(typeDouble);
1262         }
1263         ;
1264         | DATE_TYPE
1265         {
1266             parsedData->setFldType(typeDate);
1267         }
1268         ;
1269         | TIME_TYPE
1270         {
1271             parsedData->setFldType(typeTime);
1272         }
1273         ;
1274         | TIMESTAMP_TYPE
1275         {
1276             parsedData->setFldType(typeTimeStamp);
1277         }
1278         ;
1279         | CHAR_TYPE
1280         {
1281             parsedData->setFldType(typeString);
1282             parsedData->setFldLength(2);
1283         }
1284         ;
1285         | VARCHAR_TYPE
1286         {
1287             parsedData->setFldType(typeVarchar);
1288             parsedData->setFldLength(2);
1289         }
1290         ;
1291         | BINARY_TYPE
1292         {
1293             parsedData->setFldType(typeBinary);
1294             parsedData->setFldLength(1);
1295         }
1296         ;
1299 extern int lexEof;
1300 void yyerror(const char* Msg) { 
1301     if( lexEof == 0 )
1302         fprintf(stderr, "[Parser: %s] %s\n", Msg, yytext);
1304     return;