~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to src/interfaces/ecpg/ecpglib/descriptor.c

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* dynamic SQL support routines
 
2
 *
 
3
 * $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.12 2004-08-29 05:06:59 momjian Exp $
 
4
 */
 
5
 
 
6
#define POSTGRES_ECPG_INTERNAL
 
7
#include "postgres_fe.h"
 
8
#include "pg_type.h"
 
9
 
 
10
#include "ecpgtype.h"
 
11
#include "ecpglib.h"
 
12
#include "ecpgerrno.h"
 
13
#include "extern.h"
 
14
#include "sqlca.h"
 
15
#include "sql3types.h"
 
16
 
 
17
struct descriptor *all_descriptors = NULL;
 
18
 
 
19
/* old internal convenience function that might go away later */
 
20
static PGresult
 
21
                   *
 
22
ECPGresultByDescriptor(int line, const char *name)
 
23
{
 
24
        PGresult  **resultpp = ECPGdescriptor_lvalue(line, name);
 
25
 
 
26
        if (resultpp)
 
27
                return *resultpp;
 
28
        return NULL;
 
29
}
 
30
 
 
31
static unsigned int
 
32
ECPGDynamicType_DDT(Oid type)
 
33
{
 
34
        switch (type)
 
35
        {
 
36
                case DATEOID:
 
37
                        return SQL3_DDT_DATE;
 
38
                case TIMEOID:
 
39
                        return SQL3_DDT_TIME;
 
40
                case TIMESTAMPOID:
 
41
                        return SQL3_DDT_TIMESTAMP;
 
42
                case TIMESTAMPTZOID:
 
43
                        return SQL3_DDT_TIMESTAMP_WITH_TIME_ZONE;
 
44
                case TIMETZOID:
 
45
                        return SQL3_DDT_TIME_WITH_TIME_ZONE;
 
46
                default:
 
47
                        return SQL3_DDT_ILLEGAL;
 
48
        }
 
49
}
 
50
 
 
51
bool
 
52
ECPGget_desc_header(int lineno, char *desc_name, int *count)
 
53
{
 
54
        PGresult   *ECPGresult;
 
55
        struct sqlca_t *sqlca = ECPGget_sqlca();
 
56
 
 
57
        ECPGinit_sqlca(sqlca);
 
58
        ECPGresult = ECPGresultByDescriptor(lineno, desc_name);
 
59
        if (!ECPGresult)
 
60
                return false;
 
61
 
 
62
        *count = PQnfields(ECPGresult);
 
63
        sqlca->sqlerrd[2] = 1;
 
64
        ECPGlog("ECPGget_desc_header: found %d attributes.\n", *count);
 
65
        return true;
 
66
}
 
67
 
 
68
static bool
 
69
get_int_item(int lineno, void *var, enum ECPGttype vartype, int value)
 
70
{
 
71
        switch (vartype)
 
72
        {
 
73
                case ECPGt_short:
 
74
                        *(short *) var = (short) value;
 
75
                        break;
 
76
                case ECPGt_int:
 
77
                        *(int *) var = (int) value;
 
78
                        break;
 
79
                case ECPGt_long:
 
80
                        *(long *) var = (long) value;
 
81
                        break;
 
82
                case ECPGt_unsigned_short:
 
83
                        *(unsigned short *) var = (unsigned short) value;
 
84
                        break;
 
85
                case ECPGt_unsigned_int:
 
86
                        *(unsigned int *) var = (unsigned int) value;
 
87
                        break;
 
88
                case ECPGt_unsigned_long:
 
89
                        *(unsigned long *) var = (unsigned long) value;
 
90
                        break;
 
91
#ifdef HAVE_LONG_LONG_INT_64
 
92
                case ECPGt_long_long:
 
93
                        *(long long int *) var = (long long int) value;
 
94
                        break;
 
95
                case ECPGt_unsigned_long_long:
 
96
                        *(unsigned long long int *) var = (unsigned long long int) value;
 
97
                        break;
 
98
#endif   /* HAVE_LONG_LONG_INT_64 */
 
99
                case ECPGt_float:
 
100
                        *(float *) var = (float) value;
 
101
                        break;
 
102
                case ECPGt_double:
 
103
                        *(double *) var = (double) value;
 
104
                        break;
 
105
                default:
 
106
                        ECPGraise(lineno, ECPG_VAR_NOT_NUMERIC, ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION, NULL);
 
107
                        return (false);
 
108
        }
 
109
 
 
110
        return (true);
 
111
}
 
