1 |
dpavlin |
1 |
/* |
2 |
|
|
* This SQL Parser is copied from the O'Reilly Lex & Yacc book, 2nd Edition, |
3 |
|
|
* 1995, by John R. Levine, Tony Mason, and Doug Brown. I only copied the |
4 |
|
|
* query-related language subset. Added some stuff so it could interface w/ |
5 |
|
|
* Obj_Srvr.pm. |
6 |
|
|
* |
7 |
|
|
* Jeremy Hickerson, 5/21/2003 |
8 |
|
|
*/ |
9 |
|
|
|
10 |
|
|
%{ |
11 |
|
|
#define YYDEBUG 0 |
12 |
|
|
extern int yydebug = 0; /* jhjh */ |
13 |
|
|
|
14 |
|
|
#include <string.h> |
15 |
|
|
#include "obj_srvr.h" |
16 |
|
|
/* #include "flexdef.h" */ |
17 |
|
|
|
18 |
|
|
char fullname[255]; |
19 |
|
|
char temp[255]; |
20 |
|
|
char tmpstr[3]; |
21 |
|
|
char perl_op[31]; |
22 |
|
|
char tmp_str[31]; |
23 |
|
|
|
24 |
|
|
void yyerror(); |
25 |
|
|
char *alloca (); |
26 |
|
|
void end_sql(); |
27 |
|
|
%} |
28 |
|
|
|
29 |
|
|
/* symbolic tokens */ |
30 |
|
|
/* jhjh %union { |
31 |
|
|
int intval; |
32 |
|
|
double floatval; |
33 |
|
|
char *strval; |
34 |
|
|
int subtok; |
35 |
|
|
} */ |
36 |
|
|
|
37 |
|
|
%token <strval> NAME |
38 |
|
|
%token <strval> STRING |
39 |
|
|
%token <strval> INTNUM APPROXNUM |
40 |
|
|
|
41 |
|
|
%type <strval> statement query_exp query_term query_spec opt_all_distinct |
42 |
|
|
%type <strval> selection table_exp opt_where_clause from_clause |
43 |
|
|
%type <strval> table_ref_commalist table_ref where_clause opt_order_by_clause |
44 |
|
|
%type <strval> opt_group_by_clause column_ref_commalist opt_having_clause |
45 |
|
|
%type <strval> search_condition predicate comparison_predicate between_predicate |
46 |
|
|
%type <strval> comparison |
47 |
|
|
%type <strval> like_predicate opt_escape test_for_null in_predicate atom_commalist |
48 |
|
|
%type <strval> all_or_any_predicate any_all_some existence_test subquery |
49 |
|
|
%type <strval> scalar_exp scalar_exp_commalist atom parameter_ref function_ref |
50 |
|
|
%type <strval> literal table column_ref column cursor parameter range_variable |
51 |
|
|
%type <strval> user sql when_action |
52 |
|
|
|
53 |
|
|
/* type for literals */ |
54 |
|
|
%type <strval> '(' ')' '.' |
55 |
|
|
|
56 |
|
|
/* operators */ |
57 |
|
|
%left <strval> OR |
58 |
|
|
%left <strval> AND |
59 |
|
|
%left <strval> NOT |
60 |
|
|
%left <strval> COMP_EQ /* = */ |
61 |
|
|
%left <strval> COMP_NE1 /* <> */ |
62 |
|
|
%left <strval> COMP_NE2 /* != */ |
63 |
|
|
%left <strval> COMP_LT /* < */ |
64 |
|
|
%left <strval> COMP_GT /* > */ |
65 |
|
|
%left <strval> COMP_LE /* <= */ |
66 |
|
|
%left <strval> COMP_GE /* >= */ |
67 |
|
|
%left <strval> '+' '-' |
68 |
|
|
%left <strval> '*' '/' |
69 |
|
|
%nonassoc <strval> UMINUS |
70 |
|
|
|
71 |
|
|
|
72 |
|
|
/* literal keyword tokens */ |
73 |
|
|
%token <strval> ALL AMMSC ANY AS ASC AUTHORIZATION BETWEEN BY CHARACTER |
74 |
|
|
%token <strval> CHECK CLOSE CONTINUE CURRENT CURSOR DECIMAL DECLARE DEFAULT |
75 |
|
|
%token <strval> DESC DISTINCT DOUBLE ESCAPE EXISTS FETCH FLOAT FOR FOREIGN |
76 |
|
|
%token <strval> FOUND FROM GOTO GROUP HAVING IN INDICATOR INTEGER INTO IS KEY |
77 |
|
|
%token <strval> LANGUAGE LIKE NULLX NUMERIC OF ON OPEN OPTION ORDER PARAMETER |
78 |
|
|
%token <strval> PRECISION PRIMARY PRIVILEGES PROCEDURE REAL REFERENCES SCHEMA |
79 |
|
|
%token <strval> SELECT SMALLINT SOME SQLCODE SQLERROR TO UNION UNIQUE USER |
80 |
|
|
%token <strval> VALUES WHENEVER WHERE WITH WORK |
81 |
|
|
|
82 |
|
|
%% |
83 |
|
|
|
84 |
|
|
statement: |
85 |
|
|
query_exp ';' { end_sql(); return 0; } |
86 |
|
|
| statement query_exp ';' { end_sql(); return 0; } |
87 |
|
|
; |
88 |
|
|
|
89 |
|
|
/* query expressions */ |
90 |
|
|
query_exp: |
91 |
|
|
query_term |
92 |
|
|
| query_exp UNION query_term |
93 |
|
|
| query_exp UNION ALL query_term |
94 |
|
|
; |
95 |
|
|
|
96 |
|
|
query_term: |
97 |
|
|
query_spec |
98 |
|
|
| '(' query_exp ')' |
99 |
|
|
; |
100 |
|
|
|
101 |
|
|
query_spec: |
102 |
|
|
SELECT opt_all_distinct selection table_exp { |
103 |
|
|
strcpy(parsed_sql.column_list, $3); |
104 |
|
|
} |
105 |
|
|
; |
106 |
|
|
|
107 |
|
|
opt_all_distinct: |
108 |
|
|
/* empty */ |
109 |
|
|
| ALL |
110 |
|
|
| DISTINCT |
111 |
|
|
; |
112 |
|
|
|
113 |
|
|
selection: |
114 |
|
|
scalar_exp_commalist |
115 |
|
|
| '*' |
116 |
|
|
; |
117 |
|
|
|
118 |
|
|
table_exp: |
119 |
|
|
from_clause |
120 |
|
|
opt_where_clause |
121 |
|
|
opt_order_by_clause opt_group_by_clause opt_having_clause |
122 |
|
|
; |
123 |
|
|
|
124 |
|
|
opt_where_clause: |
125 |
|
|
/* empty */ |
126 |
|
|
| where_clause |
127 |
|
|
; |
128 |
|
|
|
129 |
|
|
from_clause: |
130 |
|
|
FROM table_ref_commalist { |
131 |
|
|
strcpy(parsed_sql.table_list, $2); |
132 |
|
|
} |
133 |
|
|
; |
134 |
|
|
|
135 |
|
|
table_ref_commalist: |
136 |
|
|
table_ref |
137 |
|
|
| table_ref_commalist ',' table_ref { |
138 |
|
|
printf("Multiple-table query not handled\n"); glb_errflag = 1; |
139 |
|
|
} |
140 |
|
|
; |
141 |
|
|
|
142 |
|
|
table_ref: |
143 |
|
|
table |
144 |
|
|
| table range_variable |
145 |
|
|
; |
146 |
|
|
|
147 |
|
|
where_clause: |
148 |
|
|
WHERE search_condition { |
149 |
|
|
strcpy(parsed_sql.where_clause, $2); |
150 |
|
|
} |
151 |
|
|
; |
152 |
|
|
|
153 |
|
|
opt_order_by_clause: |
154 |
|
|
/* empty */ |
155 |
|
|
| ORDER BY column_ref_commalist { |
156 |
|
|
strcpy(parsed_sql.order_by, $3); |
157 |
|
|
} |
158 |
|
|
; |
159 |
|
|
|
160 |
|
|
opt_group_by_clause: |
161 |
|
|
/* empty */ |
162 |
|
|
| GROUP BY column_ref_commalist |
163 |
|
|
; |
164 |
|
|
|
165 |
|
|
column_ref_commalist: |
166 |
|
|
column_ref |
167 |
|
|
| column_ref_commalist ',' column_ref { |
168 |
|
|
strcpy($$, $1); |
169 |
|
|
strcat($$, ","); |
170 |
|
|
strcat($$, $3); |
171 |
|
|
} |
172 |
|
|
; |
173 |
|
|
|
174 |
|
|
opt_having_clause: |
175 |
|
|
/* empty */ |
176 |
|
|
| HAVING search_condition { |
177 |
|
|
printf("HAVING condition not handled\n"); glb_errflag = 1; |
178 |
|
|
} |
179 |
|
|
; |
180 |
|
|
|
181 |
|
|
|
182 |
|
|
/* search conditions */ |
183 |
|
|
search_condition: |
184 |
|
|
search_condition OR search_condition { |
185 |
|
|
strcpy($$, $1); |
186 |
|
|
strcat($$, ","); /* use comma's for spaces because of obj_srvr.pm */ |
187 |
|
|
strcat($$, $2); |
188 |
|
|
strcat($$, ","); |
189 |
|
|
strcat($$, $3); |
190 |
|
|
} |
191 |
|
|
| search_condition AND search_condition { |
192 |
|
|
strcpy($$, $1); |
193 |
|
|
strcat($$, ","); /* use comma's for spaces because of obj_srvr.pm */ |
194 |
|
|
strcat($$, $2); |
195 |
|
|
strcat($$, ","); |
196 |
|
|
strcat($$, $3); |
197 |
|
|
} |
198 |
|
|
| NOT search_condition { |
199 |
|
|
strcpy($$, $1); |
200 |
|
|
strcat($$, ","); /* use comma's for spaces because of obj_srvr.pm */ |
201 |
|
|
strcat($$, $2); |
202 |
|
|
} |
203 |
|
|
| '(' search_condition ')' { |
204 |
|
|
strcpy($$, $1); |
205 |
|
|
strcat($$, ","); /* use comma's for spaces because of obj_srvr.pm */ |
206 |
|
|
strcat($$, $2); |
207 |
|
|
strcat($$, ","); |
208 |
|
|
strcat($$, $3); |
209 |
|
|
} |
210 |
|
|
| predicate |
211 |
|
|
; |
212 |
|
|
|
213 |
|
|
predicate: |
214 |
|
|
comparison_predicate |
215 |
|
|
| between_predicate |
216 |
|
|
| like_predicate |
217 |
|
|
| test_for_null |
218 |
|
|
| in_predicate |
219 |
|
|
| all_or_any_predicate |
220 |
|
|
| existence_test |
221 |
|
|
; |
222 |
|
|
|
223 |
|
|
comparison_predicate: |
224 |
|
|
scalar_exp comparison scalar_exp { |
225 |
|
|
|
226 |
|
|
strcpy(perl_op, |
227 |
|
|
call_perl_tr_op(parsed_sql.table_list, $1, $2, $3) ); |
228 |
|
|
/* only one table allowed in "table_list" */ |
229 |
|
|
|
230 |
|
|
if ( strlen(perl_op) == 15 && |
231 |
|
|
perl_op[0] == 'd' && |
232 |
|
|
perl_op[1] == 'a' && |
233 |
|
|
perl_op[2] == 't' && |
234 |
|
|
perl_op[3] == 'e' && |
235 |
|
|
perl_op[4] == '_' && |
236 |
|
|
perl_op[5] == 'c' && |
237 |
|
|
perl_op[6] == 'o' && |
238 |
|
|
perl_op[7] == 'm' && |
239 |
|
|
perl_op[8] == 'p' && |
240 |
|
|
perl_op[9] == 'a' && |
241 |
|
|
perl_op[10] == 'r' && |
242 |
|
|
perl_op[11] == 'e' ) { |
243 |
|
|
|
244 |
|
|
strcpy(tmp_str, perl_op); |
245 |
|
|
perl_op[0] = tmp_str[13]; /* tmp_str[12] is '_' */ |
246 |
|
|
perl_op[1] = tmp_str[14]; |
247 |
|
|
perl_op[2] = '\0'; |
248 |
|
|
|
249 |
|
|
sprintf($$, "date_compare(,%s,\\\\,'%s'\\\\,%s)", |
250 |
|
|
$1, perl_op, $3); |
251 |
|
|
/* commas around 1st %s translate into spaces; */ |
252 |
|
|
/* need spaces so $subst_where will be correct */ |
253 |
|
|
/* double escape so perl will see as the */ |
254 |
|
|
/* character '\' rather than a perl escape */ |
255 |
|
|
} |
256 |
|
|
else { |
257 |
|
|
strcpy($$, $1); |
258 |
|
|
strcat($$, ","); /* use comma's for spaces because of |
259 |
|
|
obj_srvr.pm */ |
260 |
|
|
strcat($$, perl_op); |
261 |
|
|
strcat($$, ","); |
262 |
|
|
strcat($$, $3); |
263 |
|
|
} |
264 |
|
|
} |
265 |
|
|
| scalar_exp comparison subquery |
266 |
|
|
; |
267 |
|
|
|
268 |
|
|
comparison: |
269 |
|
|
COMP_EQ |
270 |
|
|
| COMP_NE1 |
271 |
|
|
| COMP_NE2 |
272 |
|
|
| COMP_LT |
273 |
|
|
| COMP_GT |
274 |
|
|
| COMP_LE |
275 |
|
|
| COMP_GE |
276 |
|
|
; |
277 |
|
|
|
278 |
|
|
between_predicate: |
279 |
|
|
scalar_exp NOT BETWEEN scalar_exp AND scalar_exp { |
280 |
|
|
|
281 |
|
|
strcpy(perl_op, |
282 |
|
|
call_perl_tr_op(parsed_sql.table_list, $1, ">=", $4) ); |
283 |
|
|
/* only one table allowed in "table_list" */ |
284 |
|
|
|
285 |
|
|
if ( strlen(perl_op) == 15 && |
286 |
|
|
perl_op[0] == 'd' && |
287 |
|
|
perl_op[1] == 'a' && |
288 |
|
|
perl_op[2] == 't' && |
289 |
|
|
perl_op[3] == 'e' && |
290 |
|
|
perl_op[4] == '_' && |
291 |
|
|
perl_op[5] == 'c' && |
292 |
|
|
perl_op[6] == 'o' && |
293 |
|
|
perl_op[7] == 'm' && |
294 |
|
|
perl_op[8] == 'p' && |
295 |
|
|
perl_op[9] == 'a' && |
296 |
|
|
perl_op[10] == 'r' && |
297 |
|
|
perl_op[11] == 'e' ) { |
298 |
|
|
|
299 |
|
|
sprintf($$, "!(date_compare(,%s,\\\\,'%s'\\\\,%s),and,date_compare(,%s,\\\\,'%s'\\\\,%s))", |
300 |
|
|
$1, ">=", $4, $1, "<=", $6); |
301 |
|
|
/* commas around 1st %s translate into spaces; */ |
302 |
|
|
/* need spaces so $subst_where will be correct */ |
303 |
|
|
/* double escape so perl will see as the */ |
304 |
|
|
/* character '\' rather than a perl escape */ |
305 |
|
|
} |
306 |
|
|
else { |
307 |
|
|
strcpy($$, "!("); |
308 |
|
|
strcat($$, $1); |
309 |
|
|
strcat($$, ","); /* use comma's for spaces because of |
310 |
|
|
obj_srvr.pm */ |
311 |
|
|
strcat($$, ">="); |
312 |
|
|
strcat($$, ","); |
313 |
|
|
strcat($$, $4); |
314 |
|
|
strcat($$, ",and,"); |
315 |
|
|
strcat($$, $1); |
316 |
|
|
strcat($$, ","); |
317 |
|
|
strcat($$, "<="); |
318 |
|
|
strcat($$, ","); |
319 |
|
|
strcat($$, $6); |
320 |
|
|
strcat($$, ")"); |
321 |
|
|
} |
322 |
|
|
} |
323 |
|
|
|
324 |
|
|
| scalar_exp BETWEEN scalar_exp AND scalar_exp { |
325 |
|
|
|
326 |
|
|
strcpy(perl_op, |
327 |
|
|
call_perl_tr_op(parsed_sql.table_list, $1, ">=", $3) ); |
328 |
|
|
/* only one table allowed in "table_list" */ |
329 |
|
|
|
330 |
|
|
if ( strlen(perl_op) == 15 && |
331 |
|
|
perl_op[0] == 'd' && |
332 |
|
|
perl_op[1] == 'a' && |
333 |
|
|
perl_op[2] == 't' && |
334 |
|
|
perl_op[3] == 'e' && |
335 |
|
|
perl_op[4] == '_' && |
336 |
|
|
perl_op[5] == 'c' && |
337 |
|
|
perl_op[6] == 'o' && |
338 |
|
|
perl_op[7] == 'm' && |
339 |
|
|
perl_op[8] == 'p' && |
340 |
|
|
perl_op[9] == 'a' && |
341 |
|
|
perl_op[10] == 'r' && |
342 |
|
|
perl_op[11] == 'e' ) { |
343 |
|
|
|
344 |
|
|
sprintf($$, "date_compare(,%s,\\\\,'%s'\\\\,%s),and,date_compare(,%s,\\\\,'%s'\\\\,%s)", |
345 |
|
|
$1, ">=", $3, $1, "<=", $5); |
346 |
|
|
/* commas around 1st %s translate into spaces; */ |
347 |
|
|
/* need spaces so $subst_where will be correct */ |
348 |
|
|
/* double escape so perl will see as the */ |
349 |
|
|
/* character '\' rather than a perl escape */ |
350 |
|
|
} |
351 |
|
|
else { |
352 |
|
|
strcpy($$, $1); |
353 |
|
|
strcat($$, ","); /* use comma's for spaces because of |
354 |
|
|
obj_srvr.pm */ |
355 |
|
|
strcat($$, ">="); |
356 |
|
|
strcat($$, ","); |
357 |
|
|
strcat($$, $3); |
358 |
|
|
strcat($$, ",and,"); |
359 |
|
|
strcat($$, $1); |
360 |
|
|
strcat($$, ","); |
361 |
|
|
strcat($$, "<="); |
362 |
|
|
strcat($$, ","); |
363 |
|
|
strcat($$, $5); |
364 |
|
|
} |
365 |
|
|
} |
366 |
|
|
; |
367 |
|
|
|
368 |
|
|
like_predicate: |
369 |
|
|
scalar_exp NOT LIKE atom opt_escape { |
370 |
|
|
strcpy($$, call_perl_like2re($1, $2, $3, $4) ); |
371 |
|
|
} |
372 |
|
|
| scalar_exp LIKE atom opt_escape { |
373 |
|
|
strcpy($$, call_perl_like2re($1, $2, $3, "") ); |
374 |
|
|
} |
375 |
|
|
; |
376 |
|
|
|
377 |
|
|
|
378 |
|
|
opt_escape: |
379 |
|
|
/* empty */ |
380 |
|
|
| ESCAPE atom { |
381 |
|
|
printf("Escape not handled\n"); glb_errflag = 1; |
382 |
|
|
} |
383 |
|
|
; |
384 |
|
|
|
385 |
|
|
test_for_null: |
386 |
|
|
column_ref IS NOT NULLX { |
387 |
|
|
strcpy($$, $1); |
388 |
|
|
strcat($$, ","); /* use comma's for spaces because of obj_srvr.pm */ |
389 |
|
|
strcat($$, $2); |
390 |
|
|
strcat($$, ","); |
391 |
|
|
strcat($$, $3); |
392 |
|
|
strcat($$, ","); |
393 |
|
|
strcat($$, $4); |
394 |
|
|
} |
395 |
|
|
| column_ref IS NULLX { |
396 |
|
|
strcpy($$, $1); |
397 |
|
|
strcat($$, ","); |
398 |
|
|
strcat($$, $2); |
399 |
|
|
strcat($$, ","); |
400 |
|
|
strcat($$, $3); |
401 |
|
|
} |
402 |
|
|
; |
403 |
|
|
|
404 |
|
|
in_predicate: |
405 |
|
|
scalar_exp NOT IN subquery { |
406 |
|
|
printf("Subquery not handled\n"); glb_errflag = 1; |
407 |
|
|
} |
408 |
|
|
| scalar_exp IN subquery { |
409 |
|
|
printf("Subquery not handled\n"); glb_errflag = 1; |
410 |
|
|
} |
411 |
|
|
| scalar_exp NOT IN '(' atom_commalist ')' { |
412 |
|
|
/* Translate into equivalent perl expression for reval in Obj_Srvr.pm */ |
413 |
|
|
/* (Use comma's for spaces because that's how Obj_Srvr.pm expects */ |
414 |
|
|
/* it. Obj_Srvr.pm will convert comma's to spaces before reval.) */ |
415 |
|
|
/* perl-escape foward slashes and parentheses to avoid screwing up */ |
416 |
|
|
/* first round of perl parsing (wh/ uses reg. exp's), before reval(). */ |
417 |
|
|
strcpy($$, "!grep \\/^"); |
418 |
|
|
strcat($$, $1); |
419 |
|
|
strcat($$, "$\\/\\\\, "); /* double escape so perl will see as the */ |
420 |
|
|
/* character '\' rather than a perl escape */ |
421 |
|
|
strcat($$, "\\("); |
422 |
|
|
strcat($$, $4); |
423 |
|
|
strcat($$, "\\)"); |
424 |
|
|
} |
425 |
|
|
| scalar_exp IN '(' atom_commalist ')' { |
426 |
|
|
/* Translate into equivalent perl expression for reval in Obj_Srvr.pm */ |
427 |
|
|
strcpy($$, "grep \\/^"); |
428 |
|
|
strcat($$, $1); |
429 |
|
|
strcat($$, "$\\/\\\\, "); |
430 |
|
|
strcat($$, "\\("); |
431 |
|
|
strcat($$, $4); |
432 |
|
|
strcat($$, "\\)"); |
433 |
|
|
} |
434 |
|
|
; |
435 |
|
|
|
436 |
|
|
atom_commalist: |
437 |
|
|
atom |
438 |
|
|
| atom_commalist ',' atom { |
439 |
|
|
strcpy($$, $1); |
440 |
|
|
strcat($$, "\\\\,"); /* save from perl-parse (see in_predicate:) */ |
441 |
|
|
strcat($$, $3); |
442 |
|
|
} |
443 |
|
|
; |
444 |
|
|
|
445 |
|
|
all_or_any_predicate: |
446 |
|
|
scalar_exp comparison any_all_some subquery { |
447 |
|
|
printf("Subquery not handled\n"); glb_errflag = 1; |
448 |
|
|
} |
449 |
|
|
; |
450 |
|
|
|
451 |
|
|
any_all_some: |
452 |
|
|
ANY |
453 |
|
|
| ALL |
454 |
|
|
| SOME |
455 |
|
|
; |
456 |
|
|
|
457 |
|
|
existence_test: |
458 |
|
|
EXISTS subquery |
459 |
|
|
{ printf("Subquery not handled\n"); glb_errflag = 1; } |
460 |
|
|
; |
461 |
|
|
|
462 |
|
|
/* jhjh - we won't handle subqueries; shouldn't need w/ a simple data model */ |
463 |
|
|
subquery: |
464 |
|
|
'(' SELECT opt_all_distinct selection table_exp ')' |
465 |
|
|
{ printf("Subquery not handled\n"); glb_errflag = 1; } |
466 |
|
|
; |
467 |
|
|
|
468 |
|
|
|
469 |
|
|
/* scalar expressions */ |
470 |
|
|
scalar_exp: |
471 |
|
|
scalar_exp '+' scalar_exp { |
472 |
|
|
strcpy($$, $1); |
473 |
|
|
strcat($$, ","); /* use comma's for spaces because of obj_srvr.pm */ |
474 |
|
|
strcat($$, $2); |
475 |
|
|
strcat($$, ","); |
476 |
|
|
strcat($$, $3); |
477 |
|
|
} |
478 |
|
|
| scalar_exp '-' scalar_exp { |
479 |
|
|
strcpy($$, $1); |
480 |
|
|
strcat($$, ","); /* use comma's for spaces because of obj_srvr.pm */ |
481 |
|
|
strcat($$, $2); |
482 |
|
|
strcat($$, ","); |
483 |
|
|
strcat($$, $3); |
484 |
|
|
} |
485 |
|
|
| scalar_exp '*' scalar_exp { |
486 |
|
|
strcpy($$, $1); |
487 |
|
|
strcat($$, ","); /* use comma's for spaces because of obj_srvr.pm */ |
488 |
|
|
strcat($$, $2); |
489 |
|
|
strcat($$, ","); |
490 |
|
|
strcat($$, $3); |
491 |
|
|
} |
492 |
|
|
| scalar_exp '/' scalar_exp { |
493 |
|
|
strcpy($$, $1); |
494 |
|
|
strcat($$, ","); /* use comma's for spaces because of obj_srvr.pm */ |
495 |
|
|
strcat($$, $2); |
496 |
|
|
strcat($$, ","); |
497 |
|
|
strcat($$, $3); |
498 |
|
|
} |
499 |
|
|
| '+' scalar_exp %prec UMINUS { /* jhjh - what is this */ |
500 |
|
|
strcpy($$, $1); |
501 |
|
|
strcat($$, ","); |
502 |
|
|
strcat($$, $2); |
503 |
|
|
} |
504 |
|
|
| '-' scalar_exp %prec UMINUS { /* jhjh - what is this */ |
505 |
|
|
strcpy($$, $1); |
506 |
|
|
strcat($$, ","); |
507 |
|
|
strcat($$, $2); |
508 |
|
|
} |
509 |
|
|
| atom /* jhjh - ignore multi-word possibilities here */ |
510 |
|
|
| column_ref |
511 |
|
|
| function_ref /* jhjh - ignore functions */ |
512 |
|
|
| '(' scalar_exp ')' { |
513 |
|
|
strcpy($$, $1); |
514 |
|
|
strcat($$, ","); /* use comma's for spaces because of obj_srvr.pm */ |
515 |
|
|
strcat($$, $2); |
516 |
|
|
strcat($$, ","); |
517 |
|
|
strcat($$, $3); |
518 |
|
|
} |
519 |
|
|
; |
520 |
|
|
|
521 |
|
|
scalar_exp_commalist: |
522 |
|
|
scalar_exp |
523 |
|
|
| scalar_exp_commalist ',' scalar_exp { |
524 |
|
|
strcpy($$, $1); |
525 |
|
|
strcat($$, ","); |
526 |
|
|
strcat($$, $3); |
527 |
|
|
} |
528 |
|
|
; |
529 |
|
|
atom: |
530 |
|
|
parameter_ref |
531 |
|
|
| literal |
532 |
|
|
| USER |
533 |
|
|
; |
534 |
|
|
|
535 |
|
|
parameter_ref: |
536 |
|
|
parameter |
537 |
|
|
| parameter parameter |
538 |
|
|
| parameter INDICATOR parameter |
539 |
|
|
; |
540 |
|
|
|
541 |
|
|
function_ref: |
542 |
|
|
AMMSC '(' '*' ')' |
543 |
|
|
| AMMSC '(' DISTINCT column_ref ')' |
544 |
|
|
| AMMSC '(' ALL scalar_exp ')' |
545 |
|
|
| AMMSC '(' scalar_exp ')' |
546 |
|
|
; |
547 |
|
|
|
548 |
|
|
literal: |
549 |
|
|
STRING |
550 |
|
|
| INTNUM |
551 |
|
|
| APPROXNUM |
552 |
|
|
; |
553 |
|
|
|
554 |
|
|
|
555 |
|
|
/* miscellaneous */ |
556 |
|
|
table: |
557 |
|
|
NAME |
558 |
|
|
|
559 |
|
|
| NAME '.' NAME |
560 |
|
|
; |
561 |
|
|
|
562 |
|
|
column_ref: |
563 |
|
|
INTNUM |
564 |
|
|
| NAME |
565 |
|
|
| NAME '.' NAME { strcpy($$, $3) } |
566 |
|
|
| NAME '.' NAME '.' NAME |
567 |
|
|
| column_ref NAME { |
568 |
|
|
printf("Multiple-table query not handled\n"); glb_errflag = 1; |
569 |
|
|
} |
570 |
|
|
; |
571 |
|
|
|
572 |
|
|
|
573 |
|
|
/* the various things you can name */ |
574 |
|
|
column: |
575 |
|
|
NAME |
576 |
|
|
; |
577 |
|
|
|
578 |
|
|
cursor: |
579 |
|
|
NAME |
580 |
|
|
; |
581 |
|
|
|
582 |
|
|
parameter: |
583 |
|
|
PARAMETER /* :name handled in parser */ |
584 |
|
|
; |
585 |
|
|
|
586 |
|
|
range_variable: |
587 |
|
|
NAME { |
588 |
|
|
printf("Table alias not handled\n"); glb_errflag = 1; |
589 |
|
|
} |
590 |
|
|
; |
591 |
|
|
|
592 |
|
|
user: |
593 |
|
|
NAME |
594 |
|
|
; |
595 |
|
|
|
596 |
|
|
|
597 |
|
|
/* embedded condition things */ |
598 |
|
|
sql: |
599 |
|
|
WHENEVER NOT FOUND when_action |
600 |
|
|
| WHENEVER SQLERROR when_action |
601 |
|
|
; |
602 |
|
|
|
603 |
|
|
when_action: |
604 |
|
|
GOTO NAME |
605 |
|
|
| CONTINUE |
606 |
|
|
; |
607 |
|
|
|
608 |
|
|
%% |
609 |
|
|
|