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