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