Bug: 1848890 select core dump after unique key violation
[csql.git] / src / sql / dmlyacc.yxx
blob8331d028f83acd1ad3c3ff7228daf38afdbd31de
1 %{
2 #include <CSql.h>
3 #include <stdlib.h>
4 #include "Parser.h"
6 class Predicate;
8 ParsedData *parsedData;
9 extern char yytext[];
10 int yylex( void );
11 void yyerror(const char* Msg);
15 %union
17    char *stringval;
18    void *predicate;
21 %token <stringval> STRING FIELD NUMBER_STRING BINARY_STRING DOUBLE OPERATOR PARAMETER
22 %token <stringval> SELECT FROM WHERE BETWEEN AND OR NOT
23 %token <stringval> STAR
24 %token <stringval> INSERT INTO VALUES
25 %token <stringval> DELETE UPDATE SET NULL_VALUE
26 %token <stringval> CREATE TABLE PRIMARY KEY DEFAULT INDEX ON HASH TREE UNIQUE DROP
27 %token <stringval> INT_TYPE LONG_TYPE SHORT_TYPE DOUBLE_TYPE TIMESTAMP_TYPE DATE_TYPE CHAR_TYPE TIME_TYPE
28 %token ';' ',' '(' ')'
29 %type <stringval> ident field value 
30 %type <predicate> conditions condition
33 command:  select_statement { YYACCEPT; }
34         | insert_statement { YYACCEPT; }
35         | delete_statement { YYACCEPT; }
36         | update_statement { YYACCEPT; }
37         | ddl_statement { YYACCEPT; }
38         ;
39         
40 select_statement: SELECT field_list FROM ident where_clause_opt semicolon_opt
41         {
42             parsedData->setStmtType(SelectStatement);
43             parsedData->setTableName($4); 
44             free($4);
45         }
46         ;
48 field_list: field_list field_list_L
49         | field 
50         ;
51 field_list_L: ',' field
52         ;
53         
54 insert_statement: INSERT INTO ident field_list_opt VALUES '(' value_list ')' semicolon_opt
55         {
56             parsedData->setStmtType(InsertStatement);
57             parsedData->setTableName($3); 
58             free($3);
59         }
60         ;
62 field_list_opt:
63         | '(' field_list ')'
64         ;
66 value_list: value_list value_list_L
67         | value
68         {
69             parsedData->insertValue((char*)$1);
70             free($1);
71         }
72         ;
73 value_list_L: ',' value 
74         {
75             parsedData->insertValue((char*)$2);
76             free($2);
77         }
78         ;
79         
80 delete_statement: DELETE FROM ident where_clause_opt semicolon_opt
81         {
82             parsedData->setStmtType(DeleteStatement);
83             parsedData->setTableName($3); 
84             free($3);
85         }
86         ;
87         
88 update_statement: UPDATE ident SET assign_list where_clause_opt semicolon_opt
89         {
90             parsedData->setStmtType(UpdateStatement);
91             parsedData->setTableName($2); 
92             free( $2 );
93         }
94         ;
96 semicolon_opt: ';'
97         |
98         ;
100 assign_list: assign_list assign_list_L
101         | assign_stmt
102         ;
104 assign_list_L: ',' assign_stmt
105         ;
106 assign_stmt: ident OPERATOR value 
107         { 
108             parsedData->insertUpdateValue( (char*) $1, (char*) $3);
109             free( $1 ); free( $3 ); 
110         }
111         ;
113 where_clause_opt:  WHERE conditions
114         |
115         ;
117 conditions: condition AND condition
118         {
119             Predicate *pred;
120             pred = parsedData->insertPredicate((Predicate*) $1, OpAnd, (Predicate*) $3);
121             parsedData->setCondition((Predicate*)pred);
122             $$= pred;
124         }
125         | condition OR condition
126         {
127             Predicate *pred;
128             pred = parsedData->insertPredicate((Predicate*) $1, OpOr, (Predicate*) $3);
129             parsedData->setCondition((Predicate*)pred);
130             $$= pred;
131         }
132         | NOT condition
133         {
134             Predicate *pred;
135             pred = parsedData->insertPredicate((Predicate*) $2, OpNot, NULL);
136             parsedData->setCondition((Predicate*)pred);
137             //((Predicate*)$2)->print();
138             $$= pred;
139         }
140         | condition
141         {
142             parsedData->setCondition((Predicate*)$1);
143             //((Predicate*)$1)->print();
144             $$=$1;
145         }
146         ;
147 condition: ident OPERATOR value 
148         {
149             ComparisionOp  op = AllDataType::getComparisionOperator((char*)$2);
150             Predicate *pred;
151             void **ptr = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$3);
152             pred = parsedData->insertPredicate((char*) $1, op, ptr);
153             free( $1 ); free( $3 ); 
154             $$=pred;
155         }
156         | ident BETWEEN value AND value
157         {
158             void **ptr1 = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$3);
159             void **ptr2 = parsedData->insertCondValueAndGetPtr((char*)$1, (char*)$5);
160             Predicate *pred1, *pred2, *pred3;
161             pred1 = parsedData->insertPredicate((char*) $1, OpGreaterThanEquals, ptr1);
162             pred2 = parsedData->insertPredicate((char*) $1, OpLessThanEquals, ptr2);
163             pred3 = parsedData->insertPredicate(pred1, OpAnd, pred2);
164             free( $1 );  free( $3 );  free( $5 );
165             $$= pred3;
166         }
167         ;
168 field:   ident
169         {
170             parsedData->insertField((char*)$1);
171             free( $1 );
172         }
173         | STAR
174         { 
175             parsedData->insertField((char*)$1);
176             free( $1 );
177         }
178         ;
179 ident:    FIELD { $$ = $1; }
180         ;
181 value:    STRING { $$ = $1; }
182         | NUMBER_STRING { $$ = $1; }
183         | BINARY_STRING { $$ = $1; }
184         | DOUBLE { $$ = $1; }
185         | PARAMETER { $$ = $1; }
186         | NULL_VALUE { $$ = (char*) 0; }
187         ;
189 ddl_statement: CREATE TABLE ident '(' create_defn_list ')' semicolon_opt
190         {
191             parsedData->setStmtType(CreateTableStatement);
192             parsedData->setTableName($3); 
193             free($3);
194         }
195         | CREATE INDEX ident ON ident '(' field_list ')' opt_constr_type opt_ind_type  semicolon_opt
196         {
197             parsedData->setStmtType(CreateIndexStatement);
198             parsedData->setIndexName($3); 
199             parsedData->setTableName($5); 
200             free($3);
201             free($5);
202         }
203         | DROP TABLE ident
204         {
205             parsedData->setStmtType(DropTableStatement);
206             parsedData->setTableName($3); 
207             free($3);
208         }
209         | DROP INDEX ident
210         {
211             parsedData->setStmtType(DropIndexStatement);
212             parsedData->setIndexName($3); 
213             free($3);
214         }
215         ;
216 opt_ind_type:
217         | HASH 
218         {
219             parsedData->setIndexType(hashIndex);
220         }
221         | TREE 
222         {
223             parsedData->setIndexType(treeIndex);
224         }
225         |
226         {
227             parsedData->setIndexType(hashIndex);
228         }
229 opt_constr_type:
230         | UNIQUE 
231         {
232             parsedData->setUnique(true);
233         }
234         | PRIMARY 
235         {
236             parsedData->setUnique(true);
237             parsedData->setPrimary(true);
238         }
239         |
240         {
241             parsedData->setUnique(false);
242             parsedData->setPrimary(false);
243         }
244         ;
245 create_defn_list: create_defn_list create_defn_list_L
246         | create_defn 
247         ;
249 create_defn_list_L: ',' create_defn
250         ;
252 create_defn: field_defn
253         {
254             parsedData->insertFldDef();
255         }
256         | constraint_defn
257         ;
259 field_defn: field_name field_type size_opt null_expr_opt default_expr_opt
260         ;
262 field_name: ident
263         {
264             parsedData->setFldName($1);
265             free($1);
266         }
267 size_opt:
268         | '(' NUMBER_STRING ')'
269         {
270             parsedData->setFldLength(atoi($2));
271             free($2);
272         }
273         ;
275 default_expr_opt:
276         | DEFAULT value
277         ;
279 null_expr_opt:
280         | NOT NULL_VALUE
281         {
282             parsedData->setFldNotNull(true);
283         }
284         ;
285 constraint_defn: primary_key_constraint
286         ;
288 primary_key_constraint: PRIMARY KEY '(' field_list ')'
289         ;
291 field_type: INT_TYPE
292         {
293             parsedData->setFldType(typeInt);
294         }
295         | LONG_TYPE
296         {
297             parsedData->setFldType(typeLong);
298         }
299         | SHORT_TYPE
300         {
301             parsedData->setFldType(typeShort);
302         }
303         | BIGINT_TYPE
304         {
305             parsedData->setFldType(typeLongLong);
306         }
307         | FLOAT_TYPE
308         {
309             parsedData->setFldType(typeFloat);
310         }
311         | DOUBLE_TYPE
312         {
313             parsedData->setFldType(typeDouble);
314         }
315         ;
316         | DATE_TYPE
317         {
318             parsedData->setFldType(typeDate);
319         }
320         ;
321         | TIME_TYPE
322         {
323             parsedData->setFldType(typeTime);
324         }
325         ;
326         | TIMESTAMP_TYPE
327         {
328             parsedData->setFldType(typeTimeStamp);
329         }
330         ;
331         | CHAR_TYPE
332         {
333             parsedData->setFldType(typeString);
334         }
335         ;
338 extern int lexEof;
339 void yyerror(const char* Msg) { 
340     if( lexEof == 0 )
341         fprintf(stderr, "[Parser: %s] %s\n", Msg, yytext);
343     return;