]> granicus.if.org Git - postgresql/blob - src/interfaces/ecpg/preproc/ecpg.addons
aae3cc9d92d18fde7a6fc32dcc05f5781b89eb32
[postgresql] / src / interfaces / ecpg / preproc / ecpg.addons
1 /* src/interfaces/ecpg/preproc/ecpg.addons */
2 ECPG: stmtClosePortalStmt block
3         {
4                 if (INFORMIX_MODE)
5                 {
6                         if (pg_strcasecmp($1+strlen("close "), "database") == 0)
7                         {
8                                 if (connection)
9                                         mmerror(PARSE_ERROR, ET_ERROR, "AT option not allowed in CLOSE DATABASE statement");
10
11                                 fprintf(yyout, "{ ECPGdisconnect(__LINE__, \"CURRENT\");");
12                                 whenever_action(2);
13                                 free($1);
14                                 break;
15                         }
16                 }
17
18                 output_statement($1, 0, ECPGst_normal);
19         }
20 ECPG: stmtDeallocateStmt block
21         {
22                 output_deallocate_prepare_statement($1);
23         }
24 ECPG: stmtDeclareCursorStmt block
25         { output_simple_statement($1); }
26 ECPG: stmtDiscardStmt block
27 ECPG: stmtFetchStmt block
28         { output_statement($1, 1, ECPGst_normal); }
29 ECPG: stmtDeleteStmt block
30 ECPG: stmtInsertStmt block
31 ECPG: stmtSelectStmt block
32 ECPG: stmtUpdateStmt block
33         { output_statement($1, 1, ECPGst_prepnormal); }
34 ECPG: stmtExecuteStmt block
35         { output_statement($1, 1, ECPGst_execute); }
36 ECPG: stmtPrepareStmt block
37         {
38                 if ($1.type == NULL || strlen($1.type) == 0)
39                         output_prepare_statement($1.name, $1.stmt);
40                 else
41                         output_statement(cat_str(5, mm_strdup("prepare"), $1.name, $1.type, mm_strdup("as"), $1.stmt), 0, ECPGst_normal);
42         }
43 ECPG: stmtTransactionStmt block
44         {
45                 fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
46                 whenever_action(2);
47                 free($1);
48         }
49 ECPG: stmtViewStmt rule
50         | ECPGAllocateDescr
51         {
52                 fprintf(yyout,"ECPGallocate_desc(__LINE__, %s);",$1);
53                 whenever_action(0);
54                 free($1);
55         }
56         | ECPGConnect
57         {
58                 if (connection)
59                         mmerror(PARSE_ERROR, ET_ERROR, "AT option not allowed in CONNECT statement");
60
61                 fprintf(yyout, "{ ECPGconnect(__LINE__, %d, %s, %d); ", compat, $1, autocommit);
62                 reset_variables();
63                 whenever_action(2);
64                 free($1);
65         }
66         | ECPGCursorStmt
67         {
68                 output_simple_statement($1);
69         }
70         | ECPGDeallocateDescr
71         {
72                 fprintf(yyout,"ECPGdeallocate_desc(__LINE__, %s);",$1);
73                 whenever_action(0);
74                 free($1);
75         }
76         | ECPGDeclare
77         {
78                 output_simple_statement($1);
79         }
80         | ECPGDescribe
81         {
82                 fprintf(yyout, "{ ECPGdescribe(__LINE__, %d, %s,", compat, $1);
83                 dump_variables(argsresult, 1);
84                 fputs("ECPGt_EORT);", yyout);
85                 fprintf(yyout, "}");
86                 output_line_number();
87
88                 free($1);
89         }
90         | ECPGDisconnect
91         {
92                 if (connection)
93                         mmerror(PARSE_ERROR, ET_ERROR, "AT option not allowed in DISCONNECT statement");
94
95                 fprintf(yyout, "{ ECPGdisconnect(__LINE__, %s);",
96                                 $1 ? $1 : "\"CURRENT\"");
97                 whenever_action(2);
98                 free($1);
99         }
100         | ECPGExecuteImmediateStmt      { output_statement($1, 0, ECPGst_exec_immediate); }
101         | ECPGFree
102         {
103                 const char *con = connection ? connection : "NULL";
104
105                 if (strcmp($1, "all") == 0)
106                         fprintf(yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con);
107                 else if ($1[0] == ':')
108                         fprintf(yyout, "{ ECPGdeallocate(__LINE__, %d, %s, %s);", compat, con, $1+1);
109                 else
110                         fprintf(yyout, "{ ECPGdeallocate(__LINE__, %d, %s, \"%s\");", compat, con, $1);
111
112                 whenever_action(2);
113                 free($1);
114         }
115         | ECPGGetDescriptor
116         {
117                 lookup_descriptor($1.name, connection);
118                 output_get_descr($1.name, $1.str);
119                 free($1.name);
120                 free($1.str);
121         }
122         | ECPGGetDescriptorHeader
123         {
124                 lookup_descriptor($1, connection);
125                 output_get_descr_header($1);
126                 free($1);
127         }
128         | ECPGOpen
129         {
130                 struct cursor *ptr;
131
132                 if ((ptr = add_additional_variables($1, true)) != NULL)
133                 {
134                         connection = ptr->connection ? mm_strdup(ptr->connection) : NULL;
135                         output_statement(mm_strdup(ptr->command), 0, ECPGst_normal);
136                         ptr->opened = true;
137                 }
138         }
139         | ECPGSetAutocommit
140         {
141                 fprintf(yyout, "{ ECPGsetcommit(__LINE__, \"%s\", %s);", $1, connection ? connection : "NULL");
142                 whenever_action(2);
143                 free($1);
144         }
145         | ECPGSetConnection
146         {
147                 if (connection)
148                         mmerror(PARSE_ERROR, ET_ERROR, "AT option not allowed in SET CONNECTION statement");
149
150                 fprintf(yyout, "{ ECPGsetconn(__LINE__, %s);", $1);
151                 whenever_action(2);
152                 free($1);
153         }
154         | ECPGSetDescriptor
155         {
156                 lookup_descriptor($1.name, connection);
157                 output_set_descr($1.name, $1.str);
158                 free($1.name);
159                 free($1.str);
160         }
161         | ECPGSetDescriptorHeader
162         {
163                 lookup_descriptor($1, connection);
164                 output_set_descr_header($1);
165                 free($1);
166         }
167         | ECPGTypedef
168         {
169                 if (connection)
170                         mmerror(PARSE_ERROR, ET_ERROR, "AT option not allowed in TYPE statement");
171
172                 fprintf(yyout, "%s", $1);
173                 free($1);
174                 output_line_number();
175         }
176         | ECPGVar
177         {
178                 if (connection)
179                         mmerror(PARSE_ERROR, ET_ERROR, "AT option not allowed in VAR statement");
180
181                 output_simple_statement($1);
182         }
183         | ECPGWhenever
184         {
185                 if (connection)
186                         mmerror(PARSE_ERROR, ET_ERROR, "AT option not allowed in WHENEVER statement");
187
188                 output_simple_statement($1);
189         }
190 ECPG: where_or_current_clauseWHERECURRENT_POFcursor_name block
191         {
192                 char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
193                 $$ = cat_str(2,mm_strdup("where current of"), cursor_marker);
194         }
195 ECPG: CopyStmtCOPYopt_binaryqualified_nameopt_column_listopt_oidscopy_fromcopy_file_namecopy_delimiteropt_withcopy_options addon
196                         if (strcmp($6, "to") == 0 && strcmp($7, "stdin") == 0)
197                                 mmerror(PARSE_ERROR, ET_ERROR, "COPY TO STDIN is not possible");
198                         else if (strcmp($6, "from") == 0 && strcmp($7, "stdout") == 0)
199                                 mmerror(PARSE_ERROR, ET_ERROR, "COPY FROM STDOUT is not possible");
200                         else if (strcmp($6, "from") == 0 && strcmp($7, "stdin") == 0)
201                                 mmerror(PARSE_ERROR, ET_WARNING, "COPY FROM STDIN is not implemented");
202 ECPG: CopyStmtCOPYselect_with_parensTOcopy_file_nameopt_withcopy_options addon
203                         if (strcmp($4, "stdin") == 0)
204                                 mmerror(PARSE_ERROR, ET_ERROR, "COPY TO STDIN is not possible");
205 ECPG: var_valueNumericOnly addon
206                 if ($1[0] == '$')
207                 {
208                         free($1);
209                         $1 = mm_strdup("$0");
210                 }
211 ECPG: fetch_argscursor_name addon
212                 add_additional_variables($1, false);
213                 if ($1[0] == ':')
214                 {
215                         free($1);
216                         $1 = mm_strdup("$0");
217                 }
218 ECPG: fetch_argsfrom_incursor_name addon
219                 add_additional_variables($2, false);
220                 if ($2[0] == ':')
221                 {
222                         free($2);
223                         $2 = mm_strdup("$0");
224                 }
225 ECPG: fetch_argsNEXTopt_from_incursor_name addon
226 ECPG: fetch_argsPRIORopt_from_incursor_name addon
227 ECPG: fetch_argsFIRST_Popt_from_incursor_name addon
228 ECPG: fetch_argsLAST_Popt_from_incursor_name addon
229 ECPG: fetch_argsALLopt_from_incursor_name addon
230                 add_additional_variables($3, false);
231                 if ($3[0] == ':')
232                 {
233                         free($3);
234                         $3 = mm_strdup("$0");
235                 }
236 ECPG: fetch_argsSignedIconstopt_from_incursor_name addon
237                 add_additional_variables($3, false);
238                 if ($3[0] == ':')
239                 {
240                         free($3);
241                         $3 = mm_strdup("$0");
242                 }
243                 if ($1[0] == '$')
244                 {
245                         free($1);
246                         $1 = mm_strdup("$0");
247                 }
248 ECPG: fetch_argsFORWARDALLopt_from_incursor_name addon
249 ECPG: fetch_argsBACKWARDALLopt_from_incursor_name addon
250                 add_additional_variables($4, false);
251                 if ($4[0] == ':')
252                 {
253                         free($4);
254                         $4 = mm_strdup("$0");
255                 }
256 ECPG: fetch_argsABSOLUTE_PSignedIconstopt_from_incursor_name addon
257 ECPG: fetch_argsRELATIVE_PSignedIconstopt_from_incursor_name addon
258 ECPG: fetch_argsFORWARDSignedIconstopt_from_incursor_name addon
259 ECPG: fetch_argsBACKWARDSignedIconstopt_from_incursor_name addon
260                 add_additional_variables($4, false);
261                 if ($4[0] == ':')
262                 {
263                         free($4);
264                         $4 = mm_strdup("$0");
265                 }
266                 if ($2[0] == '$')
267                 {
268                         free($2);
269                         $2 = mm_strdup("$0");
270                 }
271 ECPG: cursor_namename rule
272         | char_civar
273                 {
274                         char *curname = mm_alloc(strlen($1) + 2);
275                         sprintf(curname, ":%s", $1);
276                         free($1);
277                         $1 = curname;
278                         $$ = $1;
279                 }
280 ECPG: PrepareStmtPREPAREprepared_nameprep_type_clauseASPreparableStmt block
281         {
282                 $$.name = $2;
283                 $$.type = $3;
284                 $$.stmt = cat_str(3, mm_strdup("\""), $5, mm_strdup("\""));
285         }
286         | PREPARE prepared_name FROM execstring
287         {
288                 $$.name = $2;
289                 $$.type = NULL;
290                 $$.stmt = $4;
291         }
292 ECPG: ExecuteStmtEXECUTEprepared_nameexecute_param_clauseexecute_rest block
293         { $$ = $2; }
294 ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectStmt block
295         {
296                 struct cursor *ptr, *this;
297                 char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : mm_strdup($2);
298                 char *comment, *c1, *c2;
299                 int (* strcmp_fn)(const char *, const char *) = ($2[0] == ':' ? strcmp : pg_strcasecmp);
300
301                 for (ptr = cur; ptr != NULL; ptr = ptr->next)
302                 {
303                         if (strcmp_fn($2, ptr->name) == 0)
304                         {
305                                 if ($2[0] == ':')
306                                         mmerror(PARSE_ERROR, ET_ERROR, "using variable \"%s\" in different declare statements is not supported", $2+1);
307                                 else
308                                         mmerror(PARSE_ERROR, ET_ERROR, "cursor \"%s\" is already defined", $2);
309                         }
310                 }
311
312                 this = (struct cursor *) mm_alloc(sizeof(struct cursor));
313
314                 this->next = cur;
315                 this->name = $2;
316                 this->function = (current_function ? mm_strdup(current_function) : NULL);
317                 this->connection = connection;
318                 this->opened = false;
319                 this->command =  cat_str(7, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for"), $7);
320                 this->argsinsert = argsinsert;
321                 this->argsinsert_oos = NULL;
322                 this->argsresult = argsresult;
323                 this->argsresult_oos = NULL;
324                 argsinsert = argsresult = NULL;
325                 cur = this;
326
327                 c1 = mm_strdup(this->command);
328                 if ((c2 = strstr(c1, "*/")) != NULL)
329                 {
330                         /* We put this text into a comment, so we better remove [*][/]. */
331                         c2[0] = '.';
332                         c2[1] = '.';
333                 }
334                 comment = cat_str(3, mm_strdup("/*"), c1, mm_strdup("*/"));
335
336                 if ((braces_open > 0) && INFORMIX_MODE) /* we're in a function */
337                         $$ = cat_str(3, adjust_outofscope_cursor_vars(this),
338                                 mm_strdup("ECPG_informix_reset_sqlca();"),
339                                 comment);
340                 else
341                         $$ = cat2_str(adjust_outofscope_cursor_vars(this), comment);
342         }
343 ECPG: ClosePortalStmtCLOSEcursor_name block
344         {
345                 char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : $2;
346                 $$ = cat2_str(mm_strdup("close"), cursor_marker);
347         }
348 ECPG: opt_hold block
349         {
350                 if (compat == ECPG_COMPAT_INFORMIX_SE && autocommit)
351                         $$ = mm_strdup("with hold");
352                 else
353                         $$ = EMPTY;
354         }
355 ECPG: into_clauseINTOOptTempTableName block
356                                         {
357                                                 FoundInto = 1;
358                                                 $$= cat2_str(mm_strdup("into"), $2);
359                                         }
360         | ecpg_into { $$ = EMPTY; }
361 ECPG: table_refselect_with_parensopt_alias_clause addon
362         if ($2 == NULL)
363                 mmerror(PARSE_ERROR, ET_ERROR, "subquery in FROM must have an alias");
364 ECPG: table_refLATERAL_Pselect_with_parensopt_alias_clause addon
365         if ($3 == NULL)
366                 mmerror(PARSE_ERROR, ET_ERROR, "subquery in FROM must have an alias");
367 ECPG: TypenameSimpleTypenameopt_array_bounds block
368         {       $$ = cat2_str($1, $2.str); }
369 ECPG: TypenameSETOFSimpleTypenameopt_array_bounds block
370         {       $$ = cat_str(3, mm_strdup("setof"), $2, $3.str); }
371 ECPG: opt_array_boundsopt_array_bounds'['']' block
372         {
373                 $$.index1 = $1.index1;
374                 $$.index2 = $1.index2;
375                 if (strcmp($$.index1, "-1") == 0)
376                         $$.index1 = mm_strdup("0");
377                 else if (strcmp($1.index2, "-1") == 0)
378                         $$.index2 = mm_strdup("0");
379                 $$.str = cat_str(2, $1.str, mm_strdup("[]"));
380         }
381         | opt_array_bounds '[' Iresult ']'
382         {
383                 $$.index1 = $1.index1;
384                 $$.index2 = $1.index2;
385                 if (strcmp($1.index1, "-1") == 0)
386                         $$.index1 = strdup($3);
387                 else if (strcmp($1.index2, "-1") == 0)
388                         $$.index2 = strdup($3);
389                 $$.str = cat_str(4, $1.str, mm_strdup("["), $3, mm_strdup("]"));
390         }
391 ECPG: opt_array_bounds
392         {
393                 $$.index1 = mm_strdup("-1");
394                 $$.index2 = mm_strdup("-1");
395                 $$.str= EMPTY;
396         }
397 ECPG: IconstICONST block
398         { $$ = make_name(); }
399 ECPG: AexprConstNULL_P rule
400         | civar                 { $$ = $1; }
401         | civarind              { $$ = $1; }
402 ECPG: ColIdcol_name_keyword rule
403         | ECPGKeywords                  { $$ = $1; }
404         | ECPGCKeywords                 { $$ = $1; }
405         | CHAR_P                        { $$ = mm_strdup("char"); }
406         | VALUES                        { $$ = mm_strdup("values"); }
407 ECPG: type_function_nametype_func_name_keyword rule
408         | ECPGKeywords                          { $$ = $1; }
409         | ECPGTypeName                          { $$ = $1; }
410         | ECPGCKeywords                         { $$ = $1; }
411 ECPG: VariableShowStmtSHOWALL block
412         {
413                 mmerror(PARSE_ERROR, ET_ERROR, "SHOW ALL is not implemented");
414                 $$ = EMPTY;
415         }
416 ECPG: FetchStmtMOVEfetch_args rule
417         | FETCH fetch_args ecpg_fetch_into
418         {
419                 $$ = cat2_str(mm_strdup("fetch"), $2);
420         }
421         | FETCH FORWARD cursor_name opt_ecpg_fetch_into
422         {
423                 char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
424                 add_additional_variables($3, false);
425                 $$ = cat_str(2, mm_strdup("fetch forward"), cursor_marker);
426         }
427         | FETCH FORWARD from_in cursor_name opt_ecpg_fetch_into
428         {
429                 char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
430                 add_additional_variables($4, false);
431                 $$ = cat_str(2, mm_strdup("fetch forward from"), cursor_marker);
432         }
433         | FETCH BACKWARD cursor_name opt_ecpg_fetch_into
434         {
435                 char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
436                 add_additional_variables($3, false);
437                 $$ = cat_str(2, mm_strdup("fetch backward"), cursor_marker);
438         }
439         | FETCH BACKWARD from_in cursor_name opt_ecpg_fetch_into
440         {
441                 char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
442                 add_additional_variables($4, false);
443                 $$ = cat_str(2, mm_strdup("fetch backward from"), cursor_marker);
444         }
445         | MOVE FORWARD cursor_name
446         {
447                 char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
448                 add_additional_variables($3, false);
449                 $$ = cat_str(2, mm_strdup("move forward"), cursor_marker);
450         }
451         | MOVE FORWARD from_in cursor_name
452         {
453                 char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
454                 add_additional_variables($4, false);
455                 $$ = cat_str(2, mm_strdup("move forward from"), cursor_marker);
456         }
457         | MOVE BACKWARD cursor_name
458         {
459                 char *cursor_marker = $3[0] == ':' ? mm_strdup("$0") : $3;
460                 add_additional_variables($3, false);
461                 $$ = cat_str(2, mm_strdup("move backward"), cursor_marker);
462         }
463         | MOVE BACKWARD from_in cursor_name
464         {
465                 char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
466                 add_additional_variables($4, false);
467                 $$ = cat_str(2, mm_strdup("move backward from"), cursor_marker);
468         }
469 ECPG: limit_clauseLIMITselect_limit_value','select_offset_value block
470         {
471                 mmerror(PARSE_ERROR, ET_WARNING, "no longer supported LIMIT #,# syntax passed to server");
472                 $$ = cat_str(4, mm_strdup("limit"), $2, mm_strdup(","), $4);
473         }
474 ECPG: SignedIconstIconst rule
475         | civar { $$ = $1; }