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