112
 
 
113
static bool
 
114
set_int_item(int lineno, int *target, const void *var, enum ECPGttype vartype)
 
115
{
 
116
        switch (vartype)
 
117
        {
 
118
                case ECPGt_short:
 
119
                        *target = *(short *) var;
 
120
                        break;
 
121
                case ECPGt_int:
 
122
                        *target = *(int *) var;
 
123
                        break;
 
124
                case ECPGt_long:
 
125
                        *target = *(long *) var;
 
126
                        break;
 
127
                case ECPGt_unsigned_short:
 
128
                        *target = *(unsigned short *) var;
 
129
                        break;
 
130
                case ECPGt_unsigned_int:
 
131
                        *target = *(unsigned int *) var;
 
132
                        break;
 
133
                case ECPGt_unsigned_long:
 
134
                        *target = *(unsigned long *) var;
 
135
                        break;
 
136
#ifdef HAVE_LONG_LONG_INT_64
 
137
                case ECPGt_long_long:
 
138
                        *target = *(long long int *) var;
 
139
                        break;
 
140
                case ECPGt_unsigned_long_long:
 
141
                        *target = *(unsigned long long int *) var;
 
142
                        break;
 
143
#endif   /* HAVE_LONG_LONG_INT_64 */
 
144
                case ECPGt_float:
 
145
                        *target = *(float *) var;
 
146
                        break;
 
147
                case ECPGt_double:
 
148
                        *target = *(double *) var;
 
149
                        break;
 
150
                default:
 
151
                        ECPGraise(lineno, ECPG_VAR_NOT_NUMERIC, ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION, NULL);
 
152
                        return (false);
 
153
        }
 
154
 
 
155
        return true;
 
156
}
 
157
 
 
158
static bool
 
159
get_char_item(int lineno, void *var, enum ECPGttype vartype, char *value, int varcharsize)
 
160
{
 
161
        switch (vartype)
 
162
        {
 
163
                case ECPGt_char:
 
164
                case ECPGt_unsigned_char:
 
165
                        strncpy((char *) var, value, varcharsize);
 
166
                        break;
 
167
                case ECPGt_varchar:
 
168
                        {
 
169
                                struct ECPGgeneric_varchar *variable =
 
170
                                (struct ECPGgeneric_varchar *) var;
 
171
 
 
172
                                if (varcharsize == 0)
 
173
                                        strncpy(variable->arr, value, strlen(value));
 
174
                                else
 
175
                                        strncpy(variable->arr, value, varcharsize);
 
176
 
 
177
                                variable->len = strlen(value);
 
178
                                if (varcharsize > 0 && variable->len > varcharsize)
 
179
                                        variable->len = varcharsize;
 
180
                        }
 
181
                        break;
 
182
                default:
 
183
                        ECPGraise(lineno, ECPG_VAR_NOT_CHAR, ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION, NULL);
 
184
                        return (false);
 
185
        }
 
186
 
 
187
        return (true);
 
188
}
 
189
 
 
190
bool
 
191
ECPGget_desc(int lineno, char *desc_name, int index,...)
 
