PostgreSQL Source Code  git master
descriptor.c
Go to the documentation of this file.
1 /*
2  * functions needed for descriptor handling
3  *
4  * src/interfaces/ecpg/preproc/descriptor.c
5  *
6  * since descriptor might be either a string constant or a string var
7  * we need to check for a constant if we expect a constant
8  */
9 
10 #include "postgres_fe.h"
11 
12 #include "preproc_extern.h"
13 
14 /*
15  * assignment handling function (descriptor)
16  */
17 
18 static struct assignment *assignments;
19 
20 void
22 {
23  struct assignment *new = (struct assignment *) mm_alloc(sizeof(struct assignment));
24 
25  new->next = assignments;
26  new->variable = mm_alloc(strlen(var) + 1);
27  strcpy(new->variable, var);
28  new->value = value;
29  assignments = new;
30 }
31 
32 static void
34 {
35  while (assignments)
36  {
37  struct assignment *old_head = assignments;
38 
39  assignments = old_head->next;
40  free(old_head->variable);
41  free(old_head);
42  }
43 }
44 
45 static void
47 {
48  const struct variable *v = find_variable(name);
49 
50  switch (v->type->type)
51  {
52  case ECPGt_short:
53  case ECPGt_int:
54  case ECPGt_long:
55  case ECPGt_long_long:
57  case ECPGt_unsigned_int:
60  case ECPGt_const:
61  fputs(name, base_yyout);
62  break;
63  default:
64  mmerror(PARSE_ERROR, ET_ERROR, "variable \"%s\" must have a numeric type", name);
65  break;
66  }
67 }
68 
69 /*
70  * descriptor name lookup
71  */
72 
73 static struct descriptor *descriptors;
74 
75 void
77 {
78  struct descriptor *new;
79 
80  if (name[0] != '"')
81  return;
82 
83  new = (struct descriptor *) mm_alloc(sizeof(struct descriptor));
84 
85  new->next = descriptors;
86  new->name = mm_alloc(strlen(name) + 1);
87  strcpy(new->name, name);
88  if (connection)
89  {
90  new->connection = mm_alloc(strlen(connection) + 1);
91  strcpy(new->connection, connection);
92  }
93  else
94  new->connection = connection;
95  descriptors = new;
96 }
97 
98 void
100 {
101  struct descriptor *i;
102  struct descriptor **lastptr = &descriptors;
103 
104  if (name[0] != '"')
105  return;
106 
107  for (i = descriptors; i; lastptr = &i->next, i = i->next)
108  {
109  if (strcmp(name, i->name) == 0)
110  {
111  if ((!connection && !i->connection)
112  || (connection && i->connection
113  && strcmp(connection, i->connection) == 0))
114  {
115  *lastptr = i->next;
116  free(i->connection);
117  free(i->name);
118  free(i);
119  return;
120  }
121  }
122  }
123  if (connection)
124  mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to connection %s does not exist", name, connection);
125  else
126  mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to the default connection does not exist", name);
127 }
128 
129 struct descriptor
130  *
132 {
133  struct descriptor *i;
134 
135  if (name[0] != '"')
136  return NULL;
137 
138  for (i = descriptors; i; i = i->next)
139  {
140  if (strcmp(name, i->name) == 0)
141  {
142  if ((!connection && !i->connection)
143  || (connection && i->connection
144  && strcmp(connection, i->connection) == 0))
145  return i;
146  if (connection && !i->connection)
147  {
148  /* overwrite descriptor's connection */
149  i->connection = mm_strdup(connection);
150  return i;
151  }
152  }
153  }
154  if (connection)
155  mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to connection %s does not exist", name, connection);
156  else
157  mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to the default connection does not exist", name);
158  return NULL;
159 }
160 
161 void
162 output_get_descr_header(char *desc_name)
163 {
164  struct assignment *results;
165 
166  fprintf(base_yyout, "{ ECPGget_desc_header(__LINE__, %s, &(", desc_name);
167  for (results = assignments; results != NULL; results = results->next)
168  {
169  if (results->value == ECPGd_count)
170  ECPGnumeric_lvalue(results->variable);
171  else
172  mmerror(PARSE_ERROR, ET_WARNING, "descriptor header item \"%d\" does not exist", results->value);
173  }
174 
176  fprintf(base_yyout, "));\n");
177  whenever_action(3);
178 }
179 
180 void
181 output_get_descr(char *desc_name, char *index)
182 {
183  struct assignment *results;
184 
185  fprintf(base_yyout, "{ ECPGget_desc(__LINE__, %s, %s,", desc_name, index);
186  for (results = assignments; results != NULL; results = results->next)
187  {
188  const struct variable *v = find_variable(results->variable);
189  char *str_zero = mm_strdup("0");
190 
191  switch (results->value)
192  {
193  case ECPGd_nullable:
194  mmerror(PARSE_ERROR, ET_WARNING, "nullable is always 1");
195  break;
196  case ECPGd_key_member:
197  mmerror(PARSE_ERROR, ET_WARNING, "key_member is always 0");
198  break;
199  default:
200  break;
201  }
202  fprintf(base_yyout, "%s,", get_dtype(results->value));
204  NULL, NULL, -1, NULL, NULL, str_zero, NULL, NULL);
205  free(str_zero);
206  }
208  fputs("ECPGd_EODT);\n", base_yyout);
209 
210  whenever_action(2 | 1);
211 }
212 
213 void
214 output_set_descr_header(char *desc_name)
215 {
216  struct assignment *results;
217 
218  fprintf(base_yyout, "{ ECPGset_desc_header(__LINE__, %s, (int)(", desc_name);
219  for (results = assignments; results != NULL; results = results->next)
220  {
221  if (results->value == ECPGd_count)
222  ECPGnumeric_lvalue(results->variable);
223  else
224  mmerror(PARSE_ERROR, ET_WARNING, "descriptor header item \"%d\" does not exist", results->value);
225  }
226 
228  fprintf(base_yyout, "));\n");
229  whenever_action(3);
230 }
231 
232 static const char *
234 {
235  switch (itemcode)
236  {
237  case ECPGd_cardinality:
238  return "CARDINALITY";
239  case ECPGd_count:
240  return "COUNT";
241  case ECPGd_data:
242  return "DATA";
243  case ECPGd_di_code:
244  return "DATETIME_INTERVAL_CODE";
245  case ECPGd_di_precision:
246  return "DATETIME_INTERVAL_PRECISION";
247  case ECPGd_indicator:
248  return "INDICATOR";
249  case ECPGd_key_member:
250  return "KEY_MEMBER";
251  case ECPGd_length:
252  return "LENGTH";
253  case ECPGd_name:
254  return "NAME";
255  case ECPGd_nullable:
256  return "NULLABLE";
257  case ECPGd_octet:
258  return "OCTET_LENGTH";
259  case ECPGd_precision:
260  return "PRECISION";
261  case ECPGd_ret_length:
262  return "RETURNED_LENGTH";
263  case ECPGd_ret_octet:
264  return "RETURNED_OCTET_LENGTH";
265  case ECPGd_scale:
266  return "SCALE";
267  case ECPGd_type:
268  return "TYPE";
269  default:
270  return NULL;
271  }
272 }
273 
274 void
275 output_set_descr(char *desc_name, char *index)
276 {
277  struct assignment *results;
278 
279  fprintf(base_yyout, "{ ECPGset_desc(__LINE__, %s, %s,", desc_name, index);
280  for (results = assignments; results != NULL; results = results->next)
281  {
282  const struct variable *v = find_variable(results->variable);
283 
284  switch (results->value)
285  {
286  case ECPGd_cardinality:
287  case ECPGd_di_code:
288  case ECPGd_di_precision:
289  case ECPGd_precision:
290  case ECPGd_scale:
291  mmfatal(PARSE_ERROR, "descriptor item \"%s\" is not implemented",
292  descriptor_item_name(results->value));
293  break;
294 
295  case ECPGd_key_member:
296  case ECPGd_name:
297  case ECPGd_nullable:
298  case ECPGd_octet:
299  case ECPGd_ret_length:
300  case ECPGd_ret_octet:
301  mmfatal(PARSE_ERROR, "descriptor item \"%s\" cannot be set",
302  descriptor_item_name(results->value));
303  break;
304 
305  case ECPGd_data:
306  case ECPGd_indicator:
307  case ECPGd_length:
308  case ECPGd_type:
309  {
310  char *str_zero = mm_strdup("0");
311 
312  fprintf(base_yyout, "%s,", get_dtype(results->value));
314  NULL, NULL, -1, NULL, NULL, str_zero, NULL, NULL);
315  free(str_zero);
316  }
317  break;
318 
319  default:
320  ;
321  }
322  }
324  fputs("ECPGd_EODT);\n", base_yyout);
325 
326  whenever_action(2 | 1);
327 }
328 
329 /* I consider dynamic allocation overkill since at most two descriptor
330  variables are possible per statement. (input and output descriptor)
331  And descriptors are no normal variables, so they don't belong into
332  the variable list.
333 */
334 
335 #define MAX_DESCRIPTOR_NAMELEN 128
336 struct variable *
337 descriptor_variable(const char *name, int input)
338 {
339  static char descriptor_names[2][MAX_DESCRIPTOR_NAMELEN];
340  static struct ECPGtype descriptor_type = {ECPGt_descriptor, NULL, NULL, NULL, {NULL}, 0};
341  static struct variable varspace[2] = {
342  {descriptor_names[0], &descriptor_type, 0, NULL},
343  {descriptor_names[1], &descriptor_type, 0, NULL}
344  };
345 
346  strlcpy(descriptor_names[input], name, sizeof(descriptor_names[input]));
347  return &varspace[input];
348 }
349 
350 struct variable *
351 sqlda_variable(const char *name)
352 {
353  struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable));
354 
355  p->name = mm_strdup(name);
356  p->type = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
357  p->type->type = ECPGt_sqlda;
358  p->type->size = NULL;
359  p->type->struct_sizeof = NULL;
360  p->type->u.element = NULL;
361  p->type->counter = 0;
362  p->brace_level = 0;
363  p->next = NULL;
364 
365  return p;
366 }
@ ECPGt_long_long
Definition: ecpgtype.h:45
@ ECPGt_sqlda
Definition: ecpgtype.h:66
@ ECPGt_short
Definition: ecpgtype.h:43
@ ECPGt_unsigned_short
Definition: ecpgtype.h:43
@ ECPGt_int
Definition: ecpgtype.h:44
@ ECPGt_long
Definition: ecpgtype.h:44
@ ECPGt_unsigned_long
Definition: ecpgtype.h:44
@ ECPGt_const
Definition: ecpgtype.h:61
@ ECPGt_unsigned_long_long
Definition: ecpgtype.h:45
@ ECPGt_unsigned_int
Definition: ecpgtype.h:44
@ ECPGt_descriptor
Definition: ecpgtype.h:59
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
FILE * input
static struct @150 value
int i
Definition: isn.c:73
void whenever_action(int mode)
Definition: output.c:66
#define fprintf
Definition: port.h:242
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
struct variable * descriptor_variable(const char *name, int input)
Definition: descriptor.c:337
void push_assignment(char *var, enum ECPGdtype value)
Definition: descriptor.c:21
void output_set_descr(char *desc_name, char *index)
Definition: descriptor.c:275
void add_descriptor(char *name, char *connection)
Definition: descriptor.c:76
static struct descriptor * descriptors
Definition: descriptor.c:73
void output_get_descr_header(char *desc_name)
Definition: descriptor.c:162
void output_get_descr(char *desc_name, char *index)
Definition: descriptor.c:181
static struct assignment * assignments
Definition: descriptor.c:18
static void ECPGnumeric_lvalue(char *name)
Definition: descriptor.c:46
void drop_descriptor(char *name, char *connection)
Definition: descriptor.c:99
static const char * descriptor_item_name(enum ECPGdtype itemcode)
Definition: descriptor.c:233
static void drop_assignments(void)
Definition: descriptor.c:33
struct variable * sqlda_variable(const char *name)
Definition: descriptor.c:351
void output_set_descr_header(char *desc_name)
Definition: descriptor.c:214
#define MAX_DESCRIPTOR_NAMELEN
Definition: descriptor.c:335
struct descriptor * lookup_descriptor(char *name, char *connection)
Definition: descriptor.c:131
char * connection
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
char * mm_strdup(const char *string)
Definition: type.c:25
void void mmfatal(int error_code, const char *error,...) pg_attribute_printf(2
const char * get_dtype(enum ECPGdtype)
Definition: type.c:693
#define PARSE_ERROR
FILE * base_yyout
void * mm_alloc(size_t size)
Definition: type.c:13
Definition: type.h:18
char * variable
Definition: type.h:200
enum ECPGdtype value
Definition: type.h:201
struct assignment * next
Definition: type.h:202
Definition: type.h:95
char * name
Definition: type.h:178
struct variable * next
enum ECPGttype type
int brace_level
Definition: type.h:180
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
@ ET_WARNING
Definition: type.h:207
@ ET_ERROR
Definition: type.h:207
const char * name