2
* functions needed for descriptor handling
4
* since descriptor might be either a string constant or a string var
5
* we need to check for a constant if we expect a constant
8
#include "postgres_fe.h"
13
* assignment handling function (descriptor)
16
struct assignment *assignments;
19
push_assignment(char *var, enum ECPGdtype value)
21
struct assignment *new = (struct assignment *) mm_alloc(sizeof(struct assignment));
23
new->next = assignments;
24
new->variable = mm_alloc(strlen(var) + 1);
25
strcpy(new->variable, var);
31
drop_assignments(void)
35
struct assignment *old_head = assignments;
37
assignments = old_head->next;
38
free(old_head->variable);
44
ECPGnumeric_lvalue(FILE *f, char *name)
46
const struct variable *v = find_variable(name);
48
switch (v->type->type)
54
case ECPGt_unsigned_short:
55
case ECPGt_unsigned_int:
56
case ECPGt_unsigned_long:
57
case ECPGt_unsigned_long_long:
62
mmerror(PARSE_ERROR, ET_ERROR, "variable %s: numeric type needed", name);
68
* descriptor name lookup
71
static struct descriptor *descriptors;
74
add_descriptor(char *name, char *connection)
76
struct descriptor *new;
81
new = (struct descriptor *) mm_alloc(sizeof(struct descriptor));
83
new->next = descriptors;
84
new->name = mm_alloc(strlen(name) + 1);
85
strcpy(new->name, name);
88
new->connection = mm_alloc(strlen(connection) + 1);
89
strcpy(new->connection, connection);
92
new->connection = connection;
97
drop_descriptor(char *name, char *connection)
100
struct descriptor **lastptr = &descriptors;
105
for (i = descriptors; i; lastptr = &i->next, i = i->next)
107
if (!strcmp(name, i->name))
109
if ((!connection && !i->connection)
110
|| (connection && i->connection
111
&& !strcmp(connection, i->connection)))
122
mmerror(PARSE_ERROR, ET_WARNING, "unknown descriptor %s", name);
127
lookup_descriptor(char *name, char *connection)
129
struct descriptor *i;
134
for (i = descriptors; i; i = i->next)
136
if (!strcmp(name, i->name))
138
if ((!connection && !i->connection)
139
|| (connection && i->connection
140
&& !strcmp(connection, i->connection)))
144
mmerror(PARSE_ERROR, ET_WARNING, "unknown descriptor %s", name);
149
output_get_descr_header(char *desc_name)
151
struct assignment *results;
153
fprintf(yyout, "{ ECPGget_desc_header(__LINE__, %s, &(", desc_name);
154
for (results = assignments; results != NULL; results = results->next)
156
if (results->value == ECPGd_count)
157
ECPGnumeric_lvalue(yyout, results->variable);
159
mmerror(PARSE_ERROR, ET_WARNING, "unknown descriptor header item '%d'", results->value);
163
fprintf(yyout, "));\n");
168
output_get_descr(char *desc_name, char *index)
170
struct assignment *results;
172
fprintf(yyout, "{ ECPGget_desc(__LINE__, %s, %s,", desc_name, index);
173
for (results = assignments; results != NULL; results = results->next)
175
const struct variable *v = find_variable(results->variable);
177
switch (results->value)
180
mmerror(PARSE_ERROR, ET_WARNING, "nullable is always 1");
182
case ECPGd_key_member:
183
mmerror(PARSE_ERROR, ET_WARNING, "key_member is always 0");
188
fprintf(yyout, "%s,", get_dtype(results->value));
189
ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL, make_str("0"), NULL, NULL);
192
fputs("ECPGd_EODT);\n", yyout);
194
whenever_action(2 | 1);
198
output_set_descr_header(char *desc_name)
200
struct assignment *results;
202
fprintf(yyout, "{ ECPGset_desc_header(__LINE__, %s, (int)(", desc_name);
203
for (results = assignments; results != NULL; results = results->next)
205
if (results->value == ECPGd_count)
206
ECPGnumeric_lvalue(yyout, results->variable);
208
mmerror(PARSE_ERROR, ET_WARNING, "unknown descriptor header item '%d'", results->value);
212
fprintf(yyout, "));\n");
217
descriptor_item_name(enum ECPGdtype itemcode)
221
case ECPGd_cardinality:
222
return "CARDINALITY";
228
return "DATETIME_INTERVAL_CODE";
229
case ECPGd_di_precision:
230
return "DATETIME_INTERVAL_PRECISION";
231
case ECPGd_indicator:
233
case ECPGd_key_member:
242
return "OCTET_LENGTH";
243
case ECPGd_precision:
245
case ECPGd_ret_length:
246
return "RETURNED_LENGTH";
247
case ECPGd_ret_octet:
248
return "RETURNED_OCTET_LENGTH";
259
output_set_descr(char *desc_name, char *index)
261
struct assignment *results;
263
fprintf(yyout, "{ ECPGset_desc(__LINE__, %s, %s,", desc_name, index);
264
for (results = assignments; results != NULL; results = results->next)
266
const struct variable *v = find_variable(results->variable);
268
switch (results->value)
270
case ECPGd_cardinality:
272
case ECPGd_di_precision:
273
case ECPGd_precision:
275
mmerror(PARSE_ERROR, ET_FATAL, "descriptor item %s is not implemented",
276
descriptor_item_name(results->value));
279
case ECPGd_key_member:
283
case ECPGd_ret_length:
284
case ECPGd_ret_octet:
285
mmerror(PARSE_ERROR, ET_FATAL, "descriptor item %s cannot be set",
286
descriptor_item_name(results->value));
290
case ECPGd_indicator:
293
fprintf(yyout, "%s,", get_dtype(results->value));
294
ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL, make_str("0"), NULL, NULL);
302
fputs("ECPGd_EODT);\n", yyout);
304
whenever_action(2 | 1);
307
/* I consider dynamic allocation overkill since at most two descriptor
308
variables are possible per statement. (input and output descriptor)
309
And descriptors are no normal variables, so they don't belong into
313
#define MAX_DESCRIPTOR_NAMELEN 128
315
descriptor_variable(const char *name, int input)
317
static char descriptor_names[2][MAX_DESCRIPTOR_NAMELEN];
318
static const struct ECPGtype descriptor_type = {ECPGt_descriptor, NULL};
319
static const struct variable varspace[2] = {
320
{descriptor_names[0], (struct ECPGtype *) & descriptor_type, 0, NULL},
321
{descriptor_names[1], (struct ECPGtype *) & descriptor_type, 0, NULL}
324
strncpy(descriptor_names[input], name, MAX_DESCRIPTOR_NAMELEN);
325
descriptor_names[input][MAX_DESCRIPTOR_NAMELEN - 1] = 0;
326
return (struct variable *) & varspace[input];