192
{
 
193
        va_list         args;
 
194
        PGresult   *ECPGresult;
 
195
        enum ECPGdtype type;
 
196
        int                     ntuples,
 
197
                                act_tuple;
 
198
        struct variable data_var;
 
199
        struct sqlca_t *sqlca = ECPGget_sqlca();
 
200
 
 
201
        va_start(args, index);
 
202
        ECPGinit_sqlca(sqlca);
 
203
        ECPGresult = ECPGresultByDescriptor(lineno, desc_name);
 
204
        if (!ECPGresult)
 
205
                return (false);
 
206
 
 
207
        ntuples = PQntuples(ECPGresult);
 
208
        if (ntuples < 1)
 
209
        {
 
210
                ECPGraise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
 
211
                return (false);
 
212
        }
 
213
 
 
214
        if (index < 1 || index > PQnfields(ECPGresult))
 
215
        {
 
216
                ECPGraise(lineno, ECPG_INVALID_DESCRIPTOR_INDEX, ECPG_SQLSTATE_INVALID_DESCRIPTOR_INDEX, NULL);
 
217
                return (false);
 
218
        }
 
219
 
 
220
        ECPGlog("ECPGget_desc: reading items for tuple %d\n", index);
 
221
        --index;
 
222
 
 
223
        type = va_arg(args, enum ECPGdtype);
 
224
 
 
225
        memset(&data_var, 0, sizeof data_var);
 
226
        data_var.type = ECPGt_EORT;
 
227
        data_var.ind_type = ECPGt_NO_INDICATOR;
 
228
 
 
229
        while (type != ECPGd_EODT)
 
230
        {
 
231
                char            type_str[20];
 
232
                long            varcharsize;
 
233
                long            offset;
 
234
                long            arrsize;
 
235
                enum ECPGttype vartype;
 
236
                void       *var;
 
237
 
 
238
                vartype = va_arg(args, enum ECPGttype);
 
239
                var = va_arg(args, void *);
 
240
                varcharsize = va_arg(args, long);
 
241
                arrsize = va_arg(args, long);
 
242
                offset = va_arg(args, long);
 
243
 
 
244
                switch (type)
 
245
                {
 
246
                        case (ECPGd_indicator):
 
247
                                data_var.ind_type = vartype;
 
248
                                data_var.ind_pointer = var;
 
249
                                data_var.ind_varcharsize = varcharsize;
 
250
                                data_var.ind_arrsize = arrsize;
 
251
                                data_var.ind_offset = offset;
 
252
                                if (data_var.ind_arrsize == 0 || data_var.ind_varcharsize == 0)
 
253
                                        data_var.ind_value = *((void **) (data_var.ind_pointer));
 
254
                                else
 
255
                                        data_var.ind_value = data_var.ind_pointer;
 
256
                                break;
 
257
 
 
258
                        case ECPGd_data:
 
259
                                data_var.type = vartype;
 
260
                                data_var.pointer = var;
 
261
                                data_var.varcharsize = varcharsize;
 
262
                                data_var.arrsize = arrsize;
 
263
                                data_var.offset = offset;
 
264
                                if (data_var.arrsize == 0 || data_var.varcharsize == 0)
 
265
                                        data_var.value = *((void **) (data_var.pointer));
 
266
                                else
 
267
                                        data_var.value = data_var.pointer;
 
268
                                break;
 
269
 
 
270
                        case ECPGd_name:
 
271
                                if (!get_char_item(lineno, var, vartype, PQfname(ECPGresult, index), varcharsize))
 
272
                                        return (false);
 
273
 
 
274
                                ECPGlog("ECPGget_desc: NAME = %s\n", PQfname(ECPGresult, index));
 
275
                                break;
 
276
 
 
277
                        case ECPGd_nullable:
 
278
                                if (!get_int_item(lineno, var, vartype, 1))
 
279
                                        return (false);
 
280
 
 
281
                                break;
 
282
 
 
283
                        case ECPGd_key_member:
 
284
                                if (!get_int_item(lineno, var, vartype, 0))
 
285
                                        return (false);
 
286
 
 
287
                                break;
 
288
 
 
289
                        case ECPGd_scale:
 
290
                                if (!get_int_item(lineno, var, vartype, (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff))
 
291
                                        return (false);
 
292
 
 
293
                                ECPGlog("ECPGget_desc: SCALE = %d\n", (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff);
 
294
                                break;
 
295
 
 
296
                        case ECPGd_precision:
 
297
                                if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) >> 16))
 
298
                                        return (false);
 
299
 
 
300
                                ECPGlog("ECPGget_desc: PRECISION = %d\n", PQfmod(ECPGresult, index) >> 16);
 
301
                                break;
 
302
 
 
303
                        case ECPGd_octet:
 
304
                                if (!get_int_item(lineno, var, vartype, PQfsize(ECPGresult, index)))
 
305
                                        return (false);
 
306
 
 
307
                                ECPGlog("ECPGget_desc: OCTET_LENGTH = %d\n", PQfsize(ECPGresult, index));
 
308
                                break;
 
309
 
 
310
                        case ECPGd_length:
 
311
                                if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) - VARHDRSZ))
 
312
                                        return (false);
 
313
 
 
314
                                ECPGlog("ECPGget_desc: LENGTH = %d\n", PQfmod(ECPGresult, index) - VARHDRSZ);
 
315
                                break;
 
316
 
 
317
                        case ECPGd_type:
 
