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