Age Owner Branch data TLA Line data Source code
1 : : /* dynamic SQL support routines
2 : : *
3 : : * src/interfaces/ecpg/ecpglib/descriptor.c
4 : : */
5 : :
6 : : #define POSTGRES_ECPG_INTERNAL
7 : : #include "postgres_fe.h"
8 : :
9 : : #include "catalog/pg_type_d.h"
10 : : #include "ecpg-pthread-win32.h"
11 : : #include "ecpgerrno.h"
12 : : #include "ecpglib.h"
13 : : #include "ecpglib_extern.h"
14 : : #include "ecpgtype.h"
15 : : #include "sql3types.h"
16 : : #include "sqlca.h"
17 : : #include "sqlda.h"
18 : :
19 : : static void descriptor_free(struct descriptor *desc);
20 : :
21 : : /* We manage descriptors separately for each thread. */
22 : : static pthread_key_t descriptor_key;
23 : : static pthread_once_t descriptor_once = PTHREAD_ONCE_INIT;
24 : :
25 : : static void descriptor_deallocate_all(struct descriptor *list);
26 : :
27 : : static void
6790 meskes@postgresql.or 28 :UBC 0 : descriptor_destructor(void *arg)
29 : : {
30 : 0 : descriptor_deallocate_all(arg);
31 : 0 : }
32 : :
33 : : static void
6790 meskes@postgresql.or 34 :CBC 10 : descriptor_key_init(void)
35 : : {
36 : 10 : pthread_key_create(&descriptor_key, descriptor_destructor);
37 : 10 : }
38 : :
39 : : static struct descriptor *
40 : 1600154 : get_descriptors(void)
41 : : {
42 : 1600154 : pthread_once(&descriptor_once, descriptor_key_init);
43 : 1600154 : return (struct descriptor *) pthread_getspecific(descriptor_key);
44 : : }
45 : :
46 : : static void
3240 tgl@sss.pgh.pa.us 47 : 1600029 : set_descriptors(struct descriptor *value)
48 : : {
6790 meskes@postgresql.or 49 : 1600029 : pthread_setspecific(descriptor_key, value);
50 : 1600029 : }
51 : :
52 : : /* old internal convenience function that might go away later */
53 : : static PGresult *
6789 54 : 74 : ecpg_result_by_descriptor(int line, const char *name)
55 : : {
56 : 74 : struct descriptor *desc = ecpg_find_desc(line, name);
57 : :
6790 58 [ - + ]: 74 : if (desc == NULL)
6790 meskes@postgresql.or 59 :UBC 0 : return NULL;
6790 meskes@postgresql.or 60 :CBC 74 : return desc->result;
61 : : }
62 : :
63 : : static unsigned int
6789 64 : 8 : ecpg_dynamic_type_DDT(Oid type)
65 : : {
8451 66 [ + - - - : 8 : switch (type)
- - ]
67 : : {
68 : 8 : case DATEOID:
69 : 8 : return SQL3_DDT_DATE;
8451 meskes@postgresql.or 70 :UBC 0 : case TIMEOID:
71 : 0 : return SQL3_DDT_TIME;
72 : 0 : case TIMESTAMPOID:
73 : 0 : return SQL3_DDT_TIMESTAMP;
74 : 0 : case TIMESTAMPTZOID:
75 : 0 : return SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE;
76 : 0 : case TIMETZOID:
77 : 0 : return SQL3_DDT_TIME_WITH_TIME_ZONE;
78 : 0 : default:
79 : 0 : return SQL3_DDT_ILLEGAL;
80 : : }
81 : : }
82 : :
83 : : bool
7461 meskes@postgresql.or 84 :CBC 12 : ECPGget_desc_header(int lineno, const char *desc_name, int *count)
85 : : {
86 : : PGresult *ECPGresult;
8360 bruce@momjian.us 87 : 12 : struct sqlca_t *sqlca = ECPGget_sqlca();
88 : :
3977 meskes@postgresql.or 89 [ - + ]: 12 : if (sqlca == NULL)
90 : : {
3977 meskes@postgresql.or 91 :UBC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
92 : : ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
93 : 0 : return false;
94 : : }
95 : :
6789 meskes@postgresql.or 96 :CBC 12 : ecpg_init_sqlca(sqlca);
97 : 12 : ECPGresult = ecpg_result_by_descriptor(lineno, desc_name);
8451 98 [ - + ]: 12 : if (!ECPGresult)
8451 meskes@postgresql.or 99 :UBC 0 : return false;
100 : :
8451 meskes@postgresql.or 101 :CBC 12 : *count = PQnfields(ECPGresult);
8360 bruce@momjian.us 102 : 12 : sqlca->sqlerrd[2] = 1;
6563 peter_e@gmx.net 103 : 12 : ecpg_log("ECPGget_desc_header: found %d attributes\n", *count);
8451 meskes@postgresql.or 104 : 12 : return true;
105 : : }
106 : :
107 : : static bool
108 : 103 : get_int_item(int lineno, void *var, enum ECPGttype vartype, int value)
109 : : {
110 [ - + - - : 103 : switch (vartype)
- - - - -
- - ]
111 : : {
8451 meskes@postgresql.or 112 :UBC 0 : case ECPGt_short:
113 : 0 : *(short *) var = (short) value;
114 : 0 : break;
8451 meskes@postgresql.or 115 :CBC 103 : case ECPGt_int:
154 peter@eisentraut.org 116 :GNC 103 : *(int *) var = value;
8451 meskes@postgresql.or 117 :CBC 103 : break;
8451 meskes@postgresql.or 118 :UBC 0 : case ECPGt_long:
119 : 0 : *(long *) var = (long) value;
120 : 0 : break;
121 : 0 : case ECPGt_unsigned_short:
122 : 0 : *(unsigned short *) var = (unsigned short) value;
123 : 0 : break;
124 : 0 : case ECPGt_unsigned_int:
125 : 0 : *(unsigned int *) var = (unsigned int) value;
126 : 0 : break;
127 : 0 : case ECPGt_unsigned_long:
128 : 0 : *(unsigned long *) var = (unsigned long) value;
129 : 0 : break;
130 : 0 : case ECPGt_long_long:
131 : 0 : *(long long int *) var = (long long int) value;
132 : 0 : break;
133 : 0 : case ECPGt_unsigned_long_long:
134 : 0 : *(unsigned long long int *) var = (unsigned long long int) value;
135 : 0 : break;
136 : 0 : case ECPGt_float:
137 : 0 : *(float *) var = (float) value;
138 : 0 : break;
139 : 0 : case ECPGt_double:
140 : 0 : *(double *) var = (double) value;
141 : 0 : break;
142 : 0 : default:
6789 143 : 0 : ecpg_raise(lineno, ECPG_VAR_NOT_NUMERIC, ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION, NULL);
3183 peter_e@gmx.net 144 : 0 : return false;
145 : : }
146 : :
3183 peter_e@gmx.net 147 :CBC 103 : return true;
148 : : }
149 : :
150 : : static bool
7979 meskes@postgresql.or 151 : 4 : set_int_item(int lineno, int *target, const void *var, enum ECPGttype vartype)
152 : : {
153 [ - + - - : 4 : switch (vartype)
- - - - -
- - ]
154 : : {
7979 meskes@postgresql.or 155 :UBC 0 : case ECPGt_short:
5350 peter_e@gmx.net 156 : 0 : *target = *(const short *) var;
7979 meskes@postgresql.or 157 : 0 : break;
7979 meskes@postgresql.or 158 :CBC 4 : case ECPGt_int:
5350 peter_e@gmx.net 159 : 4 : *target = *(const int *) var;
7979 meskes@postgresql.or 160 : 4 : break;
7979 meskes@postgresql.or 161 :UBC 0 : case ECPGt_long:
5350 peter_e@gmx.net 162 : 0 : *target = *(const long *) var;
7979 meskes@postgresql.or 163 : 0 : break;
164 : 0 : case ECPGt_unsigned_short:
5350 peter_e@gmx.net 165 : 0 : *target = *(const unsigned short *) var;
7979 meskes@postgresql.or 166 : 0 : break;
167 : 0 : case ECPGt_unsigned_int:
5350 peter_e@gmx.net 168 : 0 : *target = *(const unsigned int *) var;
7979 meskes@postgresql.or 169 : 0 : break;
170 : 0 : case ECPGt_unsigned_long:
5350 peter_e@gmx.net 171 : 0 : *target = *(const unsigned long *) var;
7979 meskes@postgresql.or 172 : 0 : break;
173 : 0 : case ECPGt_long_long:
5350 peter_e@gmx.net 174 : 0 : *target = *(const long long int *) var;
7979 meskes@postgresql.or 175 : 0 : break;
176 : 0 : case ECPGt_unsigned_long_long:
5350 peter_e@gmx.net 177 : 0 : *target = *(const unsigned long long int *) var;
7979 meskes@postgresql.or 178 : 0 : break;
179 : 0 : case ECPGt_float:
5350 peter_e@gmx.net 180 : 0 : *target = *(const float *) var;
7979 meskes@postgresql.or 181 : 0 : break;
182 : 0 : case ECPGt_double:
5350 peter_e@gmx.net 183 : 0 : *target = *(const double *) var;
7979 meskes@postgresql.or 184 : 0 : break;
185 : 0 : default:
6789 186 : 0 : ecpg_raise(lineno, ECPG_VAR_NOT_NUMERIC, ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION, NULL);
3183 peter_e@gmx.net 187 : 0 : return false;
188 : : }
189 : :
7979 meskes@postgresql.or 190 :CBC 4 : return true;
191 : : }
192 : :
193 : : static bool
8451 194 : 30 : get_char_item(int lineno, void *var, enum ECPGttype vartype, char *value, int varcharsize)
195 : : {
196 [ + - - ]: 30 : switch (vartype)
197 : : {
198 : 30 : case ECPGt_char:
199 : : case ECPGt_unsigned_char:
200 : : case ECPGt_string:
439 peter@eisentraut.org 201 : 30 : strncpy(var, value, varcharsize);
8451 meskes@postgresql.or 202 : 30 : break;
8451 meskes@postgresql.or 203 :UBC 0 : case ECPGt_varchar:
204 : : {
205 : 0 : struct ECPGgeneric_varchar *variable =
206 : : (struct ECPGgeneric_varchar *) var;
207 : :
208 [ # # ]: 0 : if (varcharsize == 0)
2880 tgl@sss.pgh.pa.us 209 : 0 : memcpy(variable->arr, value, strlen(value));
210 : : else
8451 meskes@postgresql.or 211 : 0 : strncpy(variable->arr, value, varcharsize);
212 : :
213 : 0 : variable->len = strlen(value);
214 [ # # # # ]: 0 : if (varcharsize > 0 && variable->len > varcharsize)
215 : 0 : variable->len = varcharsize;
216 : : }
217 : 0 : break;
218 : 0 : default:
6789 219 : 0 : ecpg_raise(lineno, ECPG_VAR_NOT_CHAR, ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION, NULL);
3183 peter_e@gmx.net 220 : 0 : return false;
221 : : }
222 : :
3183 peter_e@gmx.net 223 :CBC 30 : return true;
224 : : }
225 : :
226 : : #define RETURN_IF_NO_DATA if (ntuples < 1) \
227 : : { \
228 : : va_end(args); \
229 : : ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL); \
230 : : return false; \
231 : : }
232 : :
233 : : bool
7461 meskes@postgresql.or 234 : 62 : ECPGget_desc(int lineno, const char *desc_name, int index,...)
235 : : {
236 : : va_list args;
237 : : PGresult *ECPGresult;
238 : : enum ECPGdtype type;
239 : : int ntuples,
240 : : act_tuple;
241 : : struct variable data_var;
8360 bruce@momjian.us 242 : 62 : struct sqlca_t *sqlca = ECPGget_sqlca();
286 michael@paquier.xyz 243 :GNC 62 : bool alloc_failed = (sqlca == NULL);
244 : :
245 [ - + ]: 62 : if (alloc_failed)
246 : : {
3977 meskes@postgresql.or 247 :UBC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
248 : : ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
249 : 0 : return false;
250 : : }
251 : :
8451 meskes@postgresql.or 252 :CBC 62 : va_start(args, index);
6789 253 : 62 : ecpg_init_sqlca(sqlca);
254 : 62 : ECPGresult = ecpg_result_by_descriptor(lineno, desc_name);
8451 255 [ - + ]: 62 : if (!ECPGresult)
256 : : {
5165 peter_e@gmx.net 257 :UBC 0 : va_end(args);
3183 258 : 0 : return false;
259 : : }
260 : :
8451 meskes@postgresql.or 261 :CBC 62 : ntuples = PQntuples(ECPGresult);
262 : :
263 [ + - - + ]: 62 : if (index < 1 || index > PQnfields(ECPGresult))
264 : : {
6789 meskes@postgresql.or 265 :UBC 0 : ecpg_raise(lineno, ECPG_INVALID_DESCRIPTOR_INDEX, ECPG_SQLSTATE_INVALID_DESCRIPTOR_INDEX, NULL);
5165 peter_e@gmx.net 266 : 0 : va_end(args);
3183 267 : 0 : return false;
268 : : }
269 : :
6789 meskes@postgresql.or 270 :CBC 62 : ecpg_log("ECPGget_desc: reading items for tuple %d\n", index);
8451 271 : 62 : --index;
272 : :
273 : 62 : type = va_arg(args, enum ECPGdtype);
274 : :
275 : 62 : memset(&data_var, 0, sizeof data_var);
276 : 62 : data_var.type = ECPGt_EORT;
277 : 62 : data_var.ind_type = ECPGt_NO_INDICATOR;
278 : :
279 [ + + ]: 236 : while (type != ECPGd_EODT)
280 : : {
281 : : char type_str[20];
282 : : long varcharsize;
283 : : long offset;
284 : : long arrsize;
285 : : enum ECPGttype vartype;
286 : : void *var;
287 : :
288 : 174 : vartype = va_arg(args, enum ECPGttype);
289 : 174 : var = va_arg(args, void *);
290 : 174 : varcharsize = va_arg(args, long);
291 : 174 : arrsize = va_arg(args, long);
292 : 174 : offset = va_arg(args, long);
293 : :
294 [ + + + - : 174 : switch (type)
- + + + +
+ + - +
- ]
295 : : {
296 : 26 : case (ECPGd_indicator):
5954 297 [ - + ]: 26 : RETURN_IF_NO_DATA;
8451 298 : 26 : data_var.ind_type = vartype;
299 : 26 : data_var.ind_pointer = var;
300 : 26 : data_var.ind_varcharsize = varcharsize;
301 : 26 : data_var.ind_arrsize = arrsize;
302 : 26 : data_var.ind_offset = offset;
7214 303 [ + + - + ]: 26 : if (data_var.ind_arrsize == 0 || data_var.ind_varcharsize == 0)
8451 304 : 10 : data_var.ind_value = *((void **) (data_var.ind_pointer));
305 : : else
306 : 16 : data_var.ind_value = data_var.ind_pointer;
307 : 26 : break;
308 : :
309 : 29 : case ECPGd_data:
5954 310 [ - + ]: 29 : RETURN_IF_NO_DATA;
8451 311 : 29 : data_var.type = vartype;
312 : 29 : data_var.pointer = var;
313 : 29 : data_var.varcharsize = varcharsize;
314 : 29 : data_var.arrsize = arrsize;
315 : 29 : data_var.offset = offset;
316 [ + + - + ]: 29 : if (data_var.arrsize == 0 || data_var.varcharsize == 0)
317 : 10 : data_var.value = *((void **) (data_var.pointer));
318 : : else
319 : 19 : data_var.value = data_var.pointer;
320 : 29 : break;
321 : :
322 : 30 : case ECPGd_name:
323 [ - + ]: 30 : if (!get_char_item(lineno, var, vartype, PQfname(ECPGresult, index), varcharsize))
324 : : {
5165 peter_e@gmx.net 325 :UBC 0 : va_end(args);
3183 326 : 0 : return false;
327 : : }
328 : :
6789 meskes@postgresql.or 329 :CBC 30 : ecpg_log("ECPGget_desc: NAME = %s\n", PQfname(ECPGresult, index));
8451 330 : 30 : break;
331 : :
8451 meskes@postgresql.or 332 :UBC 0 : case ECPGd_nullable:
333 [ # # ]: 0 : if (!get_int_item(lineno, var, vartype, 1))
334 : : {
5165 peter_e@gmx.net 335 : 0 : va_end(args);
3183 336 : 0 : return false;
337 : : }
338 : :
8451 meskes@postgresql.or 339 : 0 : break;
340 : :
341 : 0 : case ECPGd_key_member:
342 [ # # ]: 0 : if (!get_int_item(lineno, var, vartype, 0))
343 : : {
5165 peter_e@gmx.net 344 : 0 : va_end(args);
3183 345 : 0 : return false;
346 : : }
347 : :
8451 meskes@postgresql.or 348 : 0 : break;
349 : :
8451 meskes@postgresql.or 350 :CBC 14 : case ECPGd_scale:
351 [ - + ]: 14 : if (!get_int_item(lineno, var, vartype, (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff))
352 : : {
5165 peter_e@gmx.net 353 :UBC 0 : va_end(args);
3183 354 : 0 : return false;
355 : : }
356 : :
6789 meskes@postgresql.or 357 :CBC 14 : ecpg_log("ECPGget_desc: SCALE = %d\n", (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff);
8451 358 : 14 : break;
359 : :
360 : 14 : case ECPGd_precision:
361 [ - + ]: 14 : if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) >> 16))
362 : : {
5165 peter_e@gmx.net 363 :UBC 0 : va_end(args);
3183 364 : 0 : return false;
365 : : }
366 : :
6789 meskes@postgresql.or 367 :CBC 14 : ecpg_log("ECPGget_desc: PRECISION = %d\n", PQfmod(ECPGresult, index) >> 16);
8451 368 : 14 : break;
369 : :
370 : 14 : case ECPGd_octet:
371 [ - + ]: 14 : if (!get_int_item(lineno, var, vartype, PQfsize(ECPGresult, index)))
372 : : {
5165 peter_e@gmx.net 373 :UBC 0 : va_end(args);
3183 374 : 0 : return false;
375 : : }
376 : :
6789 meskes@postgresql.or 377 :CBC 14 : ecpg_log("ECPGget_desc: OCTET_LENGTH = %d\n", PQfsize(ECPGresult, index));
8451 378 : 14 : break;
379 : :
380 : 15 : case ECPGd_length:
381 [ - + ]: 15 : if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) - VARHDRSZ))
382 : : {
5165 peter_e@gmx.net 383 :UBC 0 : va_end(args);
3183 384 : 0 : return false;
385 : : }
386 : :
6789 meskes@postgresql.or 387 :CBC 15 : ecpg_log("ECPGget_desc: LENGTH = %d\n", PQfmod(ECPGresult, index) - VARHDRSZ);
8451 388 : 15 : break;
389 : :
390 : 14 : case ECPGd_type:
6789 391 [ - + ]: 14 : if (!get_int_item(lineno, var, vartype, ecpg_dynamic_type(PQftype(ECPGresult, index))))
392 : : {
5165 peter_e@gmx.net 393 :UBC 0 : va_end(args);
3183 394 : 0 : return false;
395 : : }
396 : :
6789 meskes@postgresql.or 397 :CBC 14 : ecpg_log("ECPGget_desc: TYPE = %d\n", ecpg_dynamic_type(PQftype(ECPGresult, index)));
8451 398 : 14 : break;
399 : :
400 : 4 : case ECPGd_di_code:
6789 401 [ - + ]: 4 : if (!get_int_item(lineno, var, vartype, ecpg_dynamic_type_DDT(PQftype(ECPGresult, index))))
402 : : {
5165 peter_e@gmx.net 403 :UBC 0 : va_end(args);
3183 404 : 0 : return false;
405 : : }
406 : :
6789 meskes@postgresql.or 407 :CBC 4 : ecpg_log("ECPGget_desc: TYPE = %d\n", ecpg_dynamic_type_DDT(PQftype(ECPGresult, index)));
8451 408 : 4 : break;
409 : :
8451 meskes@postgresql.or 410 :UBC 0 : case ECPGd_cardinality:
411 [ # # ]: 0 : if (!get_int_item(lineno, var, vartype, PQntuples(ECPGresult)))
412 : : {
5165 peter_e@gmx.net 413 : 0 : va_end(args);
3183 414 : 0 : return false;
415 : : }
416 : :
6789 meskes@postgresql.or 417 : 0 : ecpg_log("ECPGget_desc: CARDINALITY = %d\n", PQntuples(ECPGresult));
8451 418 : 0 : break;
419 : :
8451 meskes@postgresql.or 420 :CBC 14 : case ECPGd_ret_length:
421 : : case ECPGd_ret_octet:
422 : :
5954 423 [ - + ]: 14 : RETURN_IF_NO_DATA;
424 : :
425 : : /*
426 : : * this is like ECPGstore_result
427 : : */
8451 428 [ + - - + ]: 14 : if (arrsize > 0 && ntuples > arrsize)
429 : : {
5351 peter_e@gmx.net 430 :UBC 0 : ecpg_log("ECPGget_desc on line %d: incorrect number of matches; %d don't fit into array of %ld\n",
431 : : lineno, ntuples, arrsize);
6789 meskes@postgresql.or 432 : 0 : ecpg_raise(lineno, ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);
5165 peter_e@gmx.net 433 : 0 : va_end(args);
8451 meskes@postgresql.or 434 : 0 : return false;
435 : : }
436 : : /* allocate storage if needed */
7254 meskes@postgresql.or 437 [ - + - - ]:CBC 14 : if (arrsize == 0 && *(void **) var == NULL)
438 : : {
523 peter@eisentraut.org 439 :UBC 0 : void *mem = ecpg_auto_alloc(offset * ntuples, lineno);
440 : :
7258 meskes@postgresql.or 441 [ # # ]: 0 : if (!mem)
442 : : {
5165 peter_e@gmx.net 443 : 0 : va_end(args);
7258 meskes@postgresql.or 444 : 0 : return false;
445 : : }
8451 446 : 0 : *(void **) var = mem;
447 : 0 : var = mem;
448 : : }
449 : :
8451 meskes@postgresql.or 450 [ + + ]:CBC 28 : for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
451 : : {
452 [ - + ]: 14 : if (!get_int_item(lineno, var, vartype, PQgetlength(ECPGresult, act_tuple, index)))
453 : : {
5165 peter_e@gmx.net 454 :UBC 0 : va_end(args);
3183 455 : 0 : return false;
456 : : }
8451 meskes@postgresql.or 457 :CBC 14 : var = (char *) var + offset;
6789 458 : 14 : ecpg_log("ECPGget_desc: RETURNED[%d] = %d\n", act_tuple, PQgetlength(ECPGresult, act_tuple, index));
459 : : }
8451 460 : 14 : break;
461 : :
8451 meskes@postgresql.or 462 :UBC 0 : default:
463 : 0 : snprintf(type_str, sizeof(type_str), "%d", type);
6789 464 : 0 : ecpg_raise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str);
5165 peter_e@gmx.net 465 : 0 : va_end(args);
3183 466 : 0 : return false;
467 : : }
468 : :
8451 meskes@postgresql.or 469 :CBC 174 : type = va_arg(args, enum ECPGdtype);
470 : : }
471 : :
472 [ + + ]: 62 : if (data_var.type != ECPGt_EORT)
473 : : {
474 : : struct statement stmt;
475 : :
2661 tgl@sss.pgh.pa.us 476 : 29 : memset(&stmt, 0, sizeof stmt);
477 : 29 : stmt.lineno = lineno;
478 : :
479 : : /* desperate try to guess something sensible */
4 andrew@dunslane.net 480 : 29 : stmt.connection = ecpg_get_connection(NULL);
481 [ + + ]: 29 : if (stmt.connection == NULL)
482 : : {
483 : 1 : ecpg_raise(lineno, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST,
484 : 1 : ecpg_gettext("NULL"));
485 : 1 : va_end(args);
486 : 1 : return false;
487 : : }
488 : :
489 : : /* Make sure we do NOT honor the locale for numeric input */
490 : : /* since the database gives the standard decimal point */
491 : : /* (see comments in execute.c) */
492 : : #ifdef HAVE_USELOCALE
493 : :
494 : : /*
495 : : * To get here, the above PQnfields() test must have found nonzero
496 : : * fields. One needs a connection to create such a descriptor. (EXEC
497 : : * SQL SET DESCRIPTOR can populate the descriptor's "items", but it
498 : : * can't change the descriptor's PQnfields().) Any successful
499 : : * connection initializes ecpg_clocale.
500 : : */
403 peter@eisentraut.org 501 [ - + ]: 28 : Assert(ecpg_clocale);
502 : 28 : stmt.oldlocale = uselocale(ecpg_clocale);
503 : : #else
504 : : #ifdef WIN32
505 : : stmt.oldthreadlocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
506 : : #endif
507 : : stmt.oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL),
508 : : lineno, &alloc_failed);
509 : : if (alloc_failed)
510 : : {
511 : : va_end(args);
512 : : return false;
513 : : }
514 : :
515 : : setlocale(LC_NUMERIC, "C");
516 : : #endif
517 : :
6789 meskes@postgresql.or 518 : 28 : ecpg_store_result(ECPGresult, index, &stmt, &data_var);
519 : :
520 : : #ifdef HAVE_USELOCALE
403 peter@eisentraut.org 521 [ + - ]: 28 : if (stmt.oldlocale != (locale_t) 0)
522 : 28 : uselocale(stmt.oldlocale);
523 : : #else
524 : : if (stmt.oldlocale)
525 : : {
526 : : setlocale(LC_NUMERIC, stmt.oldlocale);
527 : : ecpg_free(stmt.oldlocale);
528 : : }
529 : : #ifdef WIN32
530 : : if (stmt.oldthreadlocale != -1)
531 : : _configthreadlocale(stmt.oldthreadlocale);
532 : : #endif
533 : : #endif
534 : : }
7244 meskes@postgresql.or 535 [ + + + - ]: 33 : else if (data_var.ind_type != ECPGt_NO_INDICATOR && data_var.ind_pointer != NULL)
536 : :
537 : : /*
538 : : * ind_type != NO_INDICATOR should always have ind_pointer != NULL but
539 : : * since this might be changed manually in the .c file let's play it
540 : : * safe
541 : : */
542 : : {
543 : : /*
544 : : * this is like ECPGstore_result but since we don't have a data
545 : : * variable at hand, we can't call it
546 : : */
8451 547 [ + - - + ]: 14 : if (data_var.ind_arrsize > 0 && ntuples > data_var.ind_arrsize)
548 : : {
5351 peter_e@gmx.net 549 :UBC 0 : ecpg_log("ECPGget_desc on line %d: incorrect number of matches (indicator); %d don't fit into array of %ld\n",
550 : : lineno, ntuples, data_var.ind_arrsize);
6789 meskes@postgresql.or 551 : 0 : ecpg_raise(lineno, ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);
5165 peter_e@gmx.net 552 : 0 : va_end(args);
8451 meskes@postgresql.or 553 : 0 : return false;
554 : : }
555 : :
556 : : /* allocate storage if needed */
7244 meskes@postgresql.or 557 [ - + - - ]:CBC 14 : if (data_var.ind_arrsize == 0 && data_var.ind_value == NULL)
558 : : {
523 peter@eisentraut.org 559 :UBC 0 : void *mem = ecpg_auto_alloc(data_var.ind_offset * ntuples, lineno);
560 : :
7258 meskes@postgresql.or 561 [ # # ]: 0 : if (!mem)
562 : : {
5165 peter_e@gmx.net 563 : 0 : va_end(args);
7258 meskes@postgresql.or 564 : 0 : return false;
565 : : }
8451 566 : 0 : *(void **) data_var.ind_pointer = mem;
567 : 0 : data_var.ind_value = mem;
568 : : }
569 : :
8451 meskes@postgresql.or 570 [ + + ]:CBC 28 : for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
571 : : {
572 [ - + ]: 14 : if (!get_int_item(lineno, data_var.ind_value, data_var.ind_type, -PQgetisnull(ECPGresult, act_tuple, index)))
573 : : {
5165 peter_e@gmx.net 574 :UBC 0 : va_end(args);
3183 575 : 0 : return false;
576 : : }
8451 meskes@postgresql.or 577 :CBC 14 : data_var.ind_value = (char *) data_var.ind_value + data_var.ind_offset;
6789 578 : 14 : ecpg_log("ECPGget_desc: INDICATOR[%d] = %d\n", act_tuple, -PQgetisnull(ECPGresult, act_tuple, index));
579 : : }
580 : : }
8360 bruce@momjian.us 581 : 61 : sqlca->sqlerrd[2] = ntuples;
5165 peter_e@gmx.net 582 : 61 : va_end(args);
3183 583 : 61 : return true;
584 : : }
585 : :
586 : : #undef RETURN_IF_NO_DATA
587 : :
588 : : bool
7461 meskes@postgresql.or 589 : 1 : ECPGset_desc_header(int lineno, const char *desc_name, int count)
590 : : {
6789 591 : 1 : struct descriptor *desc = ecpg_find_desc(lineno, desc_name);
592 : :
7974 593 [ - + ]: 1 : if (desc == NULL)
7974 meskes@postgresql.or 594 :UBC 0 : return false;
7974 meskes@postgresql.or 595 :CBC 1 : desc->count = count;
596 : 1 : return true;
597 : : }
598 : :
599 : : static void
2633 600 : 13 : set_desc_attr(struct descriptor_item *desc_item, struct variable *var,
601 : : char *tobeinserted)
602 : : {
603 [ + + ]: 13 : if (var->type != ECPGt_bytea)
604 : 11 : desc_item->is_binary = false;
605 : :
606 : : else
607 : : {
2108 michael@paquier.xyz 608 : 2 : struct ECPGgeneric_bytea *variable =
609 : : (struct ECPGgeneric_bytea *) (var->value);
610 : :
2633 meskes@postgresql.or 611 : 2 : desc_item->is_binary = true;
612 : 2 : desc_item->data_len = variable->len;
613 : : }
614 : :
2540 tgl@sss.pgh.pa.us 615 : 13 : ecpg_free(desc_item->data); /* free() takes care of a potential NULL value */
439 peter@eisentraut.org 616 : 13 : desc_item->data = tobeinserted;
2633 meskes@postgresql.or 617 : 13 : }
618 : :
619 : :
620 : : bool
7461 621 : 13 : ECPGset_desc(int lineno, const char *desc_name, int index,...)
622 : : {
623 : : va_list args;
624 : : struct descriptor *desc;
625 : : struct descriptor_item *desc_item;
626 : : struct variable *var;
627 : :
6789 628 : 13 : desc = ecpg_find_desc(lineno, desc_name);
7979 629 [ - + ]: 13 : if (desc == NULL)
7979 meskes@postgresql.or 630 :UBC 0 : return false;
631 : :
7979 meskes@postgresql.or 632 [ + + ]:CBC 20 : for (desc_item = desc->items; desc_item; desc_item = desc_item->next)
633 : : {
634 [ + + ]: 14 : if (desc_item->num == index)
635 : 7 : break;
636 : : }
637 : :
638 [ + + ]: 13 : if (desc_item == NULL)
639 : : {
6789 640 : 6 : desc_item = (struct descriptor_item *) ecpg_alloc(sizeof(*desc_item), lineno);
7258 641 [ - + ]: 6 : if (!desc_item)
7258 meskes@postgresql.or 642 :UBC 0 : return false;
7979 meskes@postgresql.or 643 :CBC 6 : desc_item->num = index;
6839 644 [ + - ]: 6 : if (desc->count < index)
645 : 6 : desc->count = index;
7979 646 : 6 : desc_item->next = desc->items;
647 : 6 : desc->items = desc_item;
648 : : }
649 : :
6789 650 [ - + ]: 13 : if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
7919 bruce@momjian.us 651 :UBC 0 : return false;
652 : :
7979 meskes@postgresql.or 653 :CBC 13 : va_start(args, index);
654 : :
655 : : for (;;)
656 : 17 : {
657 : : enum ECPGdtype itemtype;
6172 bruce@momjian.us 658 : 30 : char *tobeinserted = NULL;
659 : :
7979 meskes@postgresql.or 660 : 30 : itemtype = va_arg(args, enum ECPGdtype);
661 : :
662 [ + + ]: 30 : if (itemtype == ECPGd_EODT)
663 : 13 : break;
664 : :
6948 665 : 17 : var->type = va_arg(args, enum ECPGttype);
666 : 17 : var->pointer = va_arg(args, char *);
667 : :
668 : 17 : var->varcharsize = va_arg(args, long);
669 : 17 : var->arrsize = va_arg(args, long);
670 : 17 : var->offset = va_arg(args, long);
671 : :
672 [ + - - + ]: 17 : if (var->arrsize == 0 || var->varcharsize == 0)
6948 meskes@postgresql.or 673 :UBC 0 : var->value = *((char **) (var->pointer));
674 : : else
6948 meskes@postgresql.or 675 :CBC 17 : var->value = var->pointer;
676 : :
677 : : /*
678 : : * negative values are used to indicate an array without given bounds
679 : : */
680 : : /* reset to zero for us */
681 [ - + ]: 17 : if (var->arrsize < 0)
6948 meskes@postgresql.or 682 :UBC 0 : var->arrsize = 0;
6948 meskes@postgresql.or 683 [ - + ]:CBC 17 : if (var->varcharsize < 0)
6948 meskes@postgresql.or 684 :UBC 0 : var->varcharsize = 0;
685 : :
6948 meskes@postgresql.or 686 :CBC 17 : var->next = NULL;
687 : :
7979 688 [ + + - - : 17 : switch (itemtype)
- - - ]
689 : : {
690 : 13 : case ECPGd_data:
691 : : {
6789 692 [ - + ]: 13 : if (!ecpg_store_input(lineno, true, var, &tobeinserted, false))
693 : : {
6789 meskes@postgresql.or 694 :UBC 0 : ecpg_free(var);
5165 peter_e@gmx.net 695 : 0 : va_end(args);
7919 bruce@momjian.us 696 : 0 : return false;
697 : : }
698 : :
2633 meskes@postgresql.or 699 :CBC 13 : set_desc_attr(desc_item, var, tobeinserted);
7919 bruce@momjian.us 700 : 13 : tobeinserted = NULL;
701 : 13 : break;
702 : : }
703 : :
7979 meskes@postgresql.or 704 : 4 : case ECPGd_indicator:
7975 705 : 4 : set_int_item(lineno, &desc_item->indicator, var->pointer, var->type);
7979 706 : 4 : break;
707 : :
7979 meskes@postgresql.or 708 :UBC 0 : case ECPGd_length:
7975 709 : 0 : set_int_item(lineno, &desc_item->length, var->pointer, var->type);
7979 710 : 0 : break;
711 : :
712 : 0 : case ECPGd_precision:
7975 713 : 0 : set_int_item(lineno, &desc_item->precision, var->pointer, var->type);
7979 714 : 0 : break;
715 : :
716 : 0 : case ECPGd_scale:
7975 717 : 0 : set_int_item(lineno, &desc_item->scale, var->pointer, var->type);
7979 718 : 0 : break;
719 : :
720 : 0 : case ECPGd_type:
7975 721 : 0 : set_int_item(lineno, &desc_item->type, var->pointer, var->type);
7979 722 : 0 : break;
723 : :
724 : 0 : default:
725 : : {
726 : : char type_str[20];
727 : :
7919 bruce@momjian.us 728 : 0 : snprintf(type_str, sizeof(type_str), "%d", itemtype);
6789 meskes@postgresql.or 729 : 0 : ecpg_raise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str);
730 : 0 : ecpg_free(var);
5165 peter_e@gmx.net 731 : 0 : va_end(args);
7919 bruce@momjian.us 732 : 0 : return false;
733 : : }
734 : : }
735 : : }
6789 meskes@postgresql.or 736 :CBC 13 : ecpg_free(var);
5165 peter_e@gmx.net 737 : 13 : va_end(args);
738 : :
7979 meskes@postgresql.or 739 : 13 : return true;
740 : : }
741 : :
742 : : /* Free the descriptor and items in it. */
743 : : static void
3240 tgl@sss.pgh.pa.us 744 : 800015 : descriptor_free(struct descriptor *desc)
745 : : {
746 : : struct descriptor_item *desc_item;
747 : :
6790 meskes@postgresql.or 748 [ + + ]: 800017 : for (desc_item = desc->items; desc_item;)
749 : : {
750 : : struct descriptor_item *di;
751 : :
6789 752 : 2 : ecpg_free(desc_item->data);
6790 753 : 2 : di = desc_item;
754 : 2 : desc_item = desc_item->next;
6789 755 : 2 : ecpg_free(di);
756 : : }
757 : :
758 : 800015 : ecpg_free(desc->name);
6790 759 : 800015 : PQclear(desc->result);
6789 760 : 800015 : ecpg_free(desc);
6790 761 : 800015 : }
762 : :
763 : : bool
8451 764 : 800015 : ECPGdeallocate_desc(int line, const char *name)
765 : : {
766 : : struct descriptor *desc;
767 : : struct descriptor *prev;
8360 bruce@momjian.us 768 : 800015 : struct sqlca_t *sqlca = ECPGget_sqlca();
769 : :
3977 meskes@postgresql.or 770 [ - + ]: 800015 : if (sqlca == NULL)
771 : : {
3977 meskes@postgresql.or 772 :UBC 0 : ecpg_raise(line, ECPG_OUT_OF_MEMORY,
773 : : ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
774 : 0 : return false;
775 : : }
776 : :
6789 meskes@postgresql.or 777 :CBC 800015 : ecpg_init_sqlca(sqlca);
6790 778 [ + - ]: 800020 : for (desc = get_descriptors(), prev = NULL; desc; prev = desc, desc = desc->next)
779 : : {
5243 peter_e@gmx.net 780 [ + + ]: 800020 : if (strcmp(name, desc->name) == 0)
781 : : {
6790 meskes@postgresql.or 782 [ + + ]: 800015 : if (prev)
783 : 5 : prev->next = desc->next;
784 : : else
785 : 800010 : set_descriptors(desc->next);
786 : 800015 : descriptor_free(desc);
8451 787 : 800015 : return true;
788 : : }
789 : : }
6789 meskes@postgresql.or 790 :UBC 0 : ecpg_raise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, name);
8451 791 : 0 : return false;
792 : : }
793 : :
794 : : /* Deallocate all descriptors in the list */
795 : : static void
3240 tgl@sss.pgh.pa.us 796 : 0 : descriptor_deallocate_all(struct descriptor *list)
797 : : {
6790 meskes@postgresql.or 798 [ # # ]: 0 : while (list)
799 : : {
800 : 0 : struct descriptor *next = list->next;
801 : :
802 : 0 : descriptor_free(list);
803 : 0 : list = next;
804 : : }
805 : 0 : }
806 : :
807 : : bool
8451 meskes@postgresql.or 808 :CBC 800019 : ECPGallocate_desc(int line, const char *name)
809 : : {
810 : : struct descriptor *new;
8360 bruce@momjian.us 811 : 800019 : struct sqlca_t *sqlca = ECPGget_sqlca();
812 : :
3977 meskes@postgresql.or 813 [ - + ]: 800019 : if (sqlca == NULL)
814 : : {
3977 meskes@postgresql.or 815 :UBC 0 : ecpg_raise(line, ECPG_OUT_OF_MEMORY,
816 : : ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
817 : 0 : return false;
818 : : }
819 : :
6789 meskes@postgresql.or 820 :CBC 800019 : ecpg_init_sqlca(sqlca);
821 : 800019 : new = (struct descriptor *) ecpg_alloc(sizeof(struct descriptor), line);
8451 822 [ - + ]: 800019 : if (!new)
8451 meskes@postgresql.or 823 :UBC 0 : return false;
6790 meskes@postgresql.or 824 :CBC 800019 : new->next = get_descriptors();
6789 825 : 800019 : new->name = ecpg_alloc(strlen(name) + 1, line);
8451 826 [ - + ]: 800019 : if (!new->name)
827 : : {
6789 meskes@postgresql.or 828 :UBC 0 : ecpg_free(new);
8451 829 : 0 : return false;
830 : : }
7974 meskes@postgresql.or 831 :CBC 800019 : new->count = -1;
7979 832 : 800019 : new->items = NULL;
8451 833 : 800019 : new->result = PQmakeEmptyPGresult(NULL, 0);
834 [ - + ]: 800019 : if (!new->result)
835 : : {
6789 meskes@postgresql.or 836 :UBC 0 : ecpg_free(new->name);
837 : 0 : ecpg_free(new);
838 : 0 : ecpg_raise(line, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
8451 839 : 0 : return false;
840 : : }
8451 meskes@postgresql.or 841 :CBC 800019 : strcpy(new->name, name);
6790 842 : 800019 : set_descriptors(new);
8451 843 : 800019 : return true;
844 : : }
845 : :
846 : : /* Find descriptor with name in the connection. */
847 : : struct descriptor *
6789 848 : 120 : ecpg_find_desc(int line, const char *name)
849 : : {
850 : : struct descriptor *desc;
851 : :
6790 852 [ + - ]: 169 : for (desc = get_descriptors(); desc; desc = desc->next)
853 : : {
854 [ + + ]: 169 : if (strcmp(name, desc->name) == 0)
855 : 120 : return desc;
856 : : }
857 : :
6789 meskes@postgresql.or 858 :UBC 0 : ecpg_raise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, name);
6746 bruce@momjian.us 859 : 0 : return NULL; /* not found */
860 : : }
861 : :
862 : : bool
5912 bruce@momjian.us 863 :CBC 21 : ECPGdescribe(int line, int compat, bool input, const char *connection_name, const char *stmt_name,...)
864 : : {
5954 meskes@postgresql.or 865 : 21 : bool ret = false;
866 : : struct connection *con;
867 : : struct prepared_statement *prep;
868 : : PGresult *res;
869 : : va_list args;
870 : :
871 : : /* DESCRIBE INPUT is not yet supported */
872 [ - + ]: 21 : if (input)
873 : : {
5954 meskes@postgresql.or 874 :UBC 0 : ecpg_raise(line, ECPG_UNSUPPORTED, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, "DESCRIBE INPUT");
875 : 0 : return ret;
876 : : }
877 : :
2419 tgl@sss.pgh.pa.us 878 :CBC 21 : con = ecpg_get_connection(connection_name);
5954 meskes@postgresql.or 879 [ - + ]: 21 : if (!con)
880 : : {
5954 meskes@postgresql.or 881 [ # # ]:UBC 0 : ecpg_raise(line, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST,
2419 tgl@sss.pgh.pa.us 882 : 0 : connection_name ? connection_name : ecpg_gettext("NULL"));
5954 meskes@postgresql.or 883 : 0 : return ret;
884 : : }
5954 meskes@postgresql.or 885 :CBC 21 : prep = ecpg_find_prepared_statement(stmt_name, con, NULL);
886 [ - + ]: 21 : if (!prep)
887 : : {
5954 meskes@postgresql.or 888 :UBC 0 : ecpg_raise(line, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt_name);
889 : 0 : return ret;
890 : : }
891 : :
5954 meskes@postgresql.or 892 :CBC 21 : va_start(args, stmt_name);
893 : :
894 : : for (;;)
895 : 21 : {
896 : : enum ECPGttype type;
897 : : void *ptr;
898 : :
899 : : /* variable type */
900 : 42 : type = va_arg(args, enum ECPGttype);
901 : :
902 [ + + ]: 42 : if (type == ECPGt_EORT)
903 : 21 : break;
904 : :
905 : : /* rest of variable parameters */
906 : 21 : ptr = va_arg(args, void *);
3240 tgl@sss.pgh.pa.us 907 : 21 : (void) va_arg(args, long); /* skip args */
5502 908 : 21 : (void) va_arg(args, long);
909 : 21 : (void) va_arg(args, long);
910 : :
911 : : /* variable indicator */
912 : 21 : (void) va_arg(args, enum ECPGttype);
913 : 21 : (void) va_arg(args, void *); /* skip args */
914 : 21 : (void) va_arg(args, long);
915 : 21 : (void) va_arg(args, long);
916 : 21 : (void) va_arg(args, long);
917 : :
5954 meskes@postgresql.or 918 [ + + - ]: 21 : switch (type)
919 : : {
920 : 9 : case ECPGt_descriptor:
921 : : {
5912 bruce@momjian.us 922 : 9 : char *name = ptr;
923 : 9 : struct descriptor *desc = ecpg_find_desc(line, name);
924 : :
925 [ - + ]: 9 : if (desc == NULL)
5912 bruce@momjian.us 926 :UBC 0 : break;
927 : :
5954 meskes@postgresql.or 928 :CBC 9 : res = PQdescribePrepared(con->connection, stmt_name);
929 [ - + ]: 9 : if (!ecpg_check_PQresult(res, line, con->connection, compat))
5954 meskes@postgresql.or 930 :UBC 0 : break;
931 : :
1402 peter@eisentraut.org 932 :CBC 9 : PQclear(desc->result);
933 : :
5912 bruce@momjian.us 934 : 9 : desc->result = res;
935 : 9 : ret = true;
936 : 9 : break;
937 : : }
938 : 12 : case ECPGt_sqlda:
939 : : {
940 [ + + - + ]: 12 : if (INFORMIX_MODE(compat))
5954 meskes@postgresql.or 941 : 6 : {
5912 bruce@momjian.us 942 : 6 : struct sqlda_compat **_sqlda = ptr;
943 : : struct sqlda_compat *sqlda;
944 : :
945 : 6 : res = PQdescribePrepared(con->connection, stmt_name);
946 [ - + ]: 6 : if (!ecpg_check_PQresult(res, line, con->connection, compat))
5912 bruce@momjian.us 947 :UBC 0 : break;
948 : :
5912 bruce@momjian.us 949 :CBC 6 : sqlda = ecpg_build_compat_sqlda(line, res, -1, compat);
950 [ + - ]: 6 : if (sqlda)
951 : : {
952 : 6 : struct sqlda_compat *sqlda_old = *_sqlda;
953 : : struct sqlda_compat *sqlda_old1;
954 : :
955 [ - + ]: 6 : while (sqlda_old)
956 : : {
5912 bruce@momjian.us 957 :UBC 0 : sqlda_old1 = sqlda_old->desc_next;
958 : 0 : free(sqlda_old);
959 : 0 : sqlda_old = sqlda_old1;
960 : : }
961 : :
5912 bruce@momjian.us 962 :CBC 6 : *_sqlda = sqlda;
963 : 6 : ret = true;
964 : : }
965 : :
966 : 6 : PQclear(res);
967 : : }
968 : : else
969 : : {
970 : 6 : struct sqlda_struct **_sqlda = ptr;
971 : : struct sqlda_struct *sqlda;
972 : :
973 : 6 : res = PQdescribePrepared(con->connection, stmt_name);
974 [ - + ]: 6 : if (!ecpg_check_PQresult(res, line, con->connection, compat))
5912 bruce@momjian.us 975 :UBC 0 : break;
976 : :
5912 bruce@momjian.us 977 :CBC 6 : sqlda = ecpg_build_native_sqlda(line, res, -1, compat);
978 [ + - ]: 6 : if (sqlda)
979 : : {
980 : 6 : struct sqlda_struct *sqlda_old = *_sqlda;
981 : : struct sqlda_struct *sqlda_old1;
982 : :
983 [ - + ]: 6 : while (sqlda_old)
984 : : {
5912 bruce@momjian.us 985 :UBC 0 : sqlda_old1 = sqlda_old->desc_next;
986 : 0 : free(sqlda_old);
987 : 0 : sqlda_old = sqlda_old1;
988 : : }
989 : :
5912 bruce@momjian.us 990 :CBC 6 : *_sqlda = sqlda;
991 : 6 : ret = true;
992 : : }
993 : :
994 : 6 : PQclear(res);
995 : : }
996 : 12 : break;
997 : : }
5954 meskes@postgresql.or 998 : 21 : default:
999 : : /* nothing else may come */
1000 : : ;
1001 : : }
1002 : : }
1003 : :
1004 : 21 : va_end(args);
1005 : :
1006 : 21 : return ret;
1007 : : }
|