318
                                if (!get_int_item(lineno, var, vartype, ECPGDynamicType(PQftype(ECPGresult, index))))
 
319
                                        return (false);
 
320
 
 
321
                                ECPGlog("ECPGget_desc: TYPE = %d\n", ECPGDynamicType(PQftype(ECPGresult, index)));
 
322
                                break;
 
323
 
 
324
                        case ECPGd_di_code:
 
325
                                if (!get_int_item(lineno, var, vartype, ECPGDynamicType_DDT(PQftype(ECPGresult, index))))
 
326
                                        return (false);
 
327
 
 
328
                                ECPGlog("ECPGget_desc: TYPE = %d\n", ECPGDynamicType_DDT(PQftype(ECPGresult, index)));
 
329
                                break;
 
330
 
 
331
                        case ECPGd_cardinality:
 
332
                                if (!get_int_item(lineno, var, vartype, PQntuples(ECPGresult)))
 
333
                                        return (false);
 
334
 
 
335
                                ECPGlog("ECPGget_desc: CARDINALITY = %d\n", PQntuples(ECPGresult));
 
336
                                break;
 
337
 
 
338
                        case ECPGd_ret_length:
 
339
                        case ECPGd_ret_octet:
 
340
 
 
341
                                /*
 
342
                                 * this is like ECPGstore_result
 
343
                                 */
 
344
                                if (arrsize > 0 && ntuples > arrsize)
 
345
                                {
 
346
                                        ECPGlog("ECPGget_desc line %d: Incorrect number of matches: %d don't fit into array of %d\n",
 
347
                                                        lineno, ntuples, arrsize);
 
348
                                        ECPGraise(lineno, ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);
 
349
                                        return false;
 
350
                                }
 
351
                                /* allocate storage if needed */
 
352
                                if (arrsize == 0 && var != NULL && *(void **) var == NULL)
 
353
                                {
 
354
                                        void       *mem = (void *) ECPGalloc(offset * ntuples, lineno);
 
355
 
 
356
                                        *(void **) var = mem;
 
357
                                        ECPGadd_mem(mem, lineno);
 
358
                                        var = mem;
 
359
                                }
 
360
 
 
361
                                for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
 
362
                                {
 
363
                                        if (!get_int_item(lineno, var, vartype, PQgetlength(ECPGresult, act_tuple, index)))
 
364
                                                return (false);
 
365
                                        var = (char *) var + offset;
 
366
                                        ECPGlog("ECPGget_desc: RETURNED[%d] = %d\n", act_tuple, PQgetlength(ECPGresult, act_tuple, index));
 
367
                                }
 
368
                                break;
 
369
 
 
370
                        default:
 
371
                                snprintf(type_str, sizeof(type_str), "%d", type);
 
372
                                ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str);
 
373
                                return (false);
 
374
                }
 
375
 
 
376
                type = va_arg(args, enum ECPGdtype);
 
377
        }
 
378
 
 
379
        if (data_var.type != ECPGt_EORT)
 
380
        {
 
381
                struct statement stmt;
 
382
                char       *oldlocale;
 
383
 
 
384
                /* Make sure we do NOT honor the locale for numeric input */
 
385
                /* since the database gives the standard decimal point */
 
386
                oldlocale = strdup(setlocale(LC_NUMERIC, NULL));
 
387
                setlocale(LC_NUMERIC, "C");
 
388
 
 
389
                memset(&stmt, 0, sizeof stmt);
 
390
                stmt.lineno = lineno;
 
391
 
 
392
                /* desparate try to guess something sensible */
 
393
                stmt.connection = ECPGget_connection(NULL);
 
394
                ECPGstore_result(ECPGresult, index, &stmt, &data_var);
 
395
 
 
396
                setlocale(LC_NUMERIC, oldlocale);
 
397
                ECPGfree(oldlocale);
 
398
        }
 
399
        else if (data_var.ind_type != ECPGt_NO_INDICATOR)
 
