PostgreSQL Source Code  git master
type.c
Go to the documentation of this file.
1 /* src/interfaces/ecpg/preproc/type.c */
2 
3 #include "postgres_fe.h"
4 
5 #include "preproc_extern.h"
6 
7 #define indicator_set ind_type != NULL && ind_type->type != ECPGt_NO_INDICATOR
8 
9 static struct ECPGstruct_member struct_no_indicator = {"no_indicator", &ecpg_no_indicator, NULL};
10 
11 /* malloc + error check */
12 void *
13 mm_alloc(size_t size)
14 {
15  void *ptr = malloc(size);
16 
17  if (ptr == NULL)
18  mmfatal(OUT_OF_MEMORY, "out of memory");
19 
20  return ptr;
21 }
22 
23 /* strdup + error check */
24 char *
25 mm_strdup(const char *string)
26 {
27  char *new = strdup(string);
28 
29  if (new == NULL)
30  mmfatal(OUT_OF_MEMORY, "out of memory");
31 
32  return new;
33 }
34 
35 /* duplicate memberlist */
36 struct ECPGstruct_member *
38 {
39  struct ECPGstruct_member *new = NULL;
40 
41  while (rm)
42  {
43  struct ECPGtype *type;
44 
45  switch (rm->type->type)
46  {
47  case ECPGt_struct:
48  case ECPGt_union:
50  break;
51  case ECPGt_array:
52 
53  /*
54  * if this array does contain a struct again, we have to
55  * create the struct too
56  */
57  if (rm->type->u.element->type == ECPGt_struct || rm->type->u.element->type == ECPGt_union)
59  else
61  break;
62  default:
63  type = ECPGmake_simple_type(rm->type->type, rm->type->size, rm->type->counter);
64  break;
65  }
66 
67  ECPGmake_struct_member(rm->name, type, &new);
68 
69  rm = rm->next;
70  }
71 
72  return new;
73 }
74 
75 /* The NAME argument is copied. The type argument is preserved as a pointer. */
76 void
77 ECPGmake_struct_member(const char *name, struct ECPGtype *type, struct ECPGstruct_member **start)
78 {
79  struct ECPGstruct_member *ptr,
80  *ne =
81  (struct ECPGstruct_member *) mm_alloc(sizeof(struct ECPGstruct_member));
82 
83  ne->name = mm_strdup(name);
84  ne->type = type;
85  ne->next = NULL;
86 
87  for (ptr = *start; ptr && ptr->next; ptr = ptr->next);
88 
89  if (ptr)
90  ptr->next = ne;
91  else
92  *start = ne;
93 }
94 
95 struct ECPGtype *
97 {
98  struct ECPGtype *ne = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
99 
100  ne->type = type;
101  ne->type_name = NULL;
102  ne->size = size;
103  ne->u.element = NULL;
104  ne->struct_sizeof = NULL;
105  ne->counter = counter; /* only needed for varchar and bytea */
106 
107  return ne;
108 }
109 
110 struct ECPGtype *
112 {
113  struct ECPGtype *ne = ECPGmake_simple_type(ECPGt_array, size, 0);
114 
115  ne->u.element = type;
116 
117  return ne;
118 }
119 
120 struct ECPGtype *
122 {
123  struct ECPGtype *ne = ECPGmake_simple_type(type, mm_strdup("1"), 0);
124 
126  ne->u.members = ECPGstruct_member_dup(rm);
128 
129  return ne;
130 }
131 
132 static const char *
134 {
135  switch (type)
136  {
137  case ECPGt_char:
138  return "ECPGt_char";
139  break;
140  case ECPGt_unsigned_char:
141  return "ECPGt_unsigned_char";
142  break;
143  case ECPGt_short:
144  return "ECPGt_short";
145  break;
147  return "ECPGt_unsigned_short";
148  break;
149  case ECPGt_int:
150  return "ECPGt_int";
151  break;
152  case ECPGt_unsigned_int:
153  return "ECPGt_unsigned_int";
154  break;
155  case ECPGt_long:
156  return "ECPGt_long";
157  break;
158  case ECPGt_unsigned_long:
159  return "ECPGt_unsigned_long";
160  break;
161  case ECPGt_long_long:
162  return "ECPGt_long_long";
163  break;
165  return "ECPGt_unsigned_long_long";
166  break;
167  case ECPGt_float:
168  return "ECPGt_float";
169  break;
170  case ECPGt_double:
171  return "ECPGt_double";
172  break;
173  case ECPGt_bool:
174  return "ECPGt_bool";
175  break;
176  case ECPGt_varchar:
177  return "ECPGt_varchar";
178  case ECPGt_bytea:
179  return "ECPGt_bytea";
180  case ECPGt_NO_INDICATOR: /* no indicator */
181  return "ECPGt_NO_INDICATOR";
182  break;
183  case ECPGt_char_variable: /* string that should not be quoted */
184  return "ECPGt_char_variable";
185  break;
186  case ECPGt_const: /* constant string quoted */
187  return "ECPGt_const";
188  break;
189  case ECPGt_decimal:
190  return "ECPGt_decimal";
191  break;
192  case ECPGt_numeric:
193  return "ECPGt_numeric";
194  break;
195  case ECPGt_interval:
196  return "ECPGt_interval";
197  break;
198  case ECPGt_descriptor:
199  return "ECPGt_descriptor";
200  break;
201  case ECPGt_sqlda:
202  return "ECPGt_sqlda";
203  break;
204  case ECPGt_date:
205  return "ECPGt_date";
206  break;
207  case ECPGt_timestamp:
208  return "ECPGt_timestamp";
209  break;
210  case ECPGt_string:
211  return "ECPGt_string";
212  break;
213  default:
214  mmerror(PARSE_ERROR, ET_ERROR, "unrecognized variable type code %d", type);
215  }
216 
217  return NULL;
218 }
219 
220 /* Dump a type.
221  The type is dumped as:
222  type-tag <comma> - enum ECPGttype
223  reference-to-variable <comma> - char *
224  size <comma> - long size of this field (if varchar)
225  arrsize <comma> - long number of elements in the arr
226  offset <comma> - offset to the next element
227  Where:
228  type-tag is one of the simple types or varchar.
229  reference-to-variable can be a reference to a struct element.
230  arrsize is the size of the array in case of array fetches. Otherwise 0.
231  size is the maxsize in case it is a varchar. Otherwise it is the size of
232  the variable (required to do array fetches of structs).
233  */
234 static void ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
235  char *varcharsize,
236  char *arrsize, const char *size, const char *prefix, int counter);
237 static void ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, char *arrsize,
238  struct ECPGtype *type, struct ECPGtype *ind_type, const char *prefix, const char *ind_prefix);
239 
240 void
241 ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype *type, const int brace_level,
242  const char *ind_name, struct ECPGtype *ind_type, const int ind_brace_level,
243  const char *prefix, const char *ind_prefix,
244  char *arr_str_size, const char *struct_sizeof,
245  const char *ind_struct_sizeof)
246 {
247  struct variable *var;
248 
249  if (type->type != ECPGt_descriptor && type->type != ECPGt_sqlda &&
250  type->type != ECPGt_char_variable && type->type != ECPGt_const &&
251  brace_level >= 0)
252  {
253  char *str;
254 
255  str = mm_strdup(name);
256  var = find_variable(str);
257  free(str);
258 
259  if ((var->type->type != type->type) ||
260  (var->type->type_name && !type->type_name) ||
261  (!var->type->type_name && type->type_name) ||
262  (var->type->type_name && type->type_name && strcmp(var->type->type_name, type->type_name) != 0))
263  mmerror(PARSE_ERROR, ET_ERROR, "variable \"%s\" is hidden by a local variable of a different type", name);
264  else if (var->brace_level != brace_level)
265  mmerror(PARSE_ERROR, ET_WARNING, "variable \"%s\" is hidden by a local variable", name);
266 
267  if (ind_name && ind_type && ind_type->type != ECPGt_NO_INDICATOR && ind_brace_level >= 0)
268  {
269  str = mm_strdup(ind_name);
270  var = find_variable(str);
271  free(str);
272 
273  if ((var->type->type != ind_type->type) ||
274  (var->type->type_name && !ind_type->type_name) ||
275  (!var->type->type_name && ind_type->type_name) ||
276  (var->type->type_name && ind_type->type_name && strcmp(var->type->type_name, ind_type->type_name) != 0))
277  mmerror(PARSE_ERROR, ET_ERROR, "indicator variable \"%s\" is hidden by a local variable of a different type", ind_name);
278  else if (var->brace_level != ind_brace_level)
279  mmerror(PARSE_ERROR, ET_WARNING, "indicator variable \"%s\" is hidden by a local variable", ind_name);
280  }
281  }
282 
283  switch (type->type)
284  {
285  case ECPGt_array:
286  if (indicator_set && ind_type->type != ECPGt_array)
287  mmfatal(INDICATOR_NOT_ARRAY, "indicator for array/pointer has to be array/pointer");
288  switch (type->u.element->type)
289  {
290  case ECPGt_array:
291  mmerror(PARSE_ERROR, ET_ERROR, "nested arrays are not supported (except strings)"); /* array of array */
292  break;
293  case ECPGt_struct:
294  case ECPGt_union:
296  ind_name,
297  type->size,
298  type->u.element,
299  (ind_type == NULL) ? NULL : ((ind_type->type == ECPGt_NO_INDICATOR) ? ind_type : ind_type->u.element),
300  prefix, ind_prefix);
301  break;
302  default:
303  if (!IS_SIMPLE_TYPE(type->u.element->type))
304  base_yyerror("internal error: unknown datatype, please report this to <" PACKAGE_BUGREPORT ">");
305 
307  type->u.element->type,
308  type->u.element->size, type->size, struct_sizeof ? struct_sizeof : NULL,
309  prefix, type->u.element->counter);
310 
311  if (ind_type != NULL)
312  {
313  if (ind_type->type == ECPGt_NO_INDICATOR)
314  {
315  char *str_neg_one = mm_strdup("-1");
316 
317  ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, str_neg_one, NULL, ind_prefix, 0);
318  free(str_neg_one);
319  }
320  else
321  {
322  ECPGdump_a_simple(o, ind_name, ind_type->u.element->type,
323  ind_type->u.element->size, ind_type->size, NULL, ind_prefix, 0);
324  }
325  }
326  }
327  break;
328  case ECPGt_struct:
329  {
330  char *str_one = mm_strdup("1");
331 
332  if (indicator_set && ind_type->type != ECPGt_struct)
333  mmfatal(INDICATOR_NOT_STRUCT, "indicator for struct has to be a struct");
334 
335  ECPGdump_a_struct(o, name, ind_name, str_one, type, ind_type, prefix, ind_prefix);
336  free(str_one);
337  }
338  break;
339  case ECPGt_union: /* cannot dump a complete union */
340  base_yyerror("type of union has to be specified");
341  break;
342  case ECPGt_char_variable:
343  {
344  /*
345  * Allocate for each, as there are code-paths where the values
346  * get stomped on.
347  */
348  char *str_varchar_one = mm_strdup("1");
349  char *str_arr_one = mm_strdup("1");
350  char *str_neg_one = mm_strdup("-1");
351 
352  if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
353  mmfatal(INDICATOR_NOT_SIMPLE, "indicator for simple data type has to be simple");
354 
355  ECPGdump_a_simple(o, name, type->type, str_varchar_one, (arr_str_size && strcmp(arr_str_size, "0") != 0) ? arr_str_size : str_arr_one, struct_sizeof, prefix, 0);
356  if (ind_type != NULL)
357  ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, (arr_str_size && strcmp(arr_str_size, "0") != 0) ? arr_str_size : str_neg_one, ind_struct_sizeof, ind_prefix, 0);
358 
359  free(str_varchar_one);
360  free(str_arr_one);
361  free(str_neg_one);
362  }
363  break;
364  case ECPGt_descriptor:
365  {
366  /*
367  * Allocate for each, as there are code-paths where the values
368  * get stomped on.
369  */
370  char *str_neg_one = mm_strdup("-1");
371  char *ind_type_neg_one = mm_strdup("-1");
372 
373  if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
374  mmfatal(INDICATOR_NOT_SIMPLE, "indicator for simple data type has to be simple");
375 
376  ECPGdump_a_simple(o, name, type->type, NULL, str_neg_one, NULL, prefix, 0);
377  if (ind_type != NULL)
378  ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, ind_type_neg_one, NULL, ind_prefix, 0);
379 
380  free(str_neg_one);
381  free(ind_type_neg_one);
382  }
383  break;
384  default:
385  {
386  /*
387  * Allocate for each, as there are code-paths where the values
388  * get stomped on.
389  */
390  char *str_neg_one = mm_strdup("-1");
391  char *ind_type_neg_one = mm_strdup("-1");
392 
393  if (indicator_set && (ind_type->type == ECPGt_struct || ind_type->type == ECPGt_array))
394  mmfatal(INDICATOR_NOT_SIMPLE, "indicator for simple data type has to be simple");
395 
396  ECPGdump_a_simple(o, name, type->type, type->size, (arr_str_size && strcmp(arr_str_size, "0") != 0) ? arr_str_size : str_neg_one, struct_sizeof, prefix, type->counter);
397  if (ind_type != NULL)
398  ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, (arr_str_size && strcmp(arr_str_size, "0") != 0) ? arr_str_size : ind_type_neg_one, ind_struct_sizeof, ind_prefix, 0);
399 
400  free(str_neg_one);
401  free(ind_type_neg_one);
402  }
403  break;
404  }
405 }
406 
407 
408 /* If size is NULL, then the offset is 0, if not use size as a
409  string, it represents the offset needed if we are in an array of structs. */
410 static void
411 ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
412  char *varcharsize,
413  char *arrsize,
414  const char *size,
415  const char *prefix,
416  int counter)
417 {
418  if (type == ECPGt_NO_INDICATOR)
419  fprintf(o, "\n\tECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ");
420  else if (type == ECPGt_descriptor)
421  /* remember that name here already contains quotes (if needed) */
422  fprintf(o, "\n\tECPGt_descriptor, %s, 1L, 1L, 1L, ", name);
423  else if (type == ECPGt_sqlda)
424  fprintf(o, "\n\tECPGt_sqlda, &%s, 0L, 0L, 0L, ", name);
425  else
426  {
427  char *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4);
428  char *offset = (char *) mm_alloc(strlen(name) + strlen("sizeof(struct varchar_)") + 1 + strlen(varcharsize) + sizeof(int) * CHAR_BIT * 10 / 3);
429  char *struct_name;
430 
431  switch (type)
432  {
433  /*
434  * we have to use the & operator except for arrays and
435  * pointers
436  */
437 
438  case ECPGt_varchar:
439  case ECPGt_bytea:
440 
441  /*
442  * we have to use the pointer except for arrays with given
443  * bounds
444  */
445  if (((atoi(arrsize) > 0) ||
446  (atoi(arrsize) == 0 && strcmp(arrsize, "0") != 0)) &&
447  size == NULL)
448  sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
449  else
450  sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
451 
452  /*
453  * If we created a varchar structure automatically, counter is
454  * greater than 0.
455  */
456  if (type == ECPGt_varchar)
457  struct_name = "struct varchar";
458  else
459  struct_name = "struct bytea";
460 
461  if (counter)
462  sprintf(offset, "sizeof(%s_%d)", struct_name, counter);
463  else
464  sprintf(offset, "sizeof(%s)", struct_name);
465  break;
466  case ECPGt_char:
467  case ECPGt_unsigned_char:
468  case ECPGt_char_variable:
469  case ECPGt_string:
470  {
471  char *sizeof_name = "char";
472 
473  /*
474  * we have to use the pointer except for arrays with given
475  * bounds, ecpglib will distinguish between * and []
476  */
477  if ((atoi(varcharsize) > 1 ||
478  (atoi(arrsize) > 0) ||
479  (atoi(varcharsize) == 0 && strcmp(varcharsize, "0") != 0) ||
480  (atoi(arrsize) == 0 && strcmp(arrsize, "0") != 0))
481  && size == NULL)
482  {
483  sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
484  if ((type == ECPGt_char || type == ECPGt_unsigned_char) &&
485  strcmp(varcharsize, "0") == 0)
486  {
487  /*
488  * If this is an array of char *, the offset would
489  * be sizeof(char *) and not sizeof(char).
490  */
491  sizeof_name = "char *";
492  }
493  }
494  else
495  sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
496 
497  sprintf(offset, "(%s)*sizeof(%s)", strcmp(varcharsize, "0") == 0 ? "1" : varcharsize, sizeof_name);
498  break;
499  }
500  case ECPGt_numeric:
501 
502  /*
503  * we have to use a pointer here
504  */
505  sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
506  sprintf(offset, "sizeof(numeric)");
507  break;
508  case ECPGt_interval:
509 
510  /*
511  * we have to use a pointer here
512  */
513  sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
514  sprintf(offset, "sizeof(interval)");
515  break;
516  case ECPGt_date:
517 
518  /*
519  * we have to use a pointer and translate the variable type
520  */
521  sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
522  sprintf(offset, "sizeof(date)");
523  break;
524  case ECPGt_timestamp:
525 
526  /*
527  * we have to use a pointer and translate the variable type
528  */
529  sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
530  sprintf(offset, "sizeof(timestamp)");
531  break;
532  case ECPGt_const:
533 
534  /*
535  * just dump the const as string
536  */
537  sprintf(variable, "\"%s\"", name);
538  sprintf(offset, "strlen(\"%s\")", name);
539  break;
540  default:
541 
542  /*
543  * we have to use the pointer except for arrays with given
544  * bounds
545  */
546  if (((atoi(arrsize) > 0) ||
547  (atoi(arrsize) == 0 && strcmp(arrsize, "0") != 0)) &&
548  size == NULL)
549  sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
550  else
551  sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
552 
553  sprintf(offset, "sizeof(%s)", ecpg_type_name(type));
554  break;
555  }
556 
557  /*
558  * Array size would be -1 for addresses of members within structure,
559  * when pointer to structure is being dumped.
560  */
561  if (atoi(arrsize) < 0 && !size)
562  strcpy(arrsize, "1");
563 
564  /*
565  * If size i.e. the size of structure of which this variable is part
566  * of, that gives the offset to the next element, if required
567  */
568  if (size == NULL || strlen(size) == 0)
569  fprintf(o, "\n\t%s,%s,(long)%s,(long)%s,%s, ", get_type(type), variable, varcharsize, arrsize, offset);
570  else
571  fprintf(o, "\n\t%s,%s,(long)%s,(long)%s,%s, ", get_type(type), variable, varcharsize, arrsize, size);
572 
573  free(variable);
574  free(offset);
575  }
576 }
577 
578 
579 /* Penetrate a struct and dump the contents. */
580 static void
581 ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, char *arrsize, struct ECPGtype *type, struct ECPGtype *ind_type, const char *prefix, const char *ind_prefix)
582 {
583  /*
584  * If offset is NULL, then this is the first recursive level. If not then
585  * we are in a struct and the offset is used as offset.
586  */
587  struct ECPGstruct_member *p,
588  *ind_p = NULL;
589  char *pbuf = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 3);
590  char *ind_pbuf = (char *) mm_alloc(strlen(ind_name) + ((ind_prefix == NULL) ? 0 : strlen(ind_prefix)) + 3);
591 
592  if (atoi(arrsize) == 1)
593  sprintf(pbuf, "%s%s.", prefix ? prefix : "", name);
594  else
595  sprintf(pbuf, "%s%s->", prefix ? prefix : "", name);
596 
597  prefix = pbuf;
598 
599  if (ind_type == &ecpg_no_indicator)
600  ind_p = &struct_no_indicator;
601  else if (ind_type != NULL)
602  {
603  if (atoi(arrsize) == 1)
604  sprintf(ind_pbuf, "%s%s.", ind_prefix ? ind_prefix : "", ind_name);
605  else
606  sprintf(ind_pbuf, "%s%s->", ind_prefix ? ind_prefix : "", ind_name);
607 
608  ind_prefix = ind_pbuf;
609  ind_p = ind_type->u.members;
610  }
611 
612  for (p = type->u.members; p; p = p->next)
613  {
614  ECPGdump_a_type(o, p->name, p->type, -1,
615  (ind_p != NULL) ? ind_p->name : NULL,
616  (ind_p != NULL) ? ind_p->type : NULL,
617  -1,
618  prefix, ind_prefix, arrsize, type->struct_sizeof,
619  (ind_p != NULL) ? ind_type->struct_sizeof : NULL);
620  if (ind_p != NULL && ind_p != &struct_no_indicator)
621  {
622  ind_p = ind_p->next;
623  if (ind_p == NULL && p->next != NULL)
624  {
625  mmerror(PARSE_ERROR, ET_WARNING, "indicator struct \"%s\" has too few members", ind_name);
626  ind_p = &struct_no_indicator;
627  }
628  }
629  }
630 
631  if (ind_type != NULL && ind_p != NULL && ind_p != &struct_no_indicator)
632  {
633  mmerror(PARSE_ERROR, ET_WARNING, "indicator struct \"%s\" has too many members", ind_name);
634  }
635 
636  free(pbuf);
637  free(ind_pbuf);
638 }
639 
640 void
642 {
643  while (rm)
644  {
645  struct ECPGstruct_member *p = rm;
646 
647  rm = rm->next;
648  free(p->name);
649  free(p->type);
650  free(p);
651  }
652 }
653 
654 void
656 {
657  if (!IS_SIMPLE_TYPE(type->type))
658  {
659  switch (type->type)
660  {
661  case ECPGt_array:
662  switch (type->u.element->type)
663  {
664  case ECPGt_array:
665  base_yyerror("internal error: found multidimensional array\n");
666  break;
667  case ECPGt_struct:
668  case ECPGt_union:
669  /* Array of structs. */
670  ECPGfree_struct_member(type->u.element->u.members);
671  free(type->u.element);
672  break;
673  default:
674  if (!IS_SIMPLE_TYPE(type->u.element->type))
675  base_yyerror("internal error: unknown datatype, please report this to <" PACKAGE_BUGREPORT ">");
676 
677  free(type->u.element);
678  }
679  break;
680  case ECPGt_struct:
681  case ECPGt_union:
682  ECPGfree_struct_member(type->u.members);
683  break;
684  default:
685  mmerror(PARSE_ERROR, ET_ERROR, "unrecognized variable type code %d", type->type);
686  break;
687  }
688  }
689  free(type);
690 }
691 
692 const char *
694 {
695  switch (type)
696  {
697  case ECPGd_count:
698  return "ECPGd_count";
699  break;
700  case ECPGd_data:
701  return "ECPGd_data";
702  break;
703  case ECPGd_di_code:
704  return "ECPGd_di_code";
705  break;
706  case ECPGd_di_precision:
707  return "ECPGd_di_precision";
708  break;
709  case ECPGd_indicator:
710  return "ECPGd_indicator";
711  break;
712  case ECPGd_key_member:
713  return "ECPGd_key_member";
714  break;
715  case ECPGd_length:
716  return "ECPGd_length";
717  break;
718  case ECPGd_name:
719  return "ECPGd_name";
720  break;
721  case ECPGd_nullable:
722  return "ECPGd_nullable";
723  break;
724  case ECPGd_octet:
725  return "ECPGd_octet";
726  break;
727  case ECPGd_precision:
728  return "ECPGd_precision";
729  break;
730  case ECPGd_ret_length:
731  return "ECPGd_ret_length";
732  case ECPGd_ret_octet:
733  return "ECPGd_ret_octet";
734  break;
735  case ECPGd_scale:
736  return "ECPGd_scale";
737  break;
738  case ECPGd_type:
739  return "ECPGd_type";
740  break;
741  case ECPGd_cardinality:
742  return "ECPGd_cardinality";
743  default:
744  mmerror(PARSE_ERROR, ET_ERROR, "unrecognized descriptor item code %d", type);
745  }
746 
747  return NULL;
748 }
const char * ecpg_type_name(enum ECPGttype typ)
Definition: typename.c:17
ECPGttype
Definition: ecpgtype.h:42
@ ECPGt_float
Definition: ecpgtype.h:47
@ ECPGt_long_long
Definition: ecpgtype.h:45
@ ECPGt_sqlda
Definition: ecpgtype.h:66
@ ECPGt_short
Definition: ecpgtype.h:43
@ ECPGt_decimal
Definition: ecpgtype.h:51
@ ECPGt_char_variable
Definition: ecpgtype.h:60
@ ECPGt_bytea
Definition: ecpgtype.h:67
@ ECPGt_numeric
Definition: ecpgtype.h:49
@ ECPGt_union
Definition: ecpgtype.h:58
@ ECPGt_varchar
Definition: ecpgtype.h:48
@ ECPGt_struct
Definition: ecpgtype.h:57
@ ECPGt_timestamp
Definition: ecpgtype.h:54
@ ECPGt_unsigned_short
Definition: ecpgtype.h:43
@ ECPGt_int
Definition: ecpgtype.h:44
@ ECPGt_long
Definition: ecpgtype.h:44
@ ECPGt_unsigned_char
Definition: ecpgtype.h:43
@ ECPGt_double
Definition: ecpgtype.h:47
@ ECPGt_array
Definition: ecpgtype.h:56
@ ECPGt_NO_INDICATOR
Definition: ecpgtype.h:64
@ ECPGt_date
Definition: ecpgtype.h:53
@ ECPGt_interval
Definition: ecpgtype.h:55
@ ECPGt_unsigned_long
Definition: ecpgtype.h:44
@ ECPGt_const
Definition: ecpgtype.h:61
@ ECPGt_bool
Definition: ecpgtype.h:46
@ ECPGt_unsigned_long_long
Definition: ecpgtype.h:45
@ ECPGt_unsigned_int
Definition: ecpgtype.h:44
@ ECPGt_descriptor
Definition: ecpgtype.h:59
@ ECPGt_char
Definition: ecpgtype.h:43
@ ECPGt_string
Definition: ecpgtype.h:65
#define IS_SIMPLE_TYPE(type)
Definition: ecpgtype.h:92
ECPGdtype
Definition: ecpgtype.h:72
@ ECPGd_scale
Definition: ecpgtype.h:86
@ ECPGd_precision
Definition: ecpgtype.h:83
@ ECPGd_length
Definition: ecpgtype.h:79
@ ECPGd_nullable
Definition: ecpgtype.h:81
@ ECPGd_di_precision
Definition: ecpgtype.h:76
@ ECPGd_type
Definition: ecpgtype.h:87
@ ECPGd_cardinality
Definition: ecpgtype.h:89
@ ECPGd_indicator
Definition: ecpgtype.h:77
@ ECPGd_ret_length
Definition: ecpgtype.h:84
@ ECPGd_di_code
Definition: ecpgtype.h:75
@ ECPGd_count
Definition: ecpgtype.h:73
@ ECPGd_name
Definition: ecpgtype.h:80
@ ECPGd_key_member
Definition: ecpgtype.h:78
@ ECPGd_octet
Definition: ecpgtype.h:82
@ ECPGd_ret_octet
Definition: ecpgtype.h:85
@ ECPGd_data
Definition: ecpgtype.h:74
#define free(a)
Definition: header.h:65
#define malloc(a)
Definition: header.h:50
#define sprintf
Definition: port.h:240
#define fprintf
Definition: port.h:242
void base_yyerror(const char *error)
#define OUT_OF_MEMORY
void mmerror(int error_code, enum errortype type, const char *error,...) pg_attribute_printf(3
struct variable * find_variable(char *name)
Definition: variable.c:193
#define INDICATOR_NOT_SIMPLE
void void mmfatal(int error_code, const char *error,...) pg_attribute_printf(2
#define PARSE_ERROR
#define INDICATOR_NOT_STRUCT
struct ECPGtype ecpg_no_indicator
#define INDICATOR_NOT_ARRAY
static pg_noinline void Size size
Definition: slab.c:607
char * name
Definition: type.h:12
struct ECPGtype * type
Definition: type.h:13
struct ECPGstruct_member * next
Definition: type.h:14
Definition: type.h:18
char * type_name
Definition: type.h:20
union ECPGtype::@154 u
char * struct_sizeof
Definition: type.h:24
enum ECPGttype type
Definition: type.h:19
struct ECPGstruct_member * members
Definition: type.h:30
char * size
Definition: type.h:22
struct ECPGtype * element
Definition: type.h:28
int counter
Definition: type.h:32
long varcharsize
enum ECPGttype type
int brace_level
Definition: type.h:180
enum ECPGttype ind_type
struct ECPGtype * ECPGmake_array_type(struct ECPGtype *type, char *size)
Definition: type.c:111
static void ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, char *arrsize, struct ECPGtype *type, struct ECPGtype *ind_type, const char *prefix, const char *ind_prefix)
Definition: type.c:581
void ECPGmake_struct_member(const char *name, struct ECPGtype *type, struct ECPGstruct_member **start)
Definition: type.c:77
struct ECPGtype * ECPGmake_simple_type(enum ECPGttype type, char *size, int counter)
Definition: type.c:96
static void ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type, char *varcharsize, char *arrsize, const char *size, const char *prefix, int counter)
Definition: type.c:411
char * mm_strdup(const char *string)
Definition: type.c:25
void ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype *type, const int brace_level, const char *ind_name, struct ECPGtype *ind_type, const int ind_brace_level, const char *prefix, const char *ind_prefix, char *arr_str_size, const char *struct_sizeof, const char *ind_struct_sizeof)
Definition: type.c:241
static const char * get_type(enum ECPGttype type)
Definition: type.c:133
void ECPGfree_struct_member(struct ECPGstruct_member *rm)
Definition: type.c:641
struct ECPGstruct_member * ECPGstruct_member_dup(struct ECPGstruct_member *rm)
Definition: type.c:37
struct ECPGtype * ECPGmake_struct_type(struct ECPGstruct_member *rm, enum ECPGttype type, char *type_name, char *struct_sizeof)
Definition: type.c:121
void ECPGfree_type(struct ECPGtype *type)
Definition: type.c:655
static struct ECPGstruct_member struct_no_indicator
Definition: type.c:9
const char * get_dtype(enum ECPGdtype type)
Definition: type.c:693
#define indicator_set
Definition: type.c:7
void * mm_alloc(size_t size)
Definition: type.c:13
@ ET_WARNING
Definition: type.h:207
@ ET_ERROR
Definition: type.h:207
const char * type
const char * name