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  if (i->connection)
117  free(i->connection);
118  free(i->name);
119  free(i);
120  return;
121  }
122  }
123  }
124  if (connection)
125  mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to connection %s does not exist", name, connection);
126  else
127  mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to the default connection does not exist", name);
128 }
129 
130 struct descriptor
131  *
133 {
134  struct descriptor *i;
135 
136  if (name[0] != '"')
137  return NULL;
138 
139  for (i = descriptors; i; i = i->next)
140  {
141  if (strcmp(name, i->name) == 0)
142  {
143  if ((!connection && !i->connection)
144  || (connection && i->connection
145  && strcmp(connection, i->connection) == 0))
146  return i;
147  if (connection && !i->connection)
148  {
149  /* overwrite descriptor's connection */
150  i->connection = mm_strdup(connection);
151  return i;
152  }
153  }
154  }
155  if (connection)
156  mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to connection %s does not exist", name, connection);
157  else
158  mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to the default connection does not exist", name);
159  return NULL;
160 }
161 
162 void
163 output_get_descr_header(char *desc_name)
164 {
165  struct assignment *results;
166 
167  fprintf(base_yyout, "{ ECPGget_desc_header(__LINE__, %s, &(", desc_name);
168  for (results = assignments; results != NULL; results = results->next)
169  {
170  if (results->value == ECPGd_count)
171  ECPGnumeric_lvalue(results->variable);
172  else
173  mmerror(PARSE_ERROR, ET_WARNING, "descriptor header item \"%d\" does not exist", results->value);
174  }
175 
177  fprintf(base_yyout, "));\n");
178  whenever_action(3);
179 }
180 
181 void
182 output_get_descr(char *desc_name, char *index)
183 {
184  struct assignment *results;
185 
186  fprintf(base_yyout, "{ ECPGget_desc(__LINE__, %s, %s,", desc_name, index);
187  for (results = assignments; results != NULL; results = results->next)
188  {
189  const struct variable *v = find_variable(results->variable);
190  char *str_zero = mm_strdup("0");
191 
192  switch (results->value)
193  {
194  case ECPGd_nullable:
195  mmerror(PARSE_ERROR, ET_WARNING, "nullable is always 1");
196  break;
197  case ECPGd_key_member:
198  mmerror(PARSE_ERROR, ET_WARNING, "key_member is always 0");
199  break;
200  default:
201  break;
202  }
203  fprintf(base_yyout, "%s,", get_dtype(results->value));
205  NULL, NULL, -1, NULL, NULL, str_zero, NULL, NULL);
206  free(str_zero);
207  }
209  fputs("ECPGd_EODT);\n", base_yyout);
210 
211  whenever_action(2 | 1);
212 }
213 
214 void
215 output_set_descr_header(char *desc_name)
216 {
217  struct assignment *results;
218 
219  fprintf(base_yyout, "{ ECPGset_desc_header(__LINE__, %s, (int)(", desc_name);
220  for (results = assignments; results != NULL; results = results->next)
221  {
222  if (results->value == ECPGd_count)
223  ECPGnumeric_lvalue(results->variable);
224  else
225  mmerror(PARSE_ERROR, ET_WARNING, "descriptor header item \"%d\" does not exist", results->value);
226  }
227 
229  fprintf(base_yyout, "));\n");
230  whenever_action(3);
231 }
232 
233 static const char *
235 {
236  switch (itemcode)
237  {
238  case ECPGd_cardinality:
239  return "CARDINALITY";
240  case ECPGd_count:
241  return "COUNT";
242  case ECPGd_data:
243  return "DATA";
244  case ECPGd_di_code:
245  return "DATETIME_INTERVAL_CODE";
246  case ECPGd_di_precision:
247  return "DATETIME_INTERVAL_PRECISION";
248  case ECPGd_indicator:
249  return "INDICATOR";
250  case ECPGd_key_member:
251  return "KEY_MEMBER";
252  case ECPGd_length:
253  return "LENGTH";
254  case ECPGd_name:
255  return "NAME";
256  case ECPGd_nullable:
257  return "NULLABLE";
258  case ECPGd_octet:
259  return "OCTET_LENGTH";
260  case ECPGd_precision:
261  return "PRECISION";
262  case ECPGd_ret_length:
263  return "RETURNED_LENGTH";
264  case ECPGd_ret_octet:
265  return "RETURNED_OCTET_LENGTH";
266  case ECPGd_scale:
267  return "SCALE";
268  case ECPGd_type:
269  return "TYPE";
270  default:
271  return NULL;
272  }
273 }
274 
275 void
276 output_set_descr(char *desc_name, char *index)
277 {
278  struct assignment *results;
279 
280  fprintf(base_yyout, "{ ECPGset_desc(__LINE__, %s, %s,", desc_name, index);
281  for (results = assignments; results != NULL; results = results->next)
282  {
283  const struct variable *v = find_variable(results->variable);
284 
285  switch (results->value)
286  {
287  case ECPGd_cardinality:
288  case ECPGd_di_code:
289  case ECPGd_di_precision:
290  case ECPGd_precision:
291  case ECPGd_scale:
292  mmfatal(PARSE_ERROR, "descriptor item \"%s\" is not implemented",
293  descriptor_item_name(results->value));
294  break;
295 
296  case ECPGd_key_member:
297  case ECPGd_name:
298  case ECPGd_nullable:
299  case ECPGd_octet:
300  case ECPGd_ret_length:
301  case ECPGd_ret_octet:
302  mmfatal(PARSE_ERROR, "descriptor item \"%s\" cannot be set",
303  descriptor_item_name(results->value));
304  break;
305 
306  case ECPGd_data:
307  case ECPGd_indicator:
308  case ECPGd_length:
309  case ECPGd_type:
310  {
311  char *str_zero = mm_strdup("0");
312 
313  fprintf(base_yyout, "%s,", get_dtype(results->value));
315  NULL, NULL, -1, NULL, NULL, str_zero, NULL, NULL);
316  free(str_zero);
317  }
318  break;
319 
320  default:
321  ;
322  }
323  }
325  fputs("ECPGd_EODT);\n", base_yyout);
326 
327  whenever_action(2 | 1);
328 }
329 
330 /* I consider dynamic allocation overkill since at most two descriptor
331  variables are possible per statement. (input and output descriptor)
332  And descriptors are no normal variables, so they don't belong into
333  the variable list.
334 */
335 
336 #define MAX_DESCRIPTOR_NAMELEN 128
337 struct variable *
338 descriptor_variable(const char *name, int input)
339 {
340  static char descriptor_names[2][MAX_DESCRIPTOR_NAMELEN];
341  static struct ECPGtype descriptor_type = {ECPGt_descriptor, NULL, NULL, NULL, {NULL}, 0};
342  static struct variable varspace[2] = {
343  {descriptor_names[0], &descriptor_type, 0, NULL},
344  {descriptor_names[1], &descriptor_type, 0, NULL}
345  };
346 
347  strlcpy(descriptor_names[input], name, sizeof(descriptor_names[input]));
348  return &varspace[input];
349 }
350 
351 struct variable *
352 sqlda_variable(const char *name)
353 {
354  struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable));
355 
356  p->name = mm_strdup(name);
357  p->type = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
358  p->type->type = ECPGt_sqlda;
359  p->type->size = NULL;
360  p->type->struct_sizeof = NULL;
361  p->type->u.element = NULL;
362  p->type->counter = 0;
363  p->brace_level = 0;
364  p->next = NULL;
365 
366  return p;
367 }
int brace_level
Definition: type.h:174
void output_get_descr(char *desc_name, char *index)
Definition: descriptor.c:182
char * connection
Definition: type.h:188
void void mmfatal(int errorcode, const char *error,...) pg_attribute_printf(2
Definition: type.h:201
static struct assignment * assignments
Definition: descriptor.c:18
static void drop_assignments(void)
Definition: descriptor.c:33
static struct descriptor * descriptors
Definition: descriptor.c:73
void output_get_descr_header(char *desc_name)
Definition: descriptor.c:163
enum ECPGttype type
struct variable * next
#define fprintf
Definition: port.h:221
struct descriptor * lookup_descriptor(char *name, char *connection)
Definition: descriptor.c:132
Definition: type.h:17
char * mm_strdup(const char *)
Definition: type.c:25
void whenever_action(int mode)
Definition: output.c:66
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
Definition: type.h:89
static void ECPGnumeric_lvalue(char *name)
Definition: descriptor.c:46
void push_assignment(char *var, enum ECPGdtype value)
Definition: descriptor.c:21
struct descriptor * next
const char * get_dtype(enum ECPGdtype)
Definition: type.c:693
#define PARSE_ERROR
void drop_descriptor(char *name, char *connection)
Definition: descriptor.c:99
void output_set_descr_header(char *desc_name)
Definition: descriptor.c:215
struct assignment * next
Definition: type.h:196
char * variable
Definition: type.h:194
struct variable * find_variable(char *)
Definition: variable.c:194
void output_set_descr(char *desc_name, char *index)
Definition: descriptor.c:276
ECPGdtype
Definition: ecpgtype.h:71
#define MAX_DESCRIPTOR_NAMELEN
Definition: descriptor.c:336
static struct @143 value
#define free(a)
Definition: header.h:65
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
struct variable * sqlda_variable(const char *name)
Definition: descriptor.c:352
void add_descriptor(char *name, char *connection)
Definition: descriptor.c:76
struct variable * descriptor_variable(const char *name, int input)
Definition: descriptor.c:338
void mmerror(int errorcode, enum errortype type, const char *error,...) pg_attribute_printf(3
const char * name
Definition: encode.c:561
void * mm_alloc(size_t)
Definition: type.c:13
int i
char * connection
static const char * descriptor_item_name(enum ECPGdtype itemcode)
Definition: descriptor.c:234
enum ECPGdtype value
Definition: type.h:195
char * name
Definition: type.h:172
FILE * base_yyout