CUBRID Engine  latest
esql_translate.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * esql_translate.c - translate ESQL statements into sequences of
21  * CUBRID CLI function calls.
22  */
23 
24 #ident "$Id$"
25 
26 #include "config.h"
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include "language_support.h"
30 #include "misc_string.h"
31 #include "util_func.h"
32 #include "dbi.h"
33 #include "esql_translate.h"
34 #include "memory_alloc.h"
35 #include "esql_misc.h"
36 
37 /* the following definition is subject to changes of cubrid_esql.h which defines
38  * stuffs directly exported to users. ESQL_FILE_ID_VAR_NAME is the
39  * name of static variable which all user's esql C program should have.
40  * NOT_FOUND_MACRO_NAME is the macro definition name of SQL_NOT_FOUND
41  * in cubrid_esql.h. WARN_CHAR_MACRO_NAME is the macro definition name of
42  * SQL_WARNING_CHAR in cubrid_esql.h.
43  *
44  * NOTE: Be sure to make these definition consistent with the cubrid_esql.h file.
45  */
46 #define ESQL_FILE_ID_VAR_NAME "uci_esqlxc_file"
47 #define NOT_FOUND_MACRO_NAME "SQL_NOT_FOUND"
48 #define WARN_CHAR_MACRO_NAME "SQL_WARNING_CHAR"
49 
50 /* to assign a unique statement number to repetitive ordinary statements and
51  * dynamic statements.
52  */
53 #define REPETITIVE_SERIAL_NO (repetitive_no++)
54 #define FP c_out_stream
55 
56 /* WHENEVER action descriptor structure */
57 typedef struct when_desc
58 {
59  WHEN_ACTION action; /* action number */
60  const char *name; /* label or procedure name */
61 } WHEN_DESC;
62 
63 static int repetitive_no = 0; /* serial number for repititive stmt */
64 
65 /* C source file output stream */
66 static FILE *c_out_stream;
67 
68 /* Line termination; default is to string everything onto one line. */
69 static const char *NL = " ";
70 
71 /* WHENEVER action descriptors */
72 static WHEN_DESC on_warning = { CONTINUE, (char *) NULL };
73 static WHEN_DESC on_error = { CONTINUE, (char *) NULL };
74 static WHEN_DESC on_not_found = { CONTINUE, (char *) NULL };
75 
76 static void emit_start (int leading_brace);
77 static void emit_end (void);
78 static void get_quasi_string (HOST_REF * ref, const char **buf_str, const char **bufsize_str);
79 static void tr_connect (HOST_REF * db_name, HOST_REF * user_name, HOST_REF * passwd);
80 static void tr_disconnect (void);
81 static void tr_commit (void);
82 static void tr_rollback (void);
83 static void tr_static (const char *stmt, int length, bool repeat, int num_in_vars, HOST_REF * in_vars,
84  const char *in_desc_name, int num_out_vars, HOST_REF * out_vars, const char *out_desc_name);
85 static void tr_open_cs (int cs_no, const char *stmt, int length, int stmt_no, bool readonly, int num_in_vars,
86  HOST_REF * in_vars, const char *desc_name);
87 static void tr_fetch_cs (int cs_no, int num_out_vars, HOST_REF * out_vars, const char *desc_name);
88 static void tr_update_cs (int cs_no, const char *text, int length, bool repetitive, int num_in_vars,
89  HOST_REF * in_vars);
90 static void tr_delete_cs (int cs_no);
91 static void tr_close_cs (int cs_no);
92 static void tr_prepare_esql (int stmt_no, HOST_REF * stmt);
93 static void tr_describe (int stmt_no, const char *desc_name);
94 static void tr_execute (int stmt_no, int num_in_vars, HOST_REF * in_vars, const char *in_desc_name, int num_out_vars,
95  HOST_REF * out_vars, const char *out_desc_name);
96 static void tr_execute_immediate (HOST_REF * stmt);
97 static void tr_object_describe (HOST_REF * obj, int num_attrs, const char **attr_names, const char *desc_name);
98 static void tr_object_fetch (HOST_REF * obj, int num_attrs, const char **attr_names, int num_out_vars,
99  HOST_REF * out_vars, const char *desc_name);
100 static void tr_object_update (const char *set_expr, int length, bool repetitive, int num_in_vars, HOST_REF * in_vars);
101 static void tr_whenever (WHEN_CONDITION condition, WHEN_ACTION action, const char *name);
102 static void tr_set_out_stream (FILE * out_stream);
103 static void tr_set_line_terminator (const char *);
104 
105 static void emit_put_db_value (HOST_REF * host);
106 static void emit_get_db_value (int cs_no, HOST_REF * host);
107 static void tr_print_n_string (char *stmt, int length);
108 static void emit_whenever (void);
109 static char *escape_string (const char *, int length, int *counter);
110 
111 static const char *c_type_to_db_type_c[] = {
112  "DB_TYPE_C_SHORT",
113  "DB_TYPE_C_INT",
114  "DB_TYPE_C_LONG",
115  "DB_TYPE_C_FLOAT",
116  "DB_TYPE_C_DOUBLE",
117  "DB_TYPE_C_CHAR",
118  "DB_TYPE_C_CHAR",
119  "DB_TYPE_C_OBJECT",
120  "DB_TYPE_C_SET", /* Probably ought to be collection */
121  "DB_TYPE_C_SET", /* Probably ought to be collection */
122  "DB_TYPE_C_SET", /* Probably ought to be collection */
123  "DB_TYPE_C_SET", /* Probably ought to be collection */
124  "DB_TYPE_C_TIME",
125  "DB_TYPE_C_TIMESTAMP",
126  "DB_TYPE_C_DATE",
127  "DB_TYPE_C_MONETARY",
128  "", /* DB_VALUE; what to do? */
129  "DB_TYPE_C_VARCHAR",
130  "DB_TYPE_C_BIT",
131  "DB_TYPE_C_VARBIT",
132  "DB_TYPE_C_NCHAR",
133  "DB_TYPE_C_VARNCHAR",
134  "DB_TYPE_C_STRING_CONST",
135  "DB_TYPE_C_SQLDA",
136  "DB_TYPE_C_BIGINT",
137  ""
138 };
139 
140 enum esql_msg /* Message codes for esql.msg */
141 {
143 };
144 
146  tr_connect,
148  tr_commit,
149  tr_rollback,
150  tr_static,
151  tr_open_cs,
152  tr_fetch_cs,
153  tr_update_cs,
154  tr_delete_cs,
155  tr_close_cs,
157  tr_describe,
158  tr_execute,
163  tr_whenever,
166 };
167 
168 /*
169  * emit_start() -
170  * return:
171  * leading_brace(in) :
172  */
173 static void
174 emit_start (int leading_brace)
175 {
176  if (leading_brace)
177  {
178  fprintf (FP, "{ ");
179  }
180  fprintf (FP, "uci_start((void *)&%s, __FILE__, __LINE__, 0x%04x); %s", ESQL_FILE_ID_VAR_NAME, pp_uci_opt, NL);
182 }
183 
184 /*
185  * emit_end() -
186  * return:
187  */
188 static void
189 emit_end (void)
190 {
191  fprintf (FP, " uci_end();%s", NL);
193  emit_whenever ();
194  fprintf (FP, "}%s", NL);
195 }
196 
197 /*
198  * get_quasi_string() -
199  * return: void
200  * ref(in) :
201  * buf_str(out) :
202  * bufsize_str(in) :
203  */
204 static void
205 get_quasi_string (HOST_REF * ref, const char **buf_str, const char **bufsize_str)
206 {
207  /*
208  * Take any host variable that can legitimately act as a string
209  * "constant" for input purposes, and return strings to expressions
210  * that describe the start of the char buffer and the length of the
211  * char buffer.
212  */
213  switch (pp_get_type (ref))
214  {
215  case C_TYPE_VARCHAR:
216  case C_TYPE_NCHAR:
217  case C_TYPE_VARNCHAR:
218  {
219  *buf_str = pp_get_addr_expr (ref);
220  *bufsize_str = pp_get_input_size (ref);
221  }
222  break;
223 
224  case C_TYPE_CHAR_ARRAY:
225  case C_TYPE_CHAR_POINTER:
226  case C_TYPE_STRING_CONST:
227  {
228  *buf_str = pp_get_expr (ref);
229  *bufsize_str = pp_get_input_size (ref);
230  }
231  break;
232 
233  default:
234  {
235  esql_yyverror (pp_get_msg (EX_TRANS_SET, MSG_BAD_CASE), "emit_prepare");
236  *buf_str = "NULL";
237  *bufsize_str = "0";
238  }
239  break;
240  }
241 }
242 
243 /*
244  * tr_connect() - emit code to connect to the speficied database using
245  * the given user information. `user_name' can be NULL to indicate
246  * current user's login name. If 'user_name' is NULL, `passwd' has
247  * no meaning. if `passwd' is NULL the empty passwd is assumed
248  * return : void
249  * db_name(in) - pointer to symbol desc of database name
250  * user_name(in) - pointer to symbol desc of user name
251  * passwd(in) - pointer to symbol desc of passwd
252  */
253 static void
254 tr_connect (HOST_REF * db_name, HOST_REF * user_name, HOST_REF * passwd)
255 {
256  const char *buf_str;
257  const char *bufsize_str;
258 
259  emit_start (1);
260 
261  /*
262  * Notice that the code we're emitting here is ignoring buffer lengths,
263  * so it's not going to fare well with embedded nulls. This probably
264  * isn't much of a practical concern, since the strings we're coping
265  * with here are external names and such, and probably have to be
266  * null-terminated anyway.
267  */
269  {
270  fprintf (FP, "fprintf(stderr, \"uci_connect(%%s, %%s, %%s)\\n\", ");
271  get_quasi_string (db_name, &buf_str, &bufsize_str);
272  fprintf (FP, "%s, ", buf_str);
273  if (user_name == NULL)
274  {
275  fprintf (FP, " \"(char *)0\", \"(char *)0\"); %s", NL);
276  }
277  else
278  {
279  get_quasi_string (user_name, &buf_str, &bufsize_str);
280  fprintf (FP, " %s, ", buf_str);
281  if (passwd == NULL)
282  {
283  fprintf (FP, " \"(char *)0\"); %s", NL);
284  }
285  else
286  {
287  get_quasi_string (passwd, &buf_str, &bufsize_str);
288  fprintf (FP, " %s); %s", buf_str, NL);
289  }
290  }
291  }
292  get_quasi_string (db_name, &buf_str, &bufsize_str);
293  fprintf (FP, " uci_connect(%s, ", buf_str);
294  if (user_name == NULL)
295  {
296  fprintf (FP, "(char *)0, (char *)0);%s", NL);
298  }
299  else
300  {
301  get_quasi_string (user_name, &buf_str, &bufsize_str);
302  fprintf (FP, "%s, ", buf_str);
303  if (passwd == NULL)
304  {
305  fprintf (FP, "(char *)0);%s", NL);
307  }
308  else
309  {
310  get_quasi_string (passwd, &buf_str, &bufsize_str);
311  fprintf (FP, "%s);%s", buf_str, NL);
313  }
314  }
315 
316  emit_end ();
317 }
318 
319 /*
320  * tr_disconnect() - Emit the code to disconnect from the current database
321  * return : void
322  */
323 static void
325 {
326  emit_start (1);
327  fprintf (FP, " uci_disconnect();%s", NL);
329  emit_end ();
330 }
331 
332 /*
333  * tr_commit() - Emit the code to commit the current transaction.
334  * return : void
335  */
336 static void
337 tr_commit (void)
338 {
339  emit_start (1);
341  {
342  fprintf (FP, "fprintf(stderr, \"uci_commit()\\n\"); %s", NL);
343  }
344  fprintf (FP, " uci_commit();%s", NL);
346  emit_end ();
347 }
348 
349 /*
350  * tr_rollback() - emit the code to rollback the current transaction.
351  * return : none
352  */
353 static void
355 {
356  emit_start (1);
358  {
359  fprintf (FP, "fprintf(stderr, \"uci_rollback()\\n\"); %s", NL);
360  }
361  fprintf (FP, " uci_rollback();%s", NL);
363  emit_end ();
364 }
365 
366 /*
367  * tr_static() - emit codes to execute the given statements.
368  *
369  * return/side-effects: none
370  * stmt(in) : pointer to statement string
371  * length(in) : length of stmt
372  * repetitive(in) : whether the stmt is repetitive or not
373  * num_in_vars(in) : # of input variables
374  * in_vars(in) : array of pointers to input variable descriptions
375  * in_desc_name(in) : descriptor name if given
376  * num_out_vars(in) : # of output variables
377  * out_vars(in) : array of pointerss to output variable descriptions
378  * out_desc_name(in) : descriptor name if given
379  */
380 static void
381 tr_static (const char *stmt, int length, bool repetitive, int num_in_vars, HOST_REF * in_vars, const char *in_desc_name,
382  int num_out_vars, HOST_REF * out_vars, const char *out_desc_name)
383 {
384  int i;
385  int counter = 0;
386  char *temp = escape_string (stmt, length, &counter);
387 
388  emit_start (1);
389 
390  if (num_in_vars > 0)
391  {
392  for (i = 0; i < num_in_vars; i++)
393  {
394  emit_put_db_value (&in_vars[i]);
395  }
396  }
397  else if (in_desc_name != NULL)
398  {
399  fprintf (FP, " uci_put_descriptor(%s);%s", in_desc_name, NL);
401  }
402 
403  /* emit uci function */
405  {
406  fprintf (FP, "fprintf(stderr, " "\"uci_static(%%d, \\\"%%s\\\", %%ld, %%d)\\n\", %d, \"",
407  (repetitive) ? REPETITIVE_SERIAL_NO : -1);
408  tr_print_n_string (temp, length + counter);
409  fprintf (FP, "\", %ld, %d); %s", (long) length, (num_out_vars <= 0) ? -1 : num_out_vars, NL);
410  }
411  fprintf (FP, " uci_static(%d, \"", (repetitive) ? REPETITIVE_SERIAL_NO : -1);
412  tr_print_n_string (temp, length + counter);
413  fprintf (FP, "\", %ld, %d);%s", (long) length, (num_out_vars <= 0) ? -1 : num_out_vars, NL);
415 
416  if (temp != NULL)
417  {
418  free_and_init (temp);
419  }
420 
421  if (num_out_vars > 0)
422  {
423  for (i = 0; i < num_out_vars; i++)
424  {
425  emit_get_db_value (-1, &out_vars[i]);
426  }
427  }
428  else if (out_desc_name != NULL)
429  {
430  /* descriptor is given */
431  fprintf (FP, " uci_get_descriptor(-1, %s);%s", out_desc_name, NL);
433  }
434 
435  emit_end ();
436 }
437 
438 /*
439  * tr_print_n_string() - This function is intended to print a string which may
440  * contain one or more embedded NULL characters in it. It will print
441  * strings with length > 75 on multiple lines, breaking the line at the
442  * next comma.
443  * return : void
444  * stmt(in) : statement to be printed
445  * length(in) : length of statment to be printed
446  */
447 static void
448 tr_print_n_string (char *stmt, int length)
449 {
450  int ctr = 0;
451  bool need_newline = false;
452 
453  if (length == 0 || stmt == NULL)
454  {
455  return;
456  }
457 
458  for (ctr = 0; ctr < length; ctr++)
459  {
460  fputc (stmt[ctr], FP);
461  need_newline = need_newline || (ctr && !(ctr % 75));
462  if (need_newline && stmt[ctr] == ',')
463  {
464  fputc ('"', FP);
465  fputc ('\n', FP);
467  fputc ('"', FP);
468  need_newline = false;
469  }
470  }
471 }
472 
473 /*
474  * tr_open_cs() - emits codes to open a cursor.
475  *
476  * return : none
477  * cs_no(in) : cursor number
478  * stmt(in) : statement contents or prepared stmt name
479  * stmt_no(in) : prepared stmt number
480  * readonly(in) : flag for readonly cursor
481  * num_in_vars(in) : # of input variables
482  * in_vars(in) : array of input variable descriptions
483  * desc_name(in) : descriptor name if given
484  *
485  */
486 static void
487 tr_open_cs (int cs_no, const char *stmt, int length, int stmt_no, bool readonly, int num_in_vars, HOST_REF * in_vars,
488  const char *desc_name)
489 {
490  int i;
491  int counter = 0;
492  char *temp = escape_string (stmt, length, &counter);
493 
494  emit_start (1);
495 
496  if (num_in_vars > 0)
497  {
498  for (i = 0; i < num_in_vars; i++)
499  {
500  emit_put_db_value (in_vars + i);
501  }
502  }
503  else if (desc_name != NULL)
504  {
505  fprintf (FP, " uci_put_descriptor(%s);%s", desc_name, NL);
507  }
508 
509  /* emits uci function */
511  {
512  fprintf (FP, "fprintf(stderr," "\"uci_open_cs(%%d, \\\"%%s\\\", %%ld, %%d, %%d)\\n\", %d, ", cs_no);
513  if (stmt == NULL)
514  {
515  fprintf (FP, "\"(char *)0\", ");
516  }
517  else
518  {
519  fprintf (FP, "\"");
520  tr_print_n_string (temp, length + counter);
521  fprintf (FP, "\", ");
522  }
523  fprintf (FP, "%ld, %d, %d); %s", (long) length, stmt_no, readonly, NL);
524  }
525  fprintf (FP, " uci_open_cs(%d, ", cs_no);
526  if (stmt == NULL)
527  {
528  fprintf (FP, "(char *)0, ");
529  }
530  else
531  {
532  fprintf (FP, "\"");
533  tr_print_n_string (temp, length + counter);
534  fprintf (FP, "\", ");
535  }
536 
537  if (temp != NULL)
538  {
539  free_and_init (temp);
540  }
541 
542  fprintf (FP, "%ld, %d, %d);%s", (long) length, stmt_no, readonly, NL);
544 
545  emit_end ();
546 }
547 
548 /*
549  * tr_fetch_cs() - emits codes to fetch a cursor. `cs_name' should be declared
550  * prior to call this function. if `num_out_vars' is positive, it is assumed
551  * that a user specifies host variables, if it is not positive and
552  * 'desc_name' is not NULL, it is assumed that a user specifies
553  * a descriptor, if `num_out_vars' is not positive and `desc_name' is NULL,
554  * it is assumed that neither host variables nor descriptor is given
555  * (in most cases, it will cause run time warning).
556  *
557  * statement-coverage: FETCH statement
558  *
559  * return : none
560  * cs_no(in) : cursor number
561  * num_out_vars(in) : # of output variables
562  * out_vars(in) : array of output variable descriptions
563  * desc_name(in) : descriptor name if given
564  */
565 static void
566 tr_fetch_cs (int cs_no, int num_out_vars, HOST_REF * out_vars, const char *desc_name)
567 {
568  int i;
569 
570  emit_start (1);
571 
573  {
574  if (num_out_vars > 0)
575  {
576  fprintf (FP, "fprintf(stderr, \"uci_fetch_cs(%d, %d)\\n\"); %s", cs_no, num_out_vars, NL);
577  }
578  else if (desc_name != NULL)
579  {
580  fprintf (FP, "fprintf(stderr, " "\"uci_fetch_cs(%d, (%s)->sqldesc)\\n\"); %s", cs_no, desc_name, NL);
581  }
582  else
583  {
584  fprintf (FP, "fprintf(stderr, \"uci_fetch_cs(%%d, -1)\\n\", %d); %s", cs_no, NL);
585  }
586  }
587  if (num_out_vars > 0)
588  {
589  /* host variable is given */
590  fprintf (FP, " uci_fetch_cs(%d, %d);%s", cs_no, num_out_vars, NL);
592  for (i = 0; i < num_out_vars; i++)
593  {
594  emit_get_db_value (cs_no, out_vars + i);
595  }
596  }
597  else if (desc_name != NULL)
598  {
599  /* descriptor is given */
600  fprintf (FP, " uci_fetch_cs(%d, (%s)->sqldesc);%s", cs_no, desc_name, NL);
602  fprintf (FP, " uci_get_descriptor(%d, %s);%s", cs_no, desc_name, NL);
604  }
605  else
606  {
607  /* neither host var nor desc is given */
608  fprintf (FP, " uci_fetch_cs(%d, -1);%s", cs_no, NL);
610  }
611 
612  emit_end ();
613 }
614 
615 /*
616  * tr_update_cs() - emits the codes to update the current object of the
617  * cursor using the given set expression.
618  *
619  * statement-coverage: [REPEAT] UPDATE ...WHERE CURRENT OF cs_name
620  *
621  * return : none
622  * cs_no(in) : cursor id
623  * text(in) : update statement
624  * length(in) : length of text
625  * repetitive(in) :
626  * num_in_vars(in) : # of input host variables
627  * in_vars(in) : array of input host variables
628  *
629  * note : 'text' should NOT include WHERE CURRENT OF cs_name
630  */
631 static void
632 tr_update_cs (int cs_no, const char *text, int length, bool repetitive, int num_in_vars, HOST_REF * in_vars)
633 {
634  int i;
635 
636  emit_start (1);
637 
638  /* first emit the code to push the current object of the cursor */
639  fprintf (FP, " uci_psh_curr_csr_oid(%d);%s", cs_no, NL);
641 
642  if (num_in_vars > 0)
643  {
644  /* put variables in binding table */
645  for (i = 0; i < num_in_vars; i++)
646  {
647  emit_put_db_value (&in_vars[i]);
648  }
649  }
650 
651  /* emit uci function */
653  {
654  fprintf (FP, "fprintf(stderr, " "\"uci_static(%%d, \\\"%%s\\\", %%ld, 0)\\n\", %d, \"",
655  (repetitive) ? REPETITIVE_SERIAL_NO : -1);
656  tr_print_n_string ((char *) text, length);
657  fprintf (FP, "\", %ld); %s", (long) length, NL);
658  }
659  fprintf (FP, " uci_static(%d,\"", (repetitive) ? REPETITIVE_SERIAL_NO : -1);
660  tr_print_n_string ((char *) text, length);
661  fprintf (FP, "\", %ld, 0);%s", (long) length, NL);
663 
664  emit_end ();
665 }
666 
667 /*
668  * tr_delete_cs() - emit uci function call for delete cursor statement
669  * statement-coverage: DELETE FROM class_name WHERE CURRENT OF cs_name
670  * return : void
671  * cs_no(in) : cursor number
672  */
673 static void
674 tr_delete_cs (int cs_no)
675 {
676  emit_start (1);
677 
678  /* emit uci function */
680  {
681  fprintf (FP, "fprintf(stderr, \"uci_delete_cs(%d)\\n\"); %s", cs_no, NL);
682  }
683  fprintf (FP, " uci_delete_cs(%d);%s", cs_no, NL);
685 
686  emit_end ();
687 }
688 
689 /*
690  * tr_close_cs() - emits the codes to close the specified cursor
691  * statement-coverage: CLOSE cursor_name
692  * return : void
693  * cs_no(in) : cursor number
694  */
695 static void
696 tr_close_cs (int cs_no)
697 {
698  emit_start (1);
699 
701  {
702  fprintf (FP, "fprintf(stderr, \"uci_close_cs(%d)\\n\"); %s", cs_no, NL);
703  }
704  fprintf (FP, " uci_close_cs(%d);%s", cs_no, NL);
706 
707  emit_end ();
708 }
709 
710 /*
711  * tr_prepare_esql() - emits codes to prepare the given statement.
712  * statement-coverage: PREPARE statement
713  * return : void
714  * stmt_no(in) : statement number to be prepared
715  * stmt(in) : dynamic statement
716  */
717 static void
718 tr_prepare_esql (int stmt_no, HOST_REF * stmt)
719 {
720  const char *buf_str;
721  const char *bufsize_str;
722 
723  emit_start (1);
724 
725  /*
726  * The parser should have guaranteed that only a HOST_REF that smells
727  * like some sort of pseudo-string can get in here. Other types should
728  * be impossible.
729  */
730  get_quasi_string (stmt, &buf_str, &bufsize_str);
731 
732  /* emit uci function */
734  {
735  fprintf (FP, "fprintf(stderr, " "\"uci_prepare(%%d, \\\"%%s\\\", %%d)\\n\", %d, %s, %s); %s", stmt_no, buf_str,
736  bufsize_str, NL);
737  }
738  fprintf (FP, " uci_prepare(%d, %s, %s);%s", stmt_no, buf_str, bufsize_str, NL);
740 
741  emit_end ();
742 }
743 
744 /*
745  * tr_describe() - emits the codes to describe the result attributes of
746  * the prepared statement into the given descriptor.
747  * statement-coverage: DESCRIBE statement
748  * return : void
749  * stmt_no(in) : number of prepared statement
750  * desc_name(in) : name of descriptor variable
751  */
752 static void
753 tr_describe (int stmt_no, const char *desc_name)
754 {
755  emit_start (1);
756  fprintf (FP, " uci_describe(%d, %s);%s", stmt_no, desc_name, NL);
758  emit_end ();
759 }
760 
761 /*
762  * tr_execute() - emits the codes to execute the prepared dynamic stmt using
763  * host variables (if `num_in_vars' is positive) or descriptor
764  * (if 'num_in_vars' is not positive and 'out_desc_name' is not NULL).
765  * if 'num_in_vars' is not positive and 'out_desc_name' is NULL, it is
766  * assumed that there is not input values. output variables are also treated
767  * as the same way.
768  * statement-coverage: EXECUTE statement
769  * return : void
770  * stmt_no(in) : no of prepared statement
771  * num_in_vars(in) : # of input host variables
772  * in_vars(in) : array of input variable descriptions
773  * in_desc_name(in) : name of input descriptor variable
774  * num_out_vars(in) : # of output host variables
775  * out_vars(in) : array of output variable descriptions
776  * out_desc_name(in) : name of output descriptor variable
777  */
778 static void
779 tr_execute (int stmt_no, int num_in_vars, HOST_REF * in_vars, const char *in_desc_name, int num_out_vars,
780  HOST_REF * out_vars, const char *out_desc_name)
781 {
782  int i;
783 
784  emit_start (1);
785 
786  /* emit code to put var infor */
787  if (num_in_vars > 0)
788  {
789  for (i = 0; i < num_in_vars; i++)
790  {
791  emit_put_db_value (in_vars + i);
792  }
793  }
794  else if (in_desc_name != NULL)
795  {
796  /* descriptor is given */
797  fprintf (FP, " uci_put_descriptor(%s);%s", in_desc_name, NL);
799  }
800 
801  /* emit uci function */
803  {
804  if (num_out_vars > 0)
805  {
806  fprintf (FP, "fprintf(stderr, \"uci_execute(%d, %d)\\n\"); %s", stmt_no, num_out_vars, NL);
807  }
808  else if (out_desc_name != NULL)
809  {
810  fprintf (FP, "fprintf(stderr," " \"uci_execute(%d, (%s)->sqldesc)\\n\"); %s", stmt_no, out_desc_name, NL);
811  }
812  else
813  {
814  fprintf (FP, "fprintf(stderr, \"uci_execute(%d, -1)\\n\"); %s", stmt_no, NL);
815  }
816  }
817 
818  if (num_out_vars > 0)
819  {
820  /* output host variables are given */
821  fprintf (FP, " uci_execute(%d, %d);%s", stmt_no, num_out_vars, NL);
823  for (i = 0; i < num_out_vars; i++)
824  {
825  emit_get_db_value (-1, out_vars + i);
826  }
827  }
828  else if (out_desc_name != NULL)
829  {
830  /* descriptor is given */
831  fprintf (FP, " uci_execute(%d, (%s)->sqldesc);%s", stmt_no, out_desc_name, NL);
833  fprintf (FP, " uci_get_descriptor(-1, %s);%s", out_desc_name, NL);
835  }
836  else
837  {
838  fprintf (FP, " uci_execute(%d, -1);%s", stmt_no, NL);
840  }
841 
842  emit_end ();
843 }
844 
845 /*
846  * tr_execute_immediate() - emits the codes to execute the given statement
847  * immediately.
848  * statement-coverage: EXECUTE IMMEDIATE statement
849  * return : void
850  * stmt(in) : pointer to symbol tab entry describing the stmt to be executed
851  * immediately.
852  */
853 static void
855 {
856  const char *buf_str;
857  const char *bufsize_str;
858 
859  emit_start (1);
860  get_quasi_string (stmt, &buf_str, &bufsize_str);
862  {
863  fprintf (FP, "fprintf(stderr, " "\"uci_execute_immediate(\\\"%%s\\\", %%d)\\n\", %s, %s); %s", buf_str,
864  bufsize_str, NL);
865  }
866  fprintf (FP, " uci_execute_immediate(%s, %s);%s", buf_str, bufsize_str, NL);
868  emit_end ();
869 }
870 
871 /*
872  * tr_object_describe() - emits the codes to describe the given object on the
873  * given attributes
874  * statement-coverage: DESCRIBE OBJECT :obj ON attr INTO :desc
875  * return : void
876  * obj(in) : object id host variable reference
877  * num_attrs(in) : # of attribute names
878  * attr_names(in) : array of attribute name to be described
879  * desc_name(in) : SQLDA name to hold the description
880  *
881  * note: Caller should make sure the 'obj' refers to C_TYPE_OBJECTID.
882  */
883 static void
884 tr_object_describe (HOST_REF * obj, int num_attrs, const char **attr_names, const char *desc_name)
885 {
886  int i;
887 
888  fprintf (FP, "{%s", NL);
890 
891  if (num_attrs > 0)
892  {
893 #if defined(PRODUCE_ANSI_CODE)
894  fprintf (FP, " static const char *uci_attr_names[%d] = {", num_attrs);
895 #else
896  fprintf (FP, " static char *uci_attr_names[%d] = {", num_attrs);
897 #endif
898  for (i = 0; i < num_attrs; i++)
899  {
900  fprintf (FP, "%s\"%s\"", (i > 0 ? "," : ""), attr_names[i]);
901  }
902  fprintf (FP, "};%s", NL);
904  }
905 
906  emit_start (0);
907  fprintf (FP, " uci_object_describe(%s, %d, uci_attr_names, %s);%s", pp_get_expr (obj), num_attrs, desc_name, NL);
909 
910  emit_end ();
911 }
912 
913 /*
914  * tr_object_fetch() - emits the codes to fetch the specified attribute values
915  * of the given object into host variables or descriptor. If `num_out_vars'
916  * is positive, it is assumed that host variables are given in `out_vars'.
917  * Otherwise, if 'desc_name' is not NULL, it is assumed that a desc is
918  * given. Otherwise, no variable is assumed to be given to hold output.
919  * statement-coverage: FETCH OBJECT :obj ON attr ...
920  * return : void
921  * obj(in) : object id host variable reference
922  * num_attrs(in) : # of attribute names
923  * attr_names(in) : array of attribute name to be described
924  * num_out_vars(in) : # of output host variables
925  * out_vars(in) : array of output host variables
926  * desc_name(in) : SQLDA name if given
927  *
928  * note : Caller should make sure the `obj' refers to C_TYPE_OBJECTID.
929  */
930 static void
931 tr_object_fetch (HOST_REF * obj, int num_attrs, const char **attr_names, int num_out_vars, HOST_REF * out_vars,
932  const char *desc_name)
933 {
934  int i;
935 
936  fprintf (FP, "{%s", NL);
938 
939  if (num_attrs > 0)
940  {
941 #if defined(PRODUCE_ANSI_CODE)
942  fprintf (FP, " static const char *uci_attr_names[%d] = {", num_attrs);
943 #else
944  fprintf (FP, " static char *uci_attr_names[%d] = {", num_attrs);
945 #endif
946  for (i = 0; i < num_attrs; i++)
947  {
948  fprintf (FP, "%s\"%s\"", (i > 0 ? "," : ""), attr_names[i]);
949  }
950  fprintf (FP, "};%s", NL);
952  }
953 
954  emit_start (0); /* Leading brace already emitted */
955 
957  {
958  if (num_out_vars > 0)
959  {
960  fprintf (FP,
961  "fprintf(stderr, " "\"uci_object_fetch(%%s, %%d, uci_attr_names, %%d)\\n\"" ", \"%s\", %d, %d); %s",
962  pp_get_expr (obj), num_attrs, num_out_vars, NL);
963  }
964  else if (desc_name != NULL)
965  {
966  fprintf (FP,
967  "fprintf(stderr, " "\"uci_object_fetch(%%s, %%d, uci_attr_names, %%s)\\n\""
968  ", \"%s\", %d, \"(%s)->sqldesc\"); %s", pp_get_expr (obj), num_attrs, desc_name, NL);
969  }
970  else
971  {
972  fprintf (FP, "fprintf(stderr, " "\"uci_object_fetch(%%s, %%d, uci_attr_names, -1)\\n\"" ", \"%s\", %d); %s",
973  pp_get_expr (obj), num_attrs, NL);
974  }
975  }
976  if (num_out_vars > 0)
977  {
978  /* output host variables are given */
979  fprintf (FP, " uci_object_fetch(%s, %d, uci_attr_names, %d);%s", pp_get_expr (obj), num_attrs, num_out_vars, NL);
981  for (i = 0; i < num_out_vars; i++)
982  {
983  emit_get_db_value (-1, out_vars + i);
984  }
985  }
986  else if (desc_name != NULL)
987  {
988  /* descriptor is given */
989  fprintf (FP, " uci_object_fetch(%s, %d, uci_attr_names, (%s)->sqldesc);%s", pp_get_expr (obj), num_attrs,
990  desc_name, NL);
992  fprintf (FP, " uci_get_descriptor(-1, %s);%s", desc_name, NL);
994  }
995  else
996  {
997  fprintf (FP, " uci_object_fetch(%s, %d, uci_attr_names, -1);%s", pp_get_expr (obj), num_attrs, NL);
999  }
1000 
1001  emit_end ();
1002 }
1003 
1004 /*
1005  * tr_object_update() - emits the codes to update the object specified by 'obj'
1006  * using the given set expression.
1007  * statement-coverage: [REPEAT] UPDATE OBJECT :obj SET ...
1008  * return : void
1009  * set_expr(in) : string to have SET-clause
1010  * repetitive(in) : true if repetitive
1011  * num_in_vars(in) : # of input host variables
1012  * in_vars(in) : array of pointers to input host variables
1013  *
1014  * note : - Caller should make sure the `obj' refers to C_TYPE_OBJECTID.
1015  * - 'set_expr' should NOT include 'SET' keyword itself.
1016  */
1017 static void
1018 tr_object_update (const char *set_expr, int length, bool repetitive, int num_in_vars, HOST_REF * in_vars)
1019 {
1020  int i;
1021  int counter = 0;
1022  char *temp = escape_string (set_expr, length, &counter);
1023 
1024  emit_start (1);
1025 
1026  /* put variables in binding table */
1027  for (i = 0; i < num_in_vars; i++)
1028  {
1029  emit_put_db_value (&in_vars[i]);
1030  }
1031 
1032  /* emit uci function */
1033  if (pp_enable_uci_trace)
1034  {
1035  fprintf (FP, "fprintf(stderr, \"uci_static(%%d, \\\"%%s\\\", %%ld, 0)\\n\"" ", %d, \"",
1036  (repetitive) ? REPETITIVE_SERIAL_NO : -1);
1037  tr_print_n_string (temp, length + counter);
1038  fprintf (FP, "\", %ld); %s", (long) length, NL);
1039  }
1040 
1041  fprintf (FP, " uci_static(%d,\"", (repetitive) ? REPETITIVE_SERIAL_NO : -1);
1042  tr_print_n_string (temp, length + counter);
1043  fprintf (FP, "\",%ld, 0);%s", (long) length, NL);
1045 
1046  if (temp != NULL)
1047  {
1048  free_and_init (temp);
1049  }
1050 
1051  emit_end ();
1052 }
1053 
1054 /*
1055  * tr_whenever() - set action on specific condition. if 'condition' is
1056  * NOT_FOUND and 'action' is STOP, there is no effect.
1057  * return : void
1058  * condition(in) : whenever condition
1059  * action(in) : action on the condition
1060  * name(in) :label or procedure name
1061  */
1062 static void
1064 {
1065  WHEN_DESC *wd;
1066 
1067  switch (condition)
1068  {
1069  case SQLWARNING:
1070  wd = &on_warning;
1071  break;
1072  case SQLERROR:
1073  wd = &on_error;
1074  break;
1075  case NOT_FOUND:
1076  {
1077  if (action == STOP)
1078  {
1079  return;
1080  }
1081  wd = &on_not_found;
1082  }
1083  break;
1084  default:
1085  return;
1086  }
1087 
1088  wd->action = action;
1089  wd->name = name;
1090 }
1091 
1092 /*
1093  * tr_set_out_stream() - set the current ouput file stream to the given stream.
1094  * return : void
1095  * out_stream(in) : output file stream
1096  */
1097 static void
1098 tr_set_out_stream (FILE * out_stream)
1099 {
1100  c_out_stream = out_stream;
1101 }
1102 
1103 /*
1104  * tr_set_line_terminator() - set the line terminator string
1105  * return/side-effects: none
1106  * terminator(in) : string used to terminate each emitted line
1107  */
1108 static void
1109 tr_set_line_terminator (const char *terminator)
1110 {
1111  NL = terminator;
1112 }
1113 
1114 /*
1115  * emit_put_db_value() - emit uci_put_...() function according to the type
1116  * of the given host variable information.
1117  * return : void
1118  * host(in) : symbol table entry for host variable
1119  */
1120 static void
1122 {
1123  C_TYPE type;
1124  char *type_str = NULL;
1125  const char *prec_str = NULL;
1126  const char *scale_str = NULL;
1127  const char *ctype_str = NULL;
1128  const char *buf_str = NULL;
1129  const char *bufsize_str = NULL;
1130  const char *fmt = "db_col_type(%s)";
1131 
1132  fprintf (FP, " uci_put_value(%s, ", pp_get_ind_addr_expr (host));
1133 
1134  prec_str = "0";
1135  scale_str = "0";
1136  bufsize_str = "0";
1137 
1138  type = pp_get_type (host);
1139  switch (type)
1140  {
1141  case C_TYPE_SHORT:
1142  {
1143  type_str = (char *) "DB_TYPE_SHORT";
1144  ctype_str = "DB_TYPE_C_SHORT";
1145  buf_str = pp_get_addr_expr (host);
1146  }
1147  break;
1148 
1149  case C_TYPE_INTEGER:
1150  {
1151  type_str = (char *) "DB_TYPE_INTEGER";
1152  ctype_str = "DB_TYPE_C_INT";
1153  buf_str = pp_get_addr_expr (host);
1154  }
1155  break;
1156 
1157  case C_TYPE_BIGINT:
1158  {
1159  type_str = (char *) "DB_TYPE_BIGINT";
1160  ctype_str = "DB_TYPE_C_BITINT";
1161  buf_str = pp_get_addr_expr (host);
1162  }
1163  break;
1164 
1165  case C_TYPE_LONG:
1166  {
1167  type_str = (char *) "DB_TYPE_INTEGER";
1168  ctype_str = "DB_TYPE_C_LONG";
1169  buf_str = pp_get_addr_expr (host);
1170  }
1171  break;
1172 
1173  case C_TYPE_FLOAT:
1174  {
1175  type_str = (char *) "DB_TYPE_FLOAT";
1176  ctype_str = "DB_TYPE_C_FLOAT";
1177  buf_str = pp_get_addr_expr (host);
1178  }
1179  break;
1180 
1181  case C_TYPE_DOUBLE:
1182  {
1183  type_str = (char *) "DB_TYPE_DOUBLE";
1184  ctype_str = "DB_TYPE_C_DOUBLE";
1185  buf_str = pp_get_addr_expr (host);
1186  }
1187  break;
1188 
1189  case C_TYPE_VARCHAR:
1190  {
1191  type_str = (char *) "DB_TYPE_VARCHAR";
1192  ctype_str = "DB_TYPE_C_CHAR";
1193  prec_str = pp_get_precision (host);
1194  buf_str = pp_get_addr_expr (host);
1196  {
1197  bufsize_str = pp_get_input_size (host);
1198  }
1199  }
1200  break;
1201 
1202  case C_TYPE_CHAR_ARRAY:
1203  case C_TYPE_CHAR_POINTER:
1204  {
1205  type_str = (char *) "DB_TYPE_CHAR";
1206  ctype_str = "DB_TYPE_C_CHAR";
1207  prec_str = pp_get_precision (host);
1208  buf_str = pp_get_expr (host);
1209  bufsize_str = pp_get_input_size (host);
1210  }
1211  break;
1212 
1213  case C_TYPE_NCHAR:
1214  {
1215  type_str = (char *) "DB_TYPE_NCHAR";
1216  ctype_str = "DB_TYPE_C_NCHAR";
1217  prec_str = pp_get_precision (host);
1218  buf_str = pp_get_addr_expr (host);
1219  bufsize_str = pp_get_input_size (host);
1220  }
1221  break;
1222 
1223  case C_TYPE_VARNCHAR:
1224  {
1225  type_str = (char *) "DB_TYPE_VARNCHAR";
1226  ctype_str = "DB_TYPE_C_NCHAR";
1227  prec_str = pp_get_precision (host);
1228  buf_str = pp_get_addr_expr (host);
1230  {
1231  bufsize_str = pp_get_input_size (host);
1232  }
1233  }
1234  break;
1235 
1236  case C_TYPE_BIT:
1237  {
1238  type_str = (char *) "DB_TYPE_BIT";
1239  ctype_str = "DB_TYPE_C_BIT";
1240  prec_str = pp_get_precision (host);
1241  buf_str = pp_get_addr_expr (host);
1242  bufsize_str = pp_get_input_size (host);
1243  }
1244  break;
1245 
1246  case C_TYPE_VARBIT:
1247  {
1248  type_str = (char *) "DB_TYPE_VARBIT";
1249  ctype_str = "DB_TYPE_C_BIT";
1250  prec_str = pp_get_precision (host);
1251  buf_str = pp_get_addr_expr (host);
1252  bufsize_str = pp_get_input_size (host);
1253  }
1254  break;
1255 
1256  case C_TYPE_BASICSET:
1257  {
1258  type_str = (char *) "DB_TYPE_SET";
1259  ctype_str = "DB_TYPE_C_SET";
1260  buf_str = pp_get_addr_expr (host);
1261  }
1262  break;
1263 
1264  case C_TYPE_MULTISET:
1265  {
1266  type_str = (char *) "DB_TYPE_MULTISET";
1267  ctype_str = "DB_TYPE_C_SET";
1268  buf_str = pp_get_addr_expr (host);
1269  }
1270  break;
1271 
1272  case C_TYPE_SEQUENCE:
1273  {
1274  type_str = (char *) "DB_TYPE_SEQUENCE";
1275  ctype_str = "DB_TYPE_C_SET";
1276  buf_str = pp_get_addr_expr (host);
1277  }
1278  break;
1279 
1280  case C_TYPE_COLLECTION:
1281  {
1282  type_str = (char *) pp_malloc ((int) (sizeof (fmt) + strlen (pp_get_expr (host))));
1283  sprintf (type_str, fmt, pp_get_expr (host));
1284  ctype_str = "DB_TYPE_C_SET";
1285  buf_str = pp_get_addr_expr (host);
1286  }
1287  break;
1288 
1289  case C_TYPE_TIME:
1290  {
1291  type_str = (char *) "DB_TYPE_TIME";
1292  ctype_str = "DB_TYPE_C_TIME";
1293  buf_str = pp_get_addr_expr (host);
1294  bufsize_str = pp_get_input_size (host);
1295  }
1296  break;
1297 
1298  case C_TYPE_TIMESTAMP:
1299  {
1300  type_str = (char *) "DB_TYPE_TIMESTAMP";
1301  ctype_str = "DB_TYPE_C_TIMESTAMP";
1302  buf_str = pp_get_addr_expr (host);
1303  bufsize_str = pp_get_input_size (host);
1304  }
1305  break;
1306 
1307  case C_TYPE_DATE:
1308  {
1309  type_str = (char *) "DB_TYPE_DATE";
1310  ctype_str = "DB_TYPE_C_DATE";
1311  buf_str = pp_get_addr_expr (host);
1312  bufsize_str = pp_get_input_size (host);
1313  }
1314  break;
1315 
1316  case C_TYPE_MONETARY:
1317  {
1318  type_str = (char *) "DB_TYPE_MONETARY";
1319  ctype_str = "DB_TYPE_C_MONETARY";
1320  buf_str = pp_get_addr_expr (host);
1321  bufsize_str = pp_get_input_size (host);
1322  }
1323  break;
1324 
1325  case C_TYPE_OBJECTID:
1326  {
1327  type_str = (char *) "DB_TYPE_OBJECT";
1328  ctype_str = "DB_TYPE_C_OBJECT";
1329  buf_str = pp_get_addr_expr (host);
1330  }
1331  break;
1332 
1333  case C_TYPE_DB_VALUE:
1334  {
1335  type_str = (char *) "DB_TYPE_DB_VALUE";
1336  ctype_str = "0";
1337  buf_str = pp_get_addr_expr (host);
1338  }
1339  break;
1340 
1341  case C_TYPE_STRING_CONST:
1342  case C_TYPE_SQLDA:
1343  case NUM_C_TYPES:
1344  {
1345  /*
1346  * These cases should be impossible.
1347  */
1348  esql_yyverror (pp_get_msg (EX_TRANS_SET, MSG_BAD_CASE), "emit_put_db_value");
1349  type_str = (char *) "DB_TYPE_UNKNOWN";
1350  ctype_str = "0";
1351  buf_str = "NULL";
1352  }
1353  break;
1354  }
1355 
1356  fprintf (FP, "%s, %s, %s, %s, %s, %s);%s", type_str, prec_str, scale_str, ctype_str, buf_str, bufsize_str, NL);
1358 
1359  if (type == C_TYPE_COLLECTION)
1360  {
1361  free ((void *) type_str);
1362  }
1363 }
1364 
1365 /*
1366  * emit_get_db_value() - emit uci_get_db_value() function according to
1367  * the type of the given host variable information.
1368  * return : void
1369  * cs_no(in) : cursor no to identify result
1370  * host(in) : symbol table entry for host variable
1371  */
1372 static void
1373 emit_get_db_value (int cs_no, HOST_REF * host)
1374 {
1375  C_TYPE ctype;
1376 
1377  ctype = pp_get_type (host);
1378 
1379  if (ctype == C_TYPE_DB_VALUE)
1380  {
1381  fprintf (FP, " uci_get_db_value(%d, %s);%s", cs_no, pp_get_addr_expr (host), NL);
1383  return;
1384  }
1385  /*
1386  * Since the various calls to pp_get_<whatever> tend to share common
1387  * scratch areas, putting all of them in one giant fprintf() will
1388  * create havoc. It's safer to sequence the calls through separate
1389  * calls to fprintf().
1390  */
1391  ctype = pp_get_type (host);
1392  fprintf (FP, " uci_get_value(%d, %s, ", cs_no, pp_get_ind_addr_expr (host));
1393  fprintf (FP, "(void *)(%s), ", pp_get_addr_expr (host));
1394  fprintf (FP, "%s, ", c_type_to_db_type_c[ctype]);
1395  fprintf (FP, "(int)(%s), ", pp_get_output_size (host));
1396  if (ctype == C_TYPE_VARCHAR || ctype == C_TYPE_VARNCHAR || ctype == C_TYPE_VARBIT)
1397  {
1398  fprintf (FP, "&%s", pp_get_input_size (host));
1399  }
1400  else
1401  {
1402  fprintf (FP, "NULL");
1403  }
1404  fprintf (FP, ");%s", NL);
1406 }
1407 
1408 /*
1409  * emit_whenever() - emit codes to process whenever action. if more than
1410  * condition is true, action is occurred by the following order:
1411  * NOT_FOUND > SQLERROR > SQLWARNING.
1412  * return : void
1413  */
1414 static void
1416 {
1417  /* for not_found */
1418  if (on_not_found.action != CONTINUE)
1419  {
1420  fprintf (FP, " if(uci_get_sqlcode () == %s) ", NOT_FOUND_MACRO_NAME);
1421  switch (on_not_found.action)
1422  {
1423  case GOTO:
1424  {
1425  fprintf (FP, "goto %s;%s", on_not_found.name, NL);
1427  }
1428  break;
1429  case CALL:
1430  {
1431  fprintf (FP, "%s();%s", on_not_found.name, NL);
1433  }
1434  break;
1435  default:
1436  break;
1437  }
1438  }
1439 
1440  /* for errors */
1441  if (on_error.action != CONTINUE)
1442  {
1443  fprintf (FP, " if(uci_get_sqlcode () < 0) ");
1444  switch (on_error.action)
1445  {
1446  case STOP:
1447  {
1448  if (pp_enable_uci_trace)
1449  {
1450  fprintf (FP, "fprintf(stderr, \"uci_stop()\\n\"); %s", NL);
1451  }
1452  fprintf (FP, "uci_stop();%s", NL);
1454  }
1455  break;
1456  case GOTO:
1457  {
1458  fprintf (FP, "goto %s;%s", on_error.name, NL);
1460  }
1461  break;
1462  case CALL:
1463  {
1464  fprintf (FP, "%s();%s", on_error.name, NL);
1466  }
1467  break;
1468  default:
1469  break;
1470  }
1471  }
1472 
1473  /* for warnings */
1474  if (on_warning.action != CONTINUE)
1475  {
1476  fprintf (FP, " if(uci_get_sqlwarn_0 () == %s) ", WARN_CHAR_MACRO_NAME);
1477  switch (on_warning.action)
1478  {
1479  case STOP:
1480  {
1481  if (pp_enable_uci_trace)
1482  {
1483  fprintf (FP, "fprintf(stderr, \"uci_stop()\\n\"); %s", NL);
1484  }
1485  fprintf (FP, "uci_stop();%s", NL);
1487  }
1488  break;
1489  case GOTO:
1490  {
1491  fprintf (FP, "goto %s;%s", on_warning.name, NL);
1493  }
1494  break;
1495  case CALL:
1496  {
1497  fprintf (FP, "%s();%s", on_warning.name, NL);
1499  }
1500  break;
1501  default:
1502  break;
1503  }
1504  }
1505 }
1506 
1507 /*
1508  * escape_string() - copies the input string and escapes ("\") quotes, single
1509  * quotes, null, and backslashes.
1510  * return : char *
1511  * in_str(in) :
1512  * length(in) :
1513  * counter(out) :
1514  *
1515  * note : calling routine must free the string when through.
1516  */
1517 static char *
1518 escape_string (const char *in_str, int length, int *counter)
1519 {
1520  char *out_str = NULL;
1521  char *temp;
1522  char *end = (char *) in_str + length - 1;
1523  int add_count;
1524  char temp_buffer[1024];
1525 
1526 
1527  if (in_str == NULL)
1528  {
1529  return NULL;
1530  }
1531 
1532  add_count = 0;
1533  /*
1534  * Need four times the size of the input string since this is the
1535  * max size the out string could be.
1536  */
1537  if (length * 4 + 1 <= 1024)
1538  {
1539  out_str = temp_buffer;
1540  }
1541  else
1542  {
1543  out_str = (char *) pp_malloc (length * 4 + 1);
1544  }
1545  temp = out_str;
1546 
1547  while (in_str <= end)
1548  {
1549  /*
1550  * If input char is double quote,single quote, escape char, newline
1551  * of form feed, precede it by an escape character in the emitted
1552  * string
1553  */
1554  if ((*in_str == '"') || (*in_str == '\'') || (*in_str == '\\') || (*in_str == '\n') || (*in_str == '\f'))
1555  {
1556 
1557  *temp = '\\';
1558  temp++;
1559  add_count++;
1560  }
1561 
1562  /*
1563  * If input char is the null character, then replace it with
1564  * escape char 000 (octal 0) in the emitted string so that
1565  * the 'C' compilers will not choke on an unescaped null char
1566  * in string literals.
1567  */
1568  if (*in_str == '\000')
1569  {
1570  *temp = '\\';
1571  temp++;
1572 
1573  *temp = '0';
1574  temp++;
1575 
1576  *temp = '0';
1577  temp++;
1578 
1579  *temp = '0';
1580  temp++;
1581 
1582  /* Increment string addition counter */
1583  add_count += 3;
1584 
1585  /* Skip over (now replaced) null char in input string. */
1586  in_str++;
1587  }
1588  else
1589  {
1590  /*
1591  * Emit current char.
1592  * Increment input string pointer by 1.
1593  * Increment output string pointer by 1.
1594  */
1595  *temp = *in_str;
1596  temp++;
1597  in_str++;
1598  }
1599  }
1600 
1601  *temp = '\0';
1602  if (out_str == temp_buffer)
1603  {
1604  int sz = (int) (temp - out_str) + 1;
1605 
1606  out_str = (char *) pp_malloc (sz);
1607  memcpy (out_str, temp_buffer, sz);
1608  }
1609  *counter = add_count;
1610 
1611  return out_str;
1612 }
static void emit_end(void)
static void tr_delete_cs(int cs_no)
static const char * c_type_to_db_type_c[]
static void tr_static(const char *stmt, int length, bool repeat, int num_in_vars, HOST_REF *in_vars, const char *in_desc_name, int num_out_vars, HOST_REF *out_vars, const char *out_desc_name)
static int repetitive_no
static void emit_put_db_value(HOST_REF *host)
static void emit_start(int leading_brace)
static void tr_set_line_terminator(const char *)
static void tr_execute_immediate(HOST_REF *stmt)
ESQL_TRANSLATE_TABLE esql_Translate_table
static void tr_object_update(const char *set_expr, int length, bool repetitive, int num_in_vars, HOST_REF *in_vars)
static void emit_whenever(void)
static const char * NL
#define WARN_CHAR_MACRO_NAME
static void tr_rollback(void)
static void tr_print_n_string(char *stmt, int length)
static void tr_disconnect(void)
void esql_yyverror(const char *,...)
static void tr_object_fetch(HOST_REF *obj, int num_attrs, const char **attr_names, int num_out_vars, HOST_REF *out_vars, const char *desc_name)
static void emit_get_db_value(int cs_no, HOST_REF *host)
char * pp_get_ind_addr_expr(HOST_REF *ref)
#define REPETITIVE_SERIAL_NO
static void tr_connect(HOST_REF *db_name, HOST_REF *user_name, HOST_REF *passwd)
const char * pp_get_msg(int msg_set, int msg_num)
static void tr_describe(int stmt_no, const char *desc_name)
static void tr_commit(void)
void * pp_malloc(int n)
Definition: esql_misc.c:353
char * pp_get_expr(HOST_REF *ref)
WHEN_ACTION action
const char * name
static void tr_execute(int stmt_no, int num_in_vars, HOST_REF *in_vars, const char *in_desc_name, int num_out_vars, HOST_REF *out_vars, const char *out_desc_name)
#define ESQL_FILE_ID_VAR_NAME
static void tr_open_cs(int cs_no, const char *stmt, int length, int stmt_no, bool readonly, int num_in_vars, HOST_REF *in_vars, const char *desc_name)
static void tr_whenever(WHEN_CONDITION condition, WHEN_ACTION action, const char *name)
enum when_action WHEN_ACTION
#define NOT_FOUND_MACRO_NAME
static void tr_prepare_esql(int stmt_no, HOST_REF *stmt)
static void tr_update_cs(int cs_no, const char *text, int length, bool repetitive, int num_in_vars, HOST_REF *in_vars)
static void tr_object_describe(HOST_REF *obj, int num_attrs, const char **attr_names, const char *desc_name)
#define NULL
Definition: freelistheap.h:34
unsigned int pp_uci_opt
static FILE * c_out_stream
#define FP
char * db_name
static void get_quasi_string(HOST_REF *ref, const char **buf_str, const char **bufsize_str)
void emit_line_directive(void)
static WHEN_DESC on_not_found
char * pp_get_output_size(HOST_REF *ref)
static void tr_close_cs(int cs_no)
enum when_condition WHEN_CONDITION
esql_msg
char * pp_get_input_size(HOST_REF *ref)
static char * escape_string(const char *, int length, int *counter)
#define free_and_init(ptr)
Definition: memory_alloc.h:147
#define strlen(s1)
Definition: intl_support.c:43
static void tr_set_out_stream(FILE *out_stream)
struct when_desc WHEN_DESC
C_TYPE pp_get_type(HOST_REF *ref)
int i
Definition: dynamic_load.c:954
static WHEN_DESC on_error
char * pp_get_addr_expr(HOST_REF *ref)
enum c_pype C_TYPE
char * pp_get_precision(HOST_REF *ref)
static void tr_fetch_cs(int cs_no, int num_out_vars, HOST_REF *out_vars, const char *desc_name)
static char * host
int pp_disable_varchar_length
int pp_enable_uci_trace
static WHEN_DESC on_warning