PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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 {
37
39 free(old_head->variable);
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:
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 */
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/*
324 * I consider dynamic allocation overkill since at most two descriptor
325 * variables are possible per statement. (input and output descriptor)
326 * And descriptors are no normal variables, so they don't belong into
327 * the variable list.
328 */
329
330#define MAX_DESCRIPTOR_NAMELEN 128
331struct variable *
333{
335 static struct ECPGtype descriptor_type = {ECPGt_descriptor, NULL, NULL, NULL, {NULL}, 0};
336 static struct variable varspace[2] = {
339 };
340
342 return &varspace[input];
343}
344
345struct variable *
347{
348 /*
349 * Presently, sqlda variables are only needed for the duration of the
350 * current statement. Rather than add infrastructure to manage them,
351 * let's just loc_alloc them.
352 */
353 struct variable *p = (struct variable *) loc_alloc(sizeof(struct variable));
354
355 p->name = loc_strdup(name);
356 p->type = (struct ECPGtype *) loc_alloc(sizeof(struct ECPGtype));
357 p->type->type = ECPGt_sqlda;
358 p->type->type_name = NULL;
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}
#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
FILE * input
static struct @177 value
int i
Definition isn.c:77
void whenever_action(int mode)
Definition output.c:64
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
static int fb(int x)
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:346
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:332
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:330
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:675
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:235
FILE * base_yyout
char * loc_strdup(const char *string)
Definition util.c:170
#define free(a)
char * variable
Definition type.h:214
enum ECPGdtype value
Definition type.h:215
struct assignment * next
Definition type.h:216
PGconn * connection
char * connection
Definition type.h:208
struct descriptor * next
Definition type.h:97
char * name
Definition type.h:192
struct variable * next
enum ECPGttype type
int brace_level
Definition type.h:194
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:219
@ ET_WARNING
Definition type.h:221
@ ET_ERROR
Definition type.h:221
const char * name