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
33 1184 : ecpg_sqlda_align_add_size(long offset, int alignment, int size, long *current, long *next)
34 : {
35 1184 : if (offset % alignment)
36 440 : offset += alignment - (offset % alignment);
37 1184 : if (current)
38 1184 : *current = offset;
39 1184 : offset += size;
40 1184 : if (next)
41 968 : *next = offset;
42 1184 : }
43 :
44 : static long
45 88 : sqlda_compat_empty_size(const PGresult *res)
46 : {
47 : long offset;
48 : int i;
49 88 : int sqld = PQnfields(res);
50 :
51 : /* Initial size to store main structure and field structures */
52 88 : offset = sizeof(struct sqlda_compat) + sqld * sizeof(struct sqlvar_compat);
53 :
54 : /* Add space for field names */
55 456 : for (i = 0; i < sqld; i++)
56 368 : offset += strlen(PQfname(res, i)) + 1;
57 :
58 : /* Add padding to the first field value */
59 88 : ecpg_sqlda_align_add_size(offset, sizeof(int), 0, &offset, NULL);
60 :
61 88 : return offset;
62 : }
63 :
64 : static long
65 84 : sqlda_common_total_size(const PGresult *res, int row, enum COMPAT_MODE compat, long offset)
66 : {
67 84 : int sqld = PQnfields(res);
68 : int i;
69 : long next_offset;
70 :
71 : /* Add space for the field values */
72 540 : for (i = 0; i < sqld; i++)
73 : {
74 456 : enum ECPGttype type = sqlda_dynamic_type(PQftype(res, i), compat);
75 :
76 456 : switch (type)
77 : {
78 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;
82 80 : case ECPGt_int:
83 : case ECPGt_unsigned_int:
84 80 : ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
85 80 : break;
86 48 : case ECPGt_long:
87 : case ECPGt_unsigned_long:
88 48 : ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
89 48 : break;
90 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;
100 80 : case ECPGt_double:
101 80 : ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
102 80 : break;
103 32 : case ECPGt_decimal:
104 32 : ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
105 32 : break;
106 52 : 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 : */
116 52 : ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
117 52 : if (!PQgetisnull(res, row, i))
118 : {
119 44 : char *val = PQgetvalue(res, row, i);
120 : numeric *num;
121 :
122 44 : num = PGTYPESnumeric_from_asc(val, NULL);
123 44 : if (!num)
124 0 : break;
125 44 : if (num->buf)
126 28 : ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->digits - num->buf + num->ndigits, &offset, &next_offset);
127 44 : PGTYPESnumeric_free(num);
128 : }
129 52 : break;
130 0 : case ECPGt_date:
131 0 : ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
132 0 : break;
133 0 : case ECPGt_timestamp:
134 0 : ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(timestamp), &offset, &next_offset);
135 0 : break;
136 0 : case ECPGt_interval:
137 0 : ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
138 0 : break;
139 164 : case ECPGt_char:
140 : case ECPGt_unsigned_char:
141 : case ECPGt_string:
142 : default:
143 : {
144 164 : long datalen = strlen(PQgetvalue(res, row, i)) + 1;
145 :
146 164 : ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
147 164 : break;
148 : }
149 : }
150 456 : offset = next_offset;
151 : }
152 84 : return offset;
153 : }
154 :
155 :
156 : static long
157 56 : sqlda_compat_total_size(const PGresult *res, int row, enum COMPAT_MODE compat)
158 : {
159 : long offset;
160 :
161 56 : offset = sqlda_compat_empty_size(res);
162 :
163 56 : if (row < 0)
164 24 : return offset;
165 :
166 32 : offset = sqlda_common_total_size(res, row, compat, offset);
167 32 : return offset;
168 : }
169 :
170 : static long
171 128 : sqlda_native_empty_size(const PGresult *res)
172 : {
173 : long offset;
174 128 : int sqld = PQnfields(res);
175 :
176 : /* Initial size to store main structure and field structures */
177 128 : offset = sizeof(struct sqlda_struct) + (sqld - 1) * sizeof(struct sqlvar_struct);
178 :
179 : /* Add padding to the first field value */
180 128 : ecpg_sqlda_align_add_size(offset, sizeof(int), 0, &offset, NULL);
181 :
182 128 : return offset;
183 : }
184 :
185 : static long
186 76 : sqlda_native_total_size(const PGresult *res, int row, enum COMPAT_MODE compat)
187 : {
188 : long offset;
189 :
190 76 : offset = sqlda_native_empty_size(res);
191 :
192 76 : if (row < 0)
193 24 : return offset;
194 :
195 52 : offset = sqlda_common_total_size(res, row, compat, offset);
196 52 : 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 56 : 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 56 : size = sqlda_compat_total_size(res, row, compat);
215 56 : sqlda = (struct sqlda_compat *) ecpg_alloc(size, line);
216 56 : if (!sqlda)
217 0 : return NULL;
218 :
219 56 : memset(sqlda, 0, size);
220 56 : sqlvar = (struct sqlvar_compat *) (sqlda + 1);
221 56 : sqld = PQnfields(res);
222 56 : fname = (char *) (sqlvar + sqld);
223 :
224 56 : sqlda->sqld = sqld;
225 56 : ecpg_log("ecpg_build_compat_sqlda on line %d sqld = %d\n", line, sqld);
226 56 : sqlda->desc_occ = size; /* cheat here, keep the full allocated size */
227 56 : sqlda->sqlvar = sqlvar;
228 :
229 264 : for (i = 0; i < sqlda->sqld; i++)
230 : {
231 208 : sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
232 208 : strcpy(fname, PQfname(res, i));
233 208 : sqlda->sqlvar[i].sqlname = fname;
234 208 : 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 208 : sqlda->sqlvar[i].sqlxid = PQftype(res, i);
242 208 : sqlda->sqlvar[i].sqltypelen = PQfsize(res, i);
243 : }
244 :
245 56 : 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
255 32 : ecpg_set_compat_sqlda(int lineno, struct sqlda_compat **_sqlda, const PGresult *res, int row, enum COMPAT_MODE compat)
256 : {
257 32 : struct sqlda_compat *sqlda = (*_sqlda);
258 : int i;
259 : long offset,
260 : next_offset;
261 :
262 32 : if (row < 0)
263 0 : return;
264 :
265 : /* Offset for the first field value */
266 32 : offset = sqlda_compat_empty_size(res);
267 :
268 : /*
269 : * Set sqlvar[i]->sqldata pointers and convert values to correct format
270 : */
271 192 : for (i = 0; i < sqlda->sqld; i++)
272 : {
273 : int isnull;
274 : int datalen;
275 160 : bool set_data = true;
276 :
277 160 : switch (sqlda->sqlvar[i].sqltype)
278 : {
279 0 : case ECPGt_short:
280 : case ECPGt_unsigned_short:
281 0 : ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
282 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
283 0 : sqlda->sqlvar[i].sqllen = sizeof(short);
284 0 : break;
285 32 : case ECPGt_int:
286 : case ECPGt_unsigned_int:
287 32 : ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
288 32 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
289 32 : sqlda->sqlvar[i].sqllen = sizeof(int);
290 32 : break;
291 0 : case ECPGt_long:
292 : case ECPGt_unsigned_long:
293 0 : ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
294 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
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);
300 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
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);
305 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
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);
310 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
311 0 : sqlda->sqlvar[i].sqllen = sizeof(float);
312 0 : break;
313 32 : case ECPGt_double:
314 32 : ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
315 32 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
316 32 : sqlda->sqlvar[i].sqllen = sizeof(double);
317 32 : break;
318 32 : case ECPGt_decimal:
319 32 : ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
320 32 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
321 32 : sqlda->sqlvar[i].sqllen = sizeof(decimal);
322 32 : break;
323 0 : case ECPGt_numeric:
324 : {
325 : numeric *num;
326 : char *val;
327 :
328 0 : set_data = false;
329 :
330 0 : ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
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 :
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 :
359 0 : PGTYPESnumeric_free(num);
360 :
361 0 : break;
362 : }
363 0 : case ECPGt_date:
364 0 : ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
365 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
366 0 : sqlda->sqlvar[i].sqllen = sizeof(date);
367 0 : break;
368 0 : case ECPGt_timestamp:
369 0 : ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(timestamp), &offset, &next_offset);
370 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
371 0 : sqlda->sqlvar[i].sqllen = sizeof(timestamp);
372 0 : break;
373 0 : case ECPGt_interval:
374 0 : ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
375 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
376 0 : sqlda->sqlvar[i].sqllen = sizeof(interval);
377 0 : break;
378 64 : case ECPGt_char:
379 : case ECPGt_unsigned_char:
380 : case ECPGt_string:
381 : default:
382 64 : datalen = strlen(PQgetvalue(res, row, i)) + 1;
383 64 : ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
384 64 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
385 64 : sqlda->sqlvar[i].sqllen = datalen;
386 64 : if (datalen > 32768)
387 0 : sqlda->sqlvar[i].sqlilongdata = sqlda->sqlvar[i].sqldata;
388 64 : break;
389 : }
390 :
391 160 : isnull = PQgetisnull(res, row, i);
392 160 : ecpg_log("ecpg_set_compat_sqlda on line %d row %d col %d %s\n", lineno, row, i, isnull ? "IS NULL" : "IS NOT NULL");
393 160 : sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
394 160 : sqlda->sqlvar[i].sqlitype = ECPGt_short;
395 160 : sqlda->sqlvar[i].sqlilen = sizeof(short);
396 160 : if (!isnull)
397 : {
398 128 : if (set_data)
399 128 : ecpg_get_data(res, row, i, lineno,
400 128 : sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
401 128 : sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
402 : ECPG_ARRAY_NONE, compat, false);
403 : }
404 : else
405 32 : ECPGset_noind_null(sqlda->sqlvar[i].sqltype, sqlda->sqlvar[i].sqldata);
406 :
407 160 : offset = next_offset;
408 : }
409 : }
410 :
411 : struct sqlda_struct *
412 76 : 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 76 : size = sqlda_native_total_size(res, row, compat);
419 76 : sqlda = (struct sqlda_struct *) ecpg_alloc(size, line);
420 76 : if (!sqlda)
421 0 : return NULL;
422 :
423 76 : memset(sqlda, 0, size);
424 :
425 76 : sprintf(sqlda->sqldaid, "SQLDA ");
426 76 : sqlda->sqld = sqlda->sqln = PQnfields(res);
427 76 : ecpg_log("ecpg_build_native_sqlda on line %d sqld = %d\n", line, sqlda->sqld);
428 76 : sqlda->sqldabc = sizeof(struct sqlda_struct) + (sqlda->sqld - 1) * sizeof(struct sqlvar_struct);
429 :
430 420 : for (i = 0; i < sqlda->sqld; i++)
431 : {
432 : char *fname;
433 :
434 344 : sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
435 344 : fname = PQfname(res, i);
436 344 : sqlda->sqlvar[i].sqlname.length = strlen(fname);
437 344 : strcpy(sqlda->sqlvar[i].sqlname.data, fname);
438 : }
439 :
440 76 : return sqlda;
441 : }
442 :
443 : void
444 52 : ecpg_set_native_sqlda(int lineno, struct sqlda_struct **_sqlda, const PGresult *res, int row, enum COMPAT_MODE compat)
445 : {
446 52 : struct sqlda_struct *sqlda = (*_sqlda);
447 : int i;
448 : long offset,
449 : next_offset;
450 :
451 52 : if (row < 0)
452 0 : return;
453 :
454 : /* Offset for the first field value */
455 52 : offset = sqlda_native_empty_size(res);
456 :
457 : /*
458 : * Set sqlvar[i]->sqldata pointers and convert values to correct format
459 : */
460 348 : for (i = 0; i < sqlda->sqld; i++)
461 : {
462 : int isnull;
463 : int datalen;
464 296 : bool set_data = true;
465 :
466 296 : switch (sqlda->sqlvar[i].sqltype)
467 : {
468 0 : case ECPGt_short:
469 : case ECPGt_unsigned_short:
470 0 : ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
471 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
472 0 : sqlda->sqlvar[i].sqllen = sizeof(short);
473 0 : break;
474 48 : case ECPGt_int:
475 : case ECPGt_unsigned_int:
476 48 : ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
477 48 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
478 48 : sqlda->sqlvar[i].sqllen = sizeof(int);
479 48 : break;
480 48 : case ECPGt_long:
481 : case ECPGt_unsigned_long:
482 48 : ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
483 48 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
484 48 : sqlda->sqlvar[i].sqllen = sizeof(long);
485 48 : break;
486 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);
489 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
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);
494 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
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);
499 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
500 0 : sqlda->sqlvar[i].sqllen = sizeof(float);
501 0 : break;
502 48 : case ECPGt_double:
503 48 : ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
504 48 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
505 48 : sqlda->sqlvar[i].sqllen = sizeof(double);
506 48 : break;
507 0 : case ECPGt_decimal:
508 0 : ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
509 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
510 0 : sqlda->sqlvar[i].sqllen = sizeof(decimal);
511 0 : break;
512 52 : case ECPGt_numeric:
513 : {
514 : numeric *num;
515 : char *val;
516 :
517 52 : set_data = false;
518 :
519 52 : ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
520 52 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
521 52 : sqlda->sqlvar[i].sqllen = sizeof(numeric);
522 :
523 52 : if (PQgetisnull(res, row, i))
524 : {
525 8 : ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
526 8 : break;
527 : }
528 :
529 44 : val = PQgetvalue(res, row, i);
530 44 : num = PGTYPESnumeric_from_asc(val, NULL);
531 44 : if (!num)
532 : {
533 0 : ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
534 0 : break;
535 : }
536 :
537 44 : memcpy(sqlda->sqlvar[i].sqldata, num, sizeof(numeric));
538 :
539 44 : if (num->buf)
540 : {
541 28 : ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->digits - num->buf + num->ndigits, &offset, &next_offset);
542 28 : memcpy((char *) sqlda + offset, num->buf, num->digits - num->buf + num->ndigits);
543 :
544 28 : ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + offset;
545 28 : ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda + offset + (num->digits - num->buf);
546 : }
547 :
548 44 : PGTYPESnumeric_free(num);
549 :
550 44 : break;
551 : }
552 0 : case ECPGt_date:
553 0 : ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
554 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
555 0 : sqlda->sqlvar[i].sqllen = sizeof(date);
556 0 : break;
557 0 : case ECPGt_timestamp:
558 0 : ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(timestamp), &offset, &next_offset);
559 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
560 0 : sqlda->sqlvar[i].sqllen = sizeof(timestamp);
561 0 : break;
562 0 : case ECPGt_interval:
563 0 : ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
564 0 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
565 0 : sqlda->sqlvar[i].sqllen = sizeof(interval);
566 0 : break;
567 100 : case ECPGt_char:
568 : case ECPGt_unsigned_char:
569 : case ECPGt_string:
570 : default:
571 100 : datalen = strlen(PQgetvalue(res, row, i)) + 1;
572 100 : ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
573 100 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
574 100 : sqlda->sqlvar[i].sqllen = datalen;
575 100 : break;
576 : }
577 :
578 296 : isnull = PQgetisnull(res, row, i);
579 296 : ecpg_log("ecpg_set_native_sqlda on line %d row %d col %d %s\n", lineno, row, i, isnull ? "IS NULL" : "IS NOT NULL");
580 296 : sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
581 296 : if (!isnull)
582 : {
583 256 : if (set_data)
584 212 : ecpg_get_data(res, row, i, lineno,
585 212 : sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
586 : sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
587 : ECPG_ARRAY_NONE, compat, false);
588 : }
589 :
590 296 : offset = next_offset;
591 : }
592 : }
|