added curses library dependency for readline library
[csql.git] / src / sql / dmlyacc.yxx
blob29504eac41c08c5f3ed8b68da32917abc10dc53b
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) opLike = true;
748             Predicate *pred;
749             void **ptr = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$3, opLike);
750             pred = parsedData->insertPredicate((char*) $1, op, ptr);
751             free( $1 ); free($2); free( $3 ); 
752             $$=pred;
753         }
754         | ident OPERATOR ident
755         {
756             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
757             Predicate *pred;
758             parsedData->insertCondValue((char*) $1);
759             parsedData->insertCondValue((char*) $3);
760             pred = parsedData->insertPredicate((char*) $1, op, (char*) $3);
761             free( $1 ); free($2); free( $3 );
762             $$=pred;
763         }
765         | ident not_opt BETWEEN value AND value
766         {
767             void **ptr1 = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$4);
768             void **ptr2 = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$6);
769             Predicate *finalPred;
770  //           pred1 = parsedData->insertPredicate((char*) $1, OpGreaterThanEquals, ptr1);
771 //            pred2 = parsedData->insertPredicate((char*) $1, OpLessThanEquals, ptr2);
772             finalPred = parsedData->insertBetPredicate((char*) $1, 
773                         OpGreaterThanEquals, ptr1, OpLessThanEquals, ptr2);
774                         //OpLessThanEquals, ptr2, OpGreaterThanEquals, ptr1);
776             if( $2 == (char*) 1 )
777                 finalPred = parsedData->insertPredicate(finalPred, OpNot, NULL);
778             free( $1 );  free( $4 );  free( $6 );
779             $$= finalPred;
780         }
781         | ident not_opt IN '(' invalue_list ')'
782         {
783             ListIterator valIter = parsedData->getInValueList().getIterator();
784             FieldValue *value1, *value2;
785             Predicate *pred1, *pred2, *finalPred;
786             void **ptr1, **ptr2;
787             if (valIter.hasElement()) {
788                value1 = (FieldValue*) valIter.nextElement();
789                ptr1 = parsedData->insertCondValueAndGetPtr((char*)$1, value1->parsedString);
790                pred1 = parsedData->insertPredicate((char*) $1, OpEquals, ptr1);
791                finalPred=pred1;
792             }
793             while (valIter.hasElement()) {
794                value2 = (FieldValue*) valIter.nextElement();
795                ptr2 = parsedData->insertCondValueAndGetPtr((char*)$1, value2->parsedString);
796                pred2 = parsedData->insertPredicate((char*) $1, OpEquals, ptr2);
797                finalPred = parsedData->insertPredicate(pred1, OpOr, pred2);
798                pred1= finalPred;     
799             }
800             if( $2 == (char*)1)
801                 finalPred = parsedData->insertPredicate(finalPred, OpNot, NULL);
803             free( $1 );  
804             $$= finalPred;
805         }
806         | ident IS NOT NULL_VALUE
807         {
808             Predicate *pred;
809             parsedData->insertCondValue((char*) $1);
810             pred = parsedData->insertNullPredicate((char*) $1, OpIsNull, false);
811             free( $1 ); free($2); free( $3 );
812             $$=pred;  
813         }
814         | ident IS NULL_VALUE
815         {
816             Predicate *pred;
817             parsedData->insertCondValue((char*) $1);
818             pred = parsedData->insertNullPredicate((char*) $1, OpIsNull, true);
819             free( $1 ); free($2); free( $3 );
820             $$=pred;  
821         }
822         | function_opt OPERATOR function_opt
823         {
824             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
825             Predicate *pred;
826             pred = parsedData->insertPredicate(((Expression*)$1), op, ((Expression*)$3));
827             $$=pred;
829         }
830         | function_opt OPERATOR ident
831         {
833             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
834             parsedData->insertCondValue((char*) $3);
835             Predicate *pred;
836             pred = parsedData->insertPredicate(((Expression*)$1), op, (char*) $3);
837             $$=pred;
838             
839         }
840         | function_opt OPERATOR value 
841         {
842             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
843             void **ptr = parsedData->insertCondValueAndGetPtr((char*)"dummy", (char*)$3, false, AGG_UNKNOWN, false, true);
844             Predicate *pred;
845             pred = parsedData->insertPredicate(((Expression*)$1), op, ptr);
846             $$=pred;
847         }
848         ;
849 not_opt: NOT
850         { $$=(char*) 1;
851         }
852         | 
853         { $$=(char*) 0; }
854         ;
855 table:   ident
856         {
857             parsedData->insertTableName((char*)$1);
858             free( $1 );
859         }
860         | ident AS ident
861         {
862             parsedData->insertTableName((char*)$1, (char*)$3);
863             free( $1 ); free($3);
864         }
865         | ident ident
866         {
867             parsedData->insertTableName((char*)$1, (char*)$2);
868             free( $1 ); free($2);
869         }
870         ;
871 field:   ident
872         {
873             parsedData->insertField((char*)$1);
874             free( $1 );
875             
876         }
877         | MIN  '(' ident ')'
878         { 
879             parsedData->insertField((char*)$3, AGG_MIN);
880             free( $1 );
881         }
882         | MAX  '(' ident ')'
883         { 
884             parsedData->insertField((char*)$3, AGG_MAX);
885             free( $1 );
886         }
887         | SUM  '(' ident ')'
888         { 
889             parsedData->insertField((char*)$3, AGG_SUM);
890             free( $1 );
891         }
892         | AVG  '(' ident ')'
893         { 
894             parsedData->insertField((char*)$3, AGG_AVG);
895             free( $1 );
896         }
897         | COUNT  '(' ident ')'
898         { 
899             parsedData->insertField((char*)$3, AGG_COUNT);
900             free( $1 );
901         }
902         | COUNT  '(' '*' ')'
903         { 
904             parsedData->insertField("*", AGG_COUNT);
905             free( $1 );
906         }
907         | '*'
908         { 
909             parsedData->insertField("*");
910         }
911         |ident'*'
912         {
913             parsedData->insertField("*");
914         }
915         ;
916 ident:    FIELD { $$ = $1; }
917         | '`'FIELD'`' { $$ = $2; }
918         ;
919 value:    STRING { $$ = $1; }
920         | num_value
921         | BINARY_STRING { $$ = $1; }
922         | doub_value
923         | PARAMETER { $$ = $1; }
924         | NULL_VALUE { $$ = (char*) 0; }
925         | NOW '(' ')'
926         {
927               char *str=(char*)malloc(20);
928               time_t rawtime;
929               struct tm * timeinfo;
930               time ( &rawtime );
931               timeinfo = localtime ( &rawtime );
932               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);
933               $$=str;
936         }
937         ;
938 num_value: NUMBER_STRING { $$ =  $1; }
939         | '-' NUMBER_STRING %prec UMINUS
940         {
941              char *n;
942              n=(char*)malloc(30);
943              strcpy(n,"-");
944              strcat(n,(char*)$2);
945              $$=n;
946              free($2);
947         }
948         | '+' NUMBER_STRING %prec UMINUS{ $$ =  $2; }
949         ;
950 doub_value : DOUBLE { $$ = $1; }
951         | '-' DOUBLE %prec UMINUS
952         {
953              char *d;
954              d=(char*)malloc(30);
955              strcpy(d,"-");
956              strcat(d,(char*)$2);
957              $$=d;
958              free($2);
959         }
960         | '+' DOUBLE %prec UMINUS{ $$ = $2; }
961         ;
962 cache_statement: CACHE TABLE ident cache_opt semicolon_opt
963         {
964             if (!Conf::config.useCache())
965             {
966               printf("CACHE_TABLE is set to FALSE in csql.conf file.\n");
967               free($3);
968               YYABORT;
969             }
970             parsedData->setStmtType(CacheTableStatement);
971             parsedData->setTableName($3); 
972         }
973         | UNCACHE TABLE ident semicolon_opt
974         {
975             parsedData->setStmtType(CacheTableStatement);
976             parsedData->setUnCache(true);
977             parsedData->setTableName($3); 
978         }
979         ; 
980 cache_opt: hcond_cache vcond_cache pk_cache direct_opt dsn_opt no_schema
981          ;
982 hcond_cache: 
983          | CONDITION value 
984          {
985             parsedData->setHCondFld(true);
986             parsedData->setHCondition((char*)$2);
987          }
988          ;
989 vcond_cache:
990          | FIELDLIST value
991          {
992             parsedData->setVCondFld(true);
993             parsedData->setVCondition((char*)$2);
994             free($2);
995          }
996          ;
997 pk_cache:
998          | PK ident
999          {
1000             parsedData->setPkFld(true);
1001             parsedData->setIndexName((char*)$2);
1002             free($2);
1003          }
1004          ;
1005 direct_opt:
1006          | DIRECT
1007          {
1008             parsedData->setDirect(true);
1009          }
1010          ;
1011 dsn_opt:
1012          | DSN value
1013          {
1014              parsedData->setDSN(true);
1015              parsedData->setPKTableName((char*)$2);
1016              free($2);
1017          }
1018 no_schema:
1019          | NOSCHEMA
1020          {
1021              parsedData->setNoSchema(true);
1022          }
1023          ;
1024 ddl_statement: CREATE TABLE ident '(' create_defn_list_con ')' semicolon_opt
1025         {
1026             parsedData->setStmtType(CreateTableStatement);
1027             parsedData->setTableName($3); 
1028             free($3);
1029         }
1030         | CREATE INDEX ident ON ident '(' field_list ')' opt_constr_type opt_ind_type opt_bucket semicolon_opt
1031         {
1032             parsedData->setStmtType(CreateIndexStatement);
1033             parsedData->setIndexName($3); 
1034             parsedData->setTableName($5); 
1035             free($3);
1036             free($5);
1037         }
1038         | DROP TABLE ident
1039         {
1040             parsedData->setStmtType(DropTableStatement);
1041             parsedData->setTableName($3); 
1042             free($3);
1043         }
1044         | DROP INDEX ident
1045         {
1046             parsedData->setStmtType(DropIndexStatement);
1047             parsedData->setIndexName($3); 
1048             free($3);
1049         }
1050         | TRUNCATE TABLE ident semicolon_opt
1051         {
1052             parsedData->setStmtType(TruncateStatement);
1053             parsedData->setTableName($3); 
1054             free($3);
1055         }
1056         ;
1057 opt_ind_type:
1058         | HASH  opt_constr_type
1059         {
1060             parsedData->setIndexType(hashIndex);
1061         }
1062         | TREE  opt_constr_type
1063         {
1064             parsedData->setIndexType(treeIndex);
1065         }
1066         |
1067         {
1068             parsedData->setIndexType(hashIndex);
1069         }
1070         ;
1071 opt_constr_type:
1072         | UNIQUE 
1073         {
1074             parsedData->setUnique(true);
1075         }
1076         | PRIMARY 
1077         {
1078             parsedData->setUnique(true);
1079             parsedData->setPrimary(true);
1080         }
1081         |
1082         {
1083             parsedData->setUnique(false);
1084             parsedData->setPrimary(false);
1085         }
1086         ;
1087 opt_bucket:
1088         | SIZE NUMBER_STRING
1089         {
1090             parsedData->setBucketSize(atoi($2));
1091             free($2);
1092         }
1093         ;
1094 create_defn_list_con:create_defn_list
1095         |create_defn_list ',' constraint_defn
1096         ;
1097 create_defn_list: create_defn_list create_defn_list_L
1098         | create_defn
1099         ;
1101 create_defn_list_L: ',' create_defn
1102         ;
1104 create_defn: field_defn
1105         {
1106             parsedData->insertFldDef();
1107         }
1108         ;
1110 field_defn: field_name field_type size_opt null_expr_opt default_expr_opt auto_increment_key 
1111         ;
1113 field_name: ident
1114         {
1115             parsedData->setFldName($1);
1116             free($1);
1117         }
1118 size_opt:
1119         | '(' NUMBER_STRING ')'
1120         {
1121             DbRetVal rv = parsedData->setFldLength(atoi($2));
1122             if (rv != OK) {
1123                 yyerror("Binary field length < 256");
1124                 free($2);
1125                 YYABORT;
1126             }
1127             free($2);
1128         }
1129         ;
1131 default_expr_opt:
1132         | DEFAULT value
1133         {
1134             DbRetVal rv = parsedData->setDefaultValue($2);
1135             if(rv != OK){
1136                 yyerror("Invalid Default value.");
1137                 free($2);
1138                 YYABORT;
1139             }
1140             free($2);
1141         }
1142         ;
1144 null_expr_opt:
1145         | NOT NULL_VALUE
1146         {
1147             parsedData->setFldNotNull(true);
1148         }
1149         ;
1150 constraint_defn : primary_key_constraint
1151         | foreign_key_constraint
1152         | primary_key_constraint ',' foreign_key_constraint
1153         ;
1154 foreign_key_constraint: foreign_key_constraint foreign_key_constraint_L
1155         | foreign_key_create
1156         ;
1157 foreign_key_constraint_L: ',' foreign_key_create
1158         ;
1159 foreign_key_create: FOREIGN KEY '(' fkField_list ')' REFERENCES ident'(' pkField_list ')'
1160         {
1161             parsedData->setForeign(true);
1162             parsedData->setPKTableName((char*)$7);
1163             parsedData->insertForeignKeyList();
1164         }
1165         ;
1166 fkField_list: fkField_list fkField_list_L
1167         | fkField
1168         ;
1169 fkField_list_L: ',' fkField
1170         ;
1171 fkField: ident
1172         {
1173            parsedData->insertFKField((char*)$1);
1174            free($1);
1175         }
1176         ;
1177 pkField_list: pkField_list pkField_list_L
1178         | pkField
1179         ;
1180 pkField_list_L: ',' pkField
1181         ;
1182 pkField: ident
1183         {
1184            parsedData->insertPKField((char*)$1);
1185            free($1);
1186         }
1187         ;
1189 primary_key_constraint: PRIMARY KEY '(' field_list ')' opt_bucket
1190         {
1191            parsedData->setPrimary(true);
1192         }
1193         ;
1194 auto_increment_key:
1195         | AUTO_INCREMENT
1196         {
1197            DataType type = parsedData->getFldType();
1198            if(type > 4)
1199            {
1200                yyerror("AUTO_INCREMENT KEY can't be created other than INTEGER field ");
1201                free($1);
1202                YYABORT;
1203            }
1204            DbRetVal ret = parsedData->setAutoIncreament(true);
1205            if(ret != OK){
1206                yyerror("A table should have ony one AUTO_INCREMENT KEY ");
1207                free($1);
1208                YYABORT;
1209            }
1210            parsedData->setFldNotNull(true);
1211            parsedData->setAutoFldName(parsedData->getFldName());
1212            parsedData->setPrimary(true);
1213         }
1214         ;
1216 field_type: INT_TYPE
1217         {
1218             parsedData->setFldType(typeInt);
1219         }
1220         | LONG_TYPE
1221         {
1222             parsedData->setFldType(typeLong);
1223         }
1224         | SHORT_TYPE
1225         {
1226             parsedData->setFldType(typeShort);
1227         }
1228         | BIGINT_TYPE
1229         {
1230             parsedData->setFldType(typeLongLong);
1231         }
1232         | TINYINT_TYPE
1233         {
1234             parsedData->setFldType(typeByteInt);
1235         }
1236         | FLOAT_TYPE
1237         {
1238             parsedData->setFldType(typeFloat);
1239         }
1240         | DOUBLE_TYPE
1241         {
1242             parsedData->setFldType(typeDouble);
1243         }
1244         ;
1245         | DATE_TYPE
1246         {
1247             parsedData->setFldType(typeDate);
1248         }
1249         ;
1250         | TIME_TYPE
1251         {
1252             parsedData->setFldType(typeTime);
1253         }
1254         ;
1255         | TIMESTAMP_TYPE
1256         {
1257             parsedData->setFldType(typeTimeStamp);
1258         }
1259         ;
1260         | CHAR_TYPE
1261         {
1262             parsedData->setFldType(typeString);
1263             parsedData->setFldLength(2);
1264         }
1265         ;
1266         | VARCHAR_TYPE
1267         {
1268             parsedData->setFldType(typeVarchar);
1269             parsedData->setFldLength(2);
1270         }
1271         ;
1272         | BINARY_TYPE
1273         {
1274             parsedData->setFldType(typeBinary);
1275             parsedData->setFldLength(1);
1276         }
1277         ;
1280 extern int lexEof;
1281 void yyerror(const char* Msg) { 
1282     if( lexEof == 0 )
1283         fprintf(stderr, "[Parser: %s] %s\n", Msg, yytext);
1285     return;