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