400
        {
 
401
                /*
 
402
                 * this is like ECPGstore_result but since we don't have a data
 
403
                 * variable at hand, we can't call it
 
404
                 */
 
405
                if (data_var.ind_arrsize > 0 && ntuples > data_var.ind_arrsize)
 
406
                {
 
407
                        ECPGlog("ECPGget_desc line %d: Incorrect number of matches (indicator): %d don't fit into array of %d\n",
 
408
                                        lineno, ntuples, data_var.ind_arrsize);
 
409
                        ECPGraise(lineno, ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);
 
410
                        return false;
 
411
                }
 
412
                /* allocate storage if needed */
 
413
                if (data_var.ind_arrsize == 0 && data_var.ind_pointer != NULL && data_var.ind_value == NULL)
 
414
                {
 
415
                        void       *mem = (void *) ECPGalloc(data_var.ind_offset * ntuples, lineno);
 
416
 
 
417
                        *(void **) data_var.ind_pointer = mem;
 
418
                        ECPGadd_mem(mem, lineno);
 
419
                        data_var.ind_value = mem;
 
420
                }
 
421
                for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
 
422
                {
 
423
                        if (!get_int_item(lineno, data_var.ind_value, data_var.ind_type, -PQgetisnull(ECPGresult, act_tuple, index)))
 
424
                                return (false);
 
425
                        data_var.ind_value = (char *) data_var.ind_value + data_var.ind_offset;
 
426
                        ECPGlog("ECPGget_desc: INDICATOR[%d] = %d\n", act_tuple, -PQgetisnull(ECPGresult, act_tuple, index));
 
427
                }
 
428
        }
 
429
        sqlca->sqlerrd[2] = ntuples;
 
430
        return (true);
 
431
}
 
432
 
 
433
bool
 
434
ECPGset_desc_header(int lineno, char *desc_name, int count)
 
435
{
 
436
        struct descriptor *desc;
 
437
 
 
438
        for (desc = all_descriptors; desc; desc = desc->next)
 
439
        {
 
440
                if (strcmp(desc_name, desc->name) == 0)
 
441
                        break;
 
442
        }
 
443
 
 
444
        if (desc == NULL)
 
445
        {
 
446
                ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, desc_name);
 
447
                return false;
 
448
        }
 
449
 
 
450
        desc->count = count;
 
451
        return true;
 
452
}
 
453
 
 
454
bool
 
455
ECPGset_desc(int lineno, char *desc_name, int index,...)
 
456
{
 
457
        va_list         args;
 
458
        struct descriptor *desc;
 
459
        struct descriptor_item *desc_item;
 
460
        struct variable *var;
 
461
 
 
462
        for (desc = all_descriptors; desc; desc = desc->next)
 
463
        {
 
464
                if (strcmp(desc_name, desc->name) == 0)
 
465
                        break;
 
466
        }
 
467
 
 
468
        if (desc == NULL)
 
469
        {
 
470
                ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, desc_name);
 
471
                return false;
 
472
        }
 
473
 
 
474
        for (desc_item = desc->items; desc_item; desc_item = desc_item->next)
 
475
        {
 
476
                if (desc_item->num == index)
 
477
                        break;
 
478
        }
 
479
 
 
480
        if (desc_item == NULL)
 
481
        {
 
482
                desc_item = (struct descriptor_item *) ECPGalloc(sizeof(*desc_item), lineno);
 
483
                desc_item->num = index;
 
484
                desc_item->next = desc->items;
 
485
                desc->items = desc_item;
 
486
        }
 
487
 
 
488
        if (!(var = (struct variable *) ECPGalloc(sizeof(struct variable), lineno)))
 
489
                return false;
 
490
 
 
491
        va_start(args, index);
 
492
 
 
493
        do
 
494
        {
 
495
                enum ECPGdtype itemtype;
 
496
                enum ECPGttype type;
 
497
                const char *tobeinserted = NULL;
 
498
                bool            malloced;
 
499
 
 
500
                itemtype = va_arg(args, enum ECPGdtype);
 
501
 
 
502
                if (itemtype == ECPGd_EODT)
 
503
                        break;
 
504
 
 
505
                type = va_arg(args, enum ECPGttype);
 
506
                ECPGget_variable(&args, type, var, false);
 
507
 
 
508
                switch (itemtype)
 
509
                {
 
510
                        case ECPGd_data:
 
511
                                {
 
512
                                        if (!ECPGstore_input(lineno, true, var, &tobeinserted, &malloced))
 
513
                                        {
 
514
                                                ECPGfree(var);
 
515
                                                return false;
 
516
                                        }
 
517
 
 
518
                                        desc_item->data = (char *) tobeinserted;
 
519
                                        tobeinserted = NULL;
 
520
                                        break;
 
521
                                }
 
522
 
 
523
                        case ECPGd_indicator:
 
524
                                set_int_item(lineno, &desc_item->indicator, var->pointer, var->type);
 
525
                                break;
 
526
 
 
527
                        case ECPGd_length:
 
528
                                set_int_item(lineno, &desc_item->length, var->pointer, var->type);
 
529
                                break;
 
530
 
 
531
                        case ECPGd_precision:
 
532
                                set_int_item(lineno, &desc_item->precision, var->pointer, var->type);
 
533
                                break;
 
534
 
 
535
                        case ECPGd_scale:
 
536
                                set_int_item(lineno, &desc_item->scale, var->pointer, var->type);
 
537
                                break;
 
538
 
 
539
                        case ECPGd_type:
 
540
                                set_int_item(lineno, &desc_item->type, var->pointer, var->type);
 
541
                                break;
 
542
 
 
543
                        default:
 
544
                                {
 
545
                                        char            type_str[20];
 
546
 
 
547
                                        snprintf(type_str, sizeof(type_str), "%d", itemtype);
 
548
                                        ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str);
 
549
                                        ECPGfree(var);
 
550
                                        return false;
 
551
                                }
 
552
                }
 
553
 
 
554
                /*
 
555
                 * if (itemtype == ECPGd_data) { free(desc_item->data);
 
556
                 * desc_item->data = NULL; }
 
557
                 */
 
558
        }
 
559
        while (true);
 
560
        ECPGfree(var);
 
561
 
 
562
        return true;
 
563
}
 
564
 
 
565
bool
 
566
ECPGdeallocate_desc(int line, const char *name)
 
567
{
 
568
        struct descriptor *i;
 
569
        struct descriptor **lastptr = &all_descriptors;
 
570
        struct sqlca_t *sqlca = ECPGget_sqlca();
 
571
 
 
572
        ECPGinit_sqlca(sqlca);
 
573
        for (i = all_descriptors; i; lastptr = &i->next, i = i->next)
 
574
        {
 
575
                if (!strcmp(name, i->name))
 
576
                {
 
577
                        *lastptr = i->next;
 
578
                        ECPGfree(i->name);
 
579
                        PQclear(i->result);
 
580
                        ECPGfree(i);
 
581
                        return true;
 
582
                }
 
583
        }
 
584
        ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, name);
 
585
        return false;
 
586
}
 
587
 
 
588
bool
 
589
ECPGallocate_desc(int line, const char *name)
 
590
{
 
591
        struct descriptor *new;
 
592
        struct sqlca_t *sqlca = ECPGget_sqlca();
 
593
 
 
594
        ECPGinit_sqlca(sqlca);
 
595
        new = (struct descriptor *) ECPGalloc(sizeof(struct descriptor), line);
 
596
        if (!new)
 
597
                return false;
 
598
        new->next = all_descriptors;
 
599
        new->name = ECPGalloc(strlen(name) + 1, line);
 
600
        if (!new->name)
 
601
        {
 
602
                ECPGfree(new);
 
603
                return false;
 
604
        }
 
605
        new->count = -1;
 
606
        new->items = NULL;
 
607
        new->result = PQmakeEmptyPGresult(NULL, 0);
 
608
        if (!new->result)
 
609
        {
 
610
                ECPGfree(new->name);
 
611
                ECPGfree(new);
 
612
                ECPGraise(line, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
 
613
                return false;
 
614
        }
 
615
        strcpy(new->name, name);
 
616
        all_descriptors = new;
 
617
        return true;
 
618
}
 
619
 
 
620
PGresult  **
 
621
ECPGdescriptor_lvalue(int line, const char *descriptor)
 
622
{
 
623
        struct descriptor *i;
 
624
 
 
625
        for (i = all_descriptors; i != NULL; i = i->next)
 
626
        {
 
627
                if (!strcmp(descriptor, i->name))
 
628
                        return &i->result;
 
629
        }
 
630
 
 
631
        ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, (char *) descriptor);
 
632
        return NULL;
 
633
}
 
634
 
 
635
bool
 
636
ECPGdescribe(int line, bool input, const char *statement,...)
 
637
{
 
638
        ECPGlog("ECPGdescribe called on line %d for %s in %s\n", line, (input) ? "input" : "output", statement);
 
639
        return false;
 
640
}