~ubuntu-branches/ubuntu/oneiric/postgresql-9.1/oneiric-security

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-05-11 10:41:53 UTC
  • Revision ID: james.westby@ubuntu.com-20110511104153-psbh2o58553fv1m0
Tags: upstream-9.1~beta1
ImportĀ upstreamĀ versionĀ 9.1~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * SQLDA support routines
 
3
 *
 
4
 * The allocated memory area pointed by an sqlda pointer
 
5
 * contains both the metadata and the data, so freeing up
 
6
 * is a simple free(sqlda) as expected by the ESQL/C examples.
 
7
 */
 
8
 
 
9
#define POSTGRES_ECPG_INTERNAL
 
10
#include "postgres_fe.h"
 
11
#include "pg_type.h"
 
12
 
 
13
#include "ecpg-pthread-win32.h"
 
14
#include "decimal.h"
 
15
#include "ecpgtype.h"
 
16
#include "ecpglib.h"
 
17
#include "ecpgerrno.h"
 
18
#include "extern.h"
 
19
#include "sqlca.h"
 
20
#include "sqlda-native.h"
 
21
#include "sqlda-compat.h"
 
22
 
 
23
/*
 
24
 * Compute the next variable's offset with
 
25
 * the current variable's size and alignment.
 
26
 *
 
27
 *
 
28
 * Returns:
 
29
 * - the current variable's offset in *current
 
30
 * - the next variable's offset in *next
 
31
 */
 
32
static void
 
33
ecpg_sqlda_align_add_size(long offset, int alignment, int size, long *current, long *next)
 
34
{
 
35
        if (offset % alignment)
 
36
                offset += alignment - (offset % alignment);
 
37
        if (current)
 
38
                *current = offset;
 
39
        offset += size;
 
40
        if (next)
 
41
                *next = offset;
 
42
}
 
43
 
 
44
static long
 
45
sqlda_compat_empty_size(const PGresult *res)
 
46
{
 
47
        long            offset;
 
48
        int                     i;
 
49
        int                     sqld = PQnfields(res);
 
50
 
 
51
        /* Initial size to store main structure and field structures */
 
52
        offset = sizeof(struct sqlda_compat) + sqld * sizeof(struct sqlvar_compat);
 
53
 
 
54
        /* Add space for field names */
 
55
        for (i = 0; i < sqld; i++)
 
56
                offset += strlen(PQfname(res, i)) + 1;
 
57
 
 
58
        /* Add padding to the first field value */
 
59
        ecpg_sqlda_align_add_size(offset, sizeof(int), 0, &offset, NULL);
 
60
 
 
61
        return offset;
 
62
}
 
63
 
 
64
static long
 
65
sqlda_common_total_size(const PGresult *res, int row, enum COMPAT_MODE compat, long offset)
 
66
{
 
67
        int                     sqld = PQnfields(res);
 
68
        int                     i;
 
69
        long            next_offset;
 
70
 
 
71
        /* Add space for the field values */
 
72
        for (i = 0; i < sqld; i++)
 
73
        {
 
74
                enum ECPGttype type = sqlda_dynamic_type(PQftype(res, i), compat);
 
75
 
 
76
                switch (type)
 
77
                {
 
78
                        case ECPGt_short:
 
79
                        case ECPGt_unsigned_short:
 
80
                                ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
 
81
                                break;
 
82
                        case ECPGt_int:
 
83
                        case ECPGt_unsigned_int:
 
84
                                ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
 
85
                                break;
 
86
                        case ECPGt_long:
 
87
                        case ECPGt_unsigned_long:
 
88
                                ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
 
89
                                break;
 
90
                        case ECPGt_long_long:
 
91
                        case ECPGt_unsigned_long_long:
 
92
                                ecpg_sqlda_align_add_size(offset, sizeof(long long), sizeof(long long), &offset, &next_offset);
 
93
                                break;
 
94
                        case ECPGt_bool:
 
95
                                ecpg_sqlda_align_add_size(offset, sizeof(bool), sizeof(bool), &offset, &next_offset);
 
96
                                break;
 
97
                        case ECPGt_float:
 
98
                                ecpg_sqlda_align_add_size(offset, sizeof(float), sizeof(float), &offset, &next_offset);
 
99
                                break;
 
100
                        case ECPGt_double:
 
101
                                ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
 
102
                                break;
 
103
                        case ECPGt_decimal:
 
104
                                ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
 
105
                                break;
 
106
                        case ECPGt_numeric:
 
107
 
 
108
                                /*
 
109
                                 * Let's align both the numeric struct and the digits array to
 
110
                                 * int Unfortunately we need to do double work here to compute
 
111
                                 * the size of the space needed for the numeric structure.
 
112
                                 */
 
113
                                ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(numeric), &offset, &next_offset);
 
114
                                if (!PQgetisnull(res, row, i))
 
115
                                {
 
116
                                        char       *val = PQgetvalue(res, row, i);
 
117
                                        numeric    *num;
 
118
 
 
119
                                        num = PGTYPESnumeric_from_asc(val, NULL);
 
120
                                        if (!num)
 
121
                                                break;
 
122
                                        ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->ndigits + 1, &offset, &next_offset);
 
123
                                        PGTYPESnumeric_free(num);
 
124
                                }
 
125
                                break;
 
126
                        case ECPGt_date:
 
127
                                ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(date), &offset, &next_offset);
 
128
                                break;
 
129
                        case ECPGt_timestamp:
 
130
                                ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(timestamp), &offset, &next_offset);
 
131
                                break;
 
132
                        case ECPGt_interval:
 
133
                                ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(interval), &offset, &next_offset);
 
134
                                break;
 
135
                        case ECPGt_char:
 
136
                        case ECPGt_unsigned_char:
 
137
                        case ECPGt_string:
 
138
                        default:
 
139
                                {
 
140
                                        long            datalen = strlen(PQgetvalue(res, row, i)) + 1;
 
141
 
 
142
                                        ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
 
143
                                        break;
 
144
                                }
 
145
                }
 
146
                offset = next_offset;
 
147
        }
 
148
        return offset;
 
149
}
 
150
 
 
151
 
 
152
static long
 
153
sqlda_compat_total_size(const PGresult *res, int row, enum COMPAT_MODE compat)
 
154
{
 
155
        long            offset;
 
156
 
 
157
        offset = sqlda_compat_empty_size(res);
 
158
 
 
159
        if (row < 0)
 
160
                return offset;
 
161
 
 
162
        offset = sqlda_common_total_size(res, row, compat, offset);
 
163
        return offset;
 
164
}
 
165
 
 
166
static long
 
167
sqlda_native_empty_size(const PGresult *res)
 
168
{
 
169
        long            offset;
 
170
        int                     sqld = PQnfields(res);
 
171
 
 
172
        /* Initial size to store main structure and field structures */
 
173
        offset = sizeof(struct sqlda_struct) + (sqld - 1) * sizeof(struct sqlvar_struct);
 
174
 
 
175
        /* Add padding to the first field value */
 
176
        ecpg_sqlda_align_add_size(offset, sizeof(int), 0, &offset, NULL);
 
177
 
 
178
        return offset;
 
179
}
 
180
 
 
181
static long
 
182
sqlda_native_total_size(const PGresult *res, int row, enum COMPAT_MODE compat)
 
183
{
 
184
        long            offset;
 
185
 
 
186
        offset = sqlda_native_empty_size(res);
 
187
 
 
188
        if (row < 0)
 
189
                return offset;
 
190
 
 
191
        offset = sqlda_common_total_size(res, row, compat, offset);
 
192
        return offset;
 
193
}
 
194
 
 
195
/*
 
196
 * Build "struct sqlda_compat" (metadata only) from PGresult
 
197
 * leaving enough space for the field values in
 
198
 * the given row number
 
199
 */
 
200
struct sqlda_compat *
 
201
ecpg_build_compat_sqlda(int line, PGresult *res, int row, enum COMPAT_MODE compat)
 
202
{
 
203
        struct sqlda_compat *sqlda;
 
204
        struct sqlvar_compat *sqlvar;
 
205
        char       *fname;
 
206
        long            size;
 
207
        int                     sqld;
 
208
        int                     i;
 
209
 
 
210
        size = sqlda_compat_total_size(res, row, compat);
 
211
        sqlda = (struct sqlda_compat *) ecpg_alloc(size, line);
 
212
        if (!sqlda)
 
213
                return NULL;
 
214
 
 
215
        memset(sqlda, 0, size);
 
216
        sqlvar = (struct sqlvar_compat *) (sqlda + 1);
 
217
        sqld = PQnfields(res);
 
218
        fname = (char *) (sqlvar + sqld);
 
219
 
 
220
        sqlda->sqld = sqld;
 
221
        ecpg_log("ecpg_build_compat_sqlda on line %d sqld = %d\n", line, sqld);
 
222
        sqlda->desc_occ = size;         /* cheat here, keep the full allocated size */
 
223
        sqlda->sqlvar = sqlvar;
 
224
 
 
225
        for (i = 0; i < sqlda->sqld; i++)
 
226
        {
 
227
                sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
 
228
                strcpy(fname, PQfname(res, i));
 
229
                sqlda->sqlvar[i].sqlname = fname;
 
230
                fname += strlen(sqlda->sqlvar[i].sqlname) + 1;
 
231
                /* this is reserved for future use, so we leave it empty for the time being */
 
232
                /* sqlda->sqlvar[i].sqlformat = (char *) (long) PQfformat(res, i);*/
 
233
                sqlda->sqlvar[i].sqlxid = PQftype(res, i);
 
234
                sqlda->sqlvar[i].sqltypelen = PQfsize(res, i);
 
235
        }
 
236
 
 
237
        return sqlda;
 
238
}
 
239
 
 
240
/*
 
241
 * Sets values from PGresult.
 
242
 */
 
243
static int2 value_is_null = -1;
 
244
static int2 value_is_not_null = 0;
 
245
 
 
246
void
 
247
ecpg_set_compat_sqlda(int lineno, struct sqlda_compat ** _sqlda, const PGresult *res, int row, enum COMPAT_MODE compat)
 
248
{
 
249
        struct sqlda_compat *sqlda = (*_sqlda);
 
250
        int                     i;
 
251
        long            offset,
 
252
                                next_offset;
 
253
 
 
254
        if (row < 0)
 
255
                return;
 
256
 
 
257
        /* Offset for the first field value */
 
258
        offset = sqlda_compat_empty_size(res);
 
259
 
 
260
        /*
 
261
         * Set sqlvar[i]->sqldata pointers and convert values to correct format
 
262
         */
 
263
        for (i = 0; i < sqlda->sqld; i++)
 
264
        {
 
265
                int                     isnull;
 
266
                int                     datalen;
 
267
                bool            set_data = true;
 
268
 
 
269
                switch (sqlda->sqlvar[i].sqltype)
 
270
                {
 
271
                        case ECPGt_short:
 
272
                        case ECPGt_unsigned_short:
 
273
                                ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
 
274
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
275
                                sqlda->sqlvar[i].sqllen = sizeof(short);
 
276
                                break;
 
277
                        case ECPGt_int:
 
278
                        case ECPGt_unsigned_int:
 
279
                                ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
 
280
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
281
                                sqlda->sqlvar[i].sqllen = sizeof(int);
 
282
                                break;
 
283
                        case ECPGt_long:
 
284
                        case ECPGt_unsigned_long:
 
285
                                ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
 
286
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
287
                                sqlda->sqlvar[i].sqllen = sizeof(long);
 
288
                                break;
 
289
                        case ECPGt_long_long:
 
290
                        case ECPGt_unsigned_long_long:
 
291
                                ecpg_sqlda_align_add_size(offset, sizeof(long long), sizeof(long long), &offset, &next_offset);
 
292
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
293
                                sqlda->sqlvar[i].sqllen = sizeof(long long);
 
294
                                break;
 
295
                        case ECPGt_bool:
 
296
                                ecpg_sqlda_align_add_size(offset, sizeof(bool), sizeof(bool), &offset, &next_offset);
 
297
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
298
                                sqlda->sqlvar[i].sqllen = sizeof(bool);
 
299
                                break;
 
300
                        case ECPGt_float:
 
301
                                ecpg_sqlda_align_add_size(offset, sizeof(float), sizeof(float), &offset, &next_offset);
 
302
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
303
                                sqlda->sqlvar[i].sqllen = sizeof(float);
 
304
                                break;
 
305
                        case ECPGt_double:
 
306
                                ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
 
307
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
308
                                sqlda->sqlvar[i].sqllen = sizeof(double);
 
309
                                break;
 
310
                        case ECPGt_decimal:
 
311
                                ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
 
312
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
313
                                sqlda->sqlvar[i].sqllen = sizeof(decimal);
 
314
                                break;
 
315
                        case ECPGt_numeric:
 
316
                                {
 
317
                                        numeric    *num;
 
318
                                        char       *val;
 
319
 
 
320
                                        set_data = false;
 
321
 
 
322
                                        ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(numeric), &offset, &next_offset);
 
323
                                        sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
324
                                        sqlda->sqlvar[i].sqllen = sizeof(numeric);
 
325
 
 
326
                                        if (PQgetisnull(res, row, i))
 
327
                                        {
 
328
                                                ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
 
329
                                                break;
 
330
                                        }
 
331
 
 
332
                                        val = PQgetvalue(res, row, i);
 
333
                                        num = PGTYPESnumeric_from_asc(val, NULL);
 
334
                                        if (!num)
 
335
                                        {
 
336
                                                ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
 
337
                                                break;
 
338
                                        }
 
339
 
 
340
                                        memcpy(sqlda->sqlvar[i].sqldata, num, sizeof(numeric));
 
341
 
 
342
                                        ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->ndigits + 1, &offset, &next_offset);
 
343
                                        memcpy((char *) sqlda + offset, num->buf, num->ndigits + 1);
 
344
 
 
345
                                        ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + offset;
 
346
                                        ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda + offset + (num->digits - num->buf);
 
347
 
 
348
                                        PGTYPESnumeric_free(num);
 
349
 
 
350
                                        break;
 
351
                                }
 
352
                        case ECPGt_date:
 
353
                                ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
 
354
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
355
                                sqlda->sqlvar[i].sqllen = sizeof(date);
 
356
                                break;
 
357
                        case ECPGt_timestamp:
 
358
                                ecpg_sqlda_align_add_size(offset, sizeof(timestamp), sizeof(timestamp), &offset, &next_offset);
 
359
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
360
                                sqlda->sqlvar[i].sqllen = sizeof(timestamp);
 
361
                                break;
 
362
                        case ECPGt_interval:
 
363
                                ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
 
364
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
365
                                sqlda->sqlvar[i].sqllen = sizeof(interval);
 
366
                                break;
 
367
                        case ECPGt_char:
 
368
                        case ECPGt_unsigned_char:
 
369
                        case ECPGt_string:
 
370
                        default:
 
371
                                datalen = strlen(PQgetvalue(res, row, i)) + 1;
 
372
                                ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
 
373
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
374
                                sqlda->sqlvar[i].sqllen = datalen;
 
375
                                if (datalen > 32768)
 
376
                                        sqlda->sqlvar[i].sqlilongdata = sqlda->sqlvar[i].sqldata;
 
377
                                break;
 
378
                }
 
379
 
 
380
                isnull = PQgetisnull(res, row, i);
 
381
                ecpg_log("ecpg_set_compat_sqlda on line %d row %d col %d %s\n", lineno, row, i, isnull ? "IS NULL" : "IS NOT NULL");
 
382
                sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
 
383
                sqlda->sqlvar[i].sqlitype = ECPGt_short;
 
384
                sqlda->sqlvar[i].sqlilen = sizeof(short);
 
385
                if (!isnull)
 
386
                {
 
387
                        if (set_data)
 
388
                                ecpg_get_data(res, row, i, lineno,
 
389
                                                          sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
 
390
                                                          sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
 
391
                                                          ECPG_ARRAY_NONE, compat, false);
 
392
                }
 
393
                else
 
394
                        ECPGset_noind_null(sqlda->sqlvar[i].sqltype, sqlda->sqlvar[i].sqldata);
 
395
 
 
396
                offset = next_offset;
 
397
        }
 
398
}
 
399
 
 
400
struct sqlda_struct *
 
401
ecpg_build_native_sqlda(int line, PGresult *res, int row, enum COMPAT_MODE compat)
 
402
{
 
403
        struct sqlda_struct *sqlda;
 
404
        long            size;
 
405
        int                     i;
 
406
 
 
407
        size = sqlda_native_total_size(res, row, compat);
 
408
        sqlda = (struct sqlda_struct *) ecpg_alloc(size, line);
 
409
        if (!sqlda)
 
410
                return NULL;
 
411
 
 
412
        memset(sqlda, 0, size);
 
413
 
 
414
        sprintf(sqlda->sqldaid, "SQLDA  ");
 
415
        sqlda->sqld = sqlda->sqln = PQnfields(res);
 
416
        ecpg_log("ecpg_build_native_sqlda on line %d sqld = %d\n", line, sqlda->sqld);
 
417
        sqlda->sqldabc = sizeof(struct sqlda_struct) + (sqlda->sqld - 1) * sizeof(struct sqlvar_struct);
 
418
 
 
419
        for (i = 0; i < sqlda->sqld; i++)
 
420
        {
 
421
                char       *fname;
 
422
 
 
423
                sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
 
424
                fname = PQfname(res, i);
 
425
                sqlda->sqlvar[i].sqlname.length = strlen(fname);
 
426
                strcpy(sqlda->sqlvar[i].sqlname.data, fname);
 
427
        }
 
428
 
 
429
        return sqlda;
 
430
}
 
431
 
 
432
void
 
433
ecpg_set_native_sqlda(int lineno, struct sqlda_struct ** _sqlda, const PGresult *res, int row, enum COMPAT_MODE compat)
 
434
{
 
435
        struct sqlda_struct *sqlda = (*_sqlda);
 
436
        int                     i;
 
437
        long            offset,
 
438
                                next_offset;
 
439
 
 
440
        if (row < 0)
 
441
                return;
 
442
 
 
443
        /* Offset for the first field value */
 
444
        offset = sqlda_native_empty_size(res);
 
445
 
 
446
        /*
 
447
         * Set sqlvar[i]->sqldata pointers and convert values to correct format
 
448
         */
 
449
        for (i = 0; i < sqlda->sqld; i++)
 
450
        {
 
451
                int                     isnull;
 
452
                int                     datalen;
 
453
                bool            set_data = true;
 
454
 
 
455
                switch (sqlda->sqlvar[i].sqltype)
 
456
                {
 
457
                        case ECPGt_short:
 
458
                        case ECPGt_unsigned_short:
 
459
                                ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
 
460
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
461
                                sqlda->sqlvar[i].sqllen = sizeof(short);
 
462
                                break;
 
463
                        case ECPGt_int:
 
464
                        case ECPGt_unsigned_int:
 
465
                                ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
 
466
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
467
                                sqlda->sqlvar[i].sqllen = sizeof(int);
 
468
                                break;
 
469
                        case ECPGt_long:
 
470
                        case ECPGt_unsigned_long:
 
471
                                ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
 
472
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
473
                                sqlda->sqlvar[i].sqllen = sizeof(long);
 
474
                                break;
 
475
                        case ECPGt_long_long:
 
476
                        case ECPGt_unsigned_long_long:
 
477
                                ecpg_sqlda_align_add_size(offset, sizeof(long long), sizeof(long long), &offset, &next_offset);
 
478
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
479
                                sqlda->sqlvar[i].sqllen = sizeof(long long);
 
480
                                break;
 
481
                        case ECPGt_bool:
 
482
                                ecpg_sqlda_align_add_size(offset, sizeof(bool), sizeof(bool), &offset, &next_offset);
 
483
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
484
                                sqlda->sqlvar[i].sqllen = sizeof(bool);
 
485
                                break;
 
486
                        case ECPGt_float:
 
487
                                ecpg_sqlda_align_add_size(offset, sizeof(float), sizeof(float), &offset, &next_offset);
 
488
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
489
                                sqlda->sqlvar[i].sqllen = sizeof(float);
 
490
                                break;
 
491
                        case ECPGt_double:
 
492
                                ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
 
493
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
494
                                sqlda->sqlvar[i].sqllen = sizeof(double);
 
495
                                break;
 
496
                        case ECPGt_decimal:
 
497
                                ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
 
498
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
499
                                sqlda->sqlvar[i].sqllen = sizeof(decimal);
 
500
                                break;
 
501
                        case ECPGt_numeric:
 
502
                                {
 
503
                                        numeric    *num;
 
504
                                        char       *val;
 
505
 
 
506
                                        set_data = false;
 
507
 
 
508
                                        ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(numeric), &offset, &next_offset);
 
509
                                        sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
510
                                        sqlda->sqlvar[i].sqllen = sizeof(numeric);
 
511
 
 
512
                                        if (PQgetisnull(res, row, i))
 
513
                                        {
 
514
                                                ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
 
515
                                                break;
 
516
                                        }
 
517
 
 
518
                                        val = PQgetvalue(res, row, i);
 
519
                                        num = PGTYPESnumeric_from_asc(val, NULL);
 
520
                                        if (!num)
 
521
                                        {
 
522
                                                ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
 
523
                                                break;
 
524
                                        }
 
525
 
 
526
                                        memcpy(sqlda->sqlvar[i].sqldata, num, sizeof(numeric));
 
527
 
 
528
                                        ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->ndigits + 1, &offset, &next_offset);
 
529
                                        memcpy((char *) sqlda + offset, num->buf, num->ndigits + 1);
 
530
 
 
531
                                        ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + offset;
 
532
                                        ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda + offset + (num->digits - num->buf);
 
533
 
 
534
                                        PGTYPESnumeric_free(num);
 
535
 
 
536
                                        break;
 
537
                                }
 
538
                        case ECPGt_date:
 
539
                                ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
 
540
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
541
                                sqlda->sqlvar[i].sqllen = sizeof(date);
 
542
                                break;
 
543
                        case ECPGt_timestamp:
 
544
                                ecpg_sqlda_align_add_size(offset, sizeof(timestamp), sizeof(timestamp), &offset, &next_offset);
 
545
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
546
                                sqlda->sqlvar[i].sqllen = sizeof(timestamp);
 
547
                                break;
 
548
                        case ECPGt_interval:
 
549
                                ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
 
550
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
551
                                sqlda->sqlvar[i].sqllen = sizeof(interval);
 
552
                                break;
 
553
                        case ECPGt_char:
 
554
                        case ECPGt_unsigned_char:
 
555
                        case ECPGt_string:
 
556
                        default:
 
557
                                datalen = strlen(PQgetvalue(res, row, i)) + 1;
 
558
                                ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
 
559
                                sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
 
560
                                sqlda->sqlvar[i].sqllen = datalen;
 
561
                                break;
 
562
                }
 
563
 
 
564
                isnull = PQgetisnull(res, row, i);
 
565
                ecpg_log("ecpg_set_native_sqlda on line %d row %d col %d %s\n", lineno, row, i, isnull ? "IS NULL" : "IS NOT NULL");
 
566
                sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
 
567
                if (!isnull)
 
568
                {
 
569
                        if (set_data)
 
570
                                ecpg_get_data(res, row, i, lineno,
 
571
                                                          sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
 
572
                                                          sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
 
573
                                                          ECPG_ARRAY_NONE, compat, false);
 
574
                }
 
575
 
 
576
                offset = next_offset;
 
577
        }
 
578
}