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 592 : ecpg_sqlda_align_add_size(long offset, int alignment, int size, long *current, long *next)
34 : {
35 592 : if (offset % alignment)
36 220 : offset += alignment - (offset % alignment);
37 592 : if (current)
38 592 : *current = offset;
39 592 : offset += size;
40 592 : if (next)
41 484 : *next = offset;
42 592 : }
43 :
44 : static long
45 44 : sqlda_compat_empty_size(const PGresult *res)
46 : {
47 : long offset;
48 : int i;
49 44 : int sqld = PQnfields(res);
50 :
51 : /* Initial size to store main structure and field structures */
52 44 : offset = sizeof(struct sqlda_compat) + sqld * sizeof(struct sqlvar_compat);
53 :
54 : /* Add space for field names */
55 228 : for (i = 0; i < sqld; i++)
56 184 : offset += strlen(PQfname(res, i)) + 1;
57 :
58 : /* Add padding to the first field value */
59 44 : ecpg_sqlda_align_add_size(offset, sizeof(int), 0, &offset, NULL);
60 :
61 44 : return offset;
62 : }
63 :
64 : static long
65 42 : sqlda_common_total_size(const PGresult *res, int row, enum COMPAT_MODE compat, long offset)
66 : {
67 42 : int sqld = PQnfields(res);
68 : int i;
69 : long next_offset;
70 :
71 : /* Add space for the field values */
72 270 : for (i = 0; i < sqld; i++)
73 : {
74 228 : enum ECPGttype type = sqlda_dynamic_type(PQftype(res, i), compat);
75 :
76 228 : 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 40 : case ECPGt_int:
83 : case ECPGt_unsigned_int:
84 40 : ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
85 40 : break;
86 24 : case ECPGt_long:
87 : case ECPGt_unsigned_long:
88 24 : ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
89 24 : 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 40 : case ECPGt_double:
101 40 : ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
102 40 : break;
103 16 : case ECPGt_decimal:
104 16 : ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
105 16 : break;
106 26 : 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 26 : ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
117 26 : if (!PQgetisnull(res, row, i))
118 : {
119 22 : char *val = PQgetvalue(res, row, i);
120 : numeric *num;
121 :
122 22 : num = PGTYPESnumeric_from_asc(val, NULL);
123 22 : if (!num)
124 0 : break;
125 22 : if (num->buf)
126 14 : ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->digits - num->buf + num->ndigits, &offset, &next_offset);
127 22 : PGTYPESnumeric_free(num);
128 : }
129 26 : 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 82 : case ECPGt_char:
140 : case ECPGt_unsigned_char:
141 : case ECPGt_string:
142 : default:
143 : {
144 82 : long datalen = strlen(PQgetvalue(res, row, i)) + 1;
145 :
146 82 : ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
147 82 : break;
148 : }
149 : }
150 228 : offset = next_offset;
151 : }
152 42 : return offset;
153 : }
154 :
155 :
156 : static long
157 28 : sqlda_compat_total_size(const PGresult *res, int row, enum COMPAT_MODE compat)
158 : {
159 : long offset;
160 :
161 28 : offset = sqlda_compat_empty_size(res);
162 :
163 28 : if (row < 0)
164 12 : return offset;
165 :
166 16 : offset = sqlda_common_total_size(res, row, compat, offset);
167 16 : return offset;
168 : }
169 :
170 : static long
171 64 : sqlda_native_empty_size(const PGresult *res)
172 : {
173 : long offset;
174 64 : int sqld = PQnfields(res);
175 :
176 : /* Initial size to store main structure and field structures */
177 64 : offset = sizeof(struct sqlda_struct) + (sqld - 1) * sizeof(struct sqlvar_struct);
178 :
179 : /* Add padding to the first field value */
180 64 : ecpg_sqlda_align_add_size(offset, sizeof(int), 0, &offset, NULL);
181 :
182 64 : return offset;
183 : }
184 :
185 : static long
186 38 : sqlda_native_total_size(const PGresult *res, int row, enum COMPAT_MODE compat)
187 : {
188 : long offset;
189 :
190 38 : offset = sqlda_native_empty_size(res);
191 :
192 38 : if (row < 0)
193 12 : return offset;
194 :
195 26 : offset = sqlda_common_total_size(res, row, compat, offset);
196 26 : 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 28 : 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 28 : size = sqlda_compat_total_size(res, row, compat);
215 28 : sqlda = (struct sqlda_compat *) ecpg_alloc(size, line);
216 28 : if (!sqlda)
217 0 : return NULL;
218 :
219 28 : memset(sqlda, 0, size);
220 28 : sqlvar = (struct sqlvar_compat *) (sqlda + 1);
221 28 : sqld = PQnfields(res);
222 28 : fname = (char *) (sqlvar + sqld);
223 :
224 28 : sqlda->sqld = sqld;
225 28 : ecpg_log("ecpg_build_compat_sqlda on line %d sqld = %d\n", line, sqld);
226 28 : sqlda->desc_occ = size; /* cheat here, keep the full allocated size */
227 28 : sqlda->sqlvar = sqlvar;
228 :
229 132 : for (i = 0; i < sqlda->sqld; i++)
230 : {
231 104 : sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
232 104 : strcpy(fname, PQfname(res, i));
233 104 : sqlda->sqlvar[i].sqlname = fname;
234 104 : 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 104 : sqlda->sqlvar[i].sqlxid = PQftype(res, i);
242 104 : sqlda->sqlvar[i].sqltypelen = PQfsize(res, i);
243 : }
244 :
245 28 : 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 16 : ecpg_set_compat_sqlda(int lineno, struct sqlda_compat **_sqlda, const PGresult *res, int row, enum COMPAT_MODE compat)
256 : {
257 16 : struct sqlda_compat *sqlda = (*_sqlda);
258 : int i;
259 : long offset,
260 : next_offset;
261 :
262 16 : if (row < 0)
263 0 : return;
264 :
265 : /* Offset for the first field value */
266 16 : offset = sqlda_compat_empty_size(res);
267 :
268 : /*
269 : * Set sqlvar[i]->sqldata pointers and convert values to correct format
270 : */
271 96 : for (i = 0; i < sqlda->sqld; i++)
272 : {
273 : int isnull;
274 : int datalen;
275 80 : bool set_data = true;
276 :
277 80 : 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 16 : case ECPGt_int:
286 : case ECPGt_unsigned_int:
287 16 : ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
288 16 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
289 16 : sqlda->sqlvar[i].sqllen = sizeof(int);
290 16 : 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 16 : case ECPGt_double:
314 16 : ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
315 16 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
316 16 : sqlda->sqlvar[i].sqllen = sizeof(double);
317 16 : break;
318 16 : case ECPGt_decimal:
319 16 : ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
320 16 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
321 16 : sqlda->sqlvar[i].sqllen = sizeof(decimal);
322 16 : 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 32 : case ECPGt_char:
379 : case ECPGt_unsigned_char:
380 : case ECPGt_string:
381 : default:
382 32 : datalen = strlen(PQgetvalue(res, row, i)) + 1;
383 32 : ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
384 32 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
385 32 : sqlda->sqlvar[i].sqllen = datalen;
386 32 : if (datalen > 32768)
387 0 : sqlda->sqlvar[i].sqlilongdata = sqlda->sqlvar[i].sqldata;
388 32 : break;
389 : }
390 :
391 80 : isnull = PQgetisnull(res, row, i);
392 80 : 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 80 : sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
394 80 : sqlda->sqlvar[i].sqlitype = ECPGt_short;
395 80 : sqlda->sqlvar[i].sqlilen = sizeof(short);
396 80 : if (!isnull)
397 : {
398 64 : if (set_data)
399 64 : ecpg_get_data(res, row, i, lineno,
400 64 : sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
401 64 : sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
402 : ECPG_ARRAY_NONE, compat, false);
403 : }
404 : else
405 16 : ECPGset_noind_null(sqlda->sqlvar[i].sqltype, sqlda->sqlvar[i].sqldata);
406 :
407 80 : offset = next_offset;
408 : }
409 : }
410 :
411 : struct sqlda_struct *
412 38 : 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 38 : size = sqlda_native_total_size(res, row, compat);
419 38 : sqlda = (struct sqlda_struct *) ecpg_alloc(size, line);
420 38 : if (!sqlda)
421 0 : return NULL;
422 :
423 38 : memset(sqlda, 0, size);
424 :
425 38 : sprintf(sqlda->sqldaid, "SQLDA ");
426 38 : sqlda->sqld = sqlda->sqln = PQnfields(res);
427 38 : ecpg_log("ecpg_build_native_sqlda on line %d sqld = %d\n", line, sqlda->sqld);
428 38 : sqlda->sqldabc = sizeof(struct sqlda_struct) + (sqlda->sqld - 1) * sizeof(struct sqlvar_struct);
429 :
430 210 : for (i = 0; i < sqlda->sqld; i++)
431 : {
432 : char *fname;
433 :
434 172 : sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
435 172 : fname = PQfname(res, i);
436 172 : sqlda->sqlvar[i].sqlname.length = strlen(fname);
437 172 : strcpy(sqlda->sqlvar[i].sqlname.data, fname);
438 : }
439 :
440 38 : return sqlda;
441 : }
442 :
443 : void
444 26 : ecpg_set_native_sqlda(int lineno, struct sqlda_struct **_sqlda, const PGresult *res, int row, enum COMPAT_MODE compat)
445 : {
446 26 : struct sqlda_struct *sqlda = (*_sqlda);
447 : int i;
448 : long offset,
449 : next_offset;
450 :
451 26 : if (row < 0)
452 0 : return;
453 :
454 : /* Offset for the first field value */
455 26 : offset = sqlda_native_empty_size(res);
456 :
457 : /*
458 : * Set sqlvar[i]->sqldata pointers and convert values to correct format
459 : */
460 174 : for (i = 0; i < sqlda->sqld; i++)
461 : {
462 : int isnull;
463 : int datalen;
464 148 : bool set_data = true;
465 :
466 148 : 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 24 : case ECPGt_int:
475 : case ECPGt_unsigned_int:
476 24 : ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
477 24 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
478 24 : sqlda->sqlvar[i].sqllen = sizeof(int);
479 24 : break;
480 24 : case ECPGt_long:
481 : case ECPGt_unsigned_long:
482 24 : ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
483 24 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
484 24 : sqlda->sqlvar[i].sqllen = sizeof(long);
485 24 : 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 24 : case ECPGt_double:
503 24 : ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
504 24 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
505 24 : sqlda->sqlvar[i].sqllen = sizeof(double);
506 24 : 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 26 : case ECPGt_numeric:
513 : {
514 : numeric *num;
515 : char *val;
516 :
517 26 : set_data = false;
518 :
519 26 : ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
520 26 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
521 26 : sqlda->sqlvar[i].sqllen = sizeof(numeric);
522 :
523 26 : if (PQgetisnull(res, row, i))
524 : {
525 4 : ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
526 4 : break;
527 : }
528 :
529 22 : val = PQgetvalue(res, row, i);
530 22 : num = PGTYPESnumeric_from_asc(val, NULL);
531 22 : if (!num)
532 : {
533 0 : ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
534 0 : break;
535 : }
536 :
537 22 : memcpy(sqlda->sqlvar[i].sqldata, num, sizeof(numeric));
538 :
539 22 : if (num->buf)
540 : {
541 14 : ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->digits - num->buf + num->ndigits, &offset, &next_offset);
542 14 : memcpy((char *) sqlda + offset, num->buf, num->digits - num->buf + num->ndigits);
543 :
544 14 : ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + offset;
545 14 : ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda + offset + (num->digits - num->buf);
546 : }
547 :
548 22 : PGTYPESnumeric_free(num);
549 :
550 22 : 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 50 : case ECPGt_char:
568 : case ECPGt_unsigned_char:
569 : case ECPGt_string:
570 : default:
571 50 : datalen = strlen(PQgetvalue(res, row, i)) + 1;
572 50 : ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
573 50 : sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
574 50 : sqlda->sqlvar[i].sqllen = datalen;
575 50 : break;
576 : }
577 :
578 148 : isnull = PQgetisnull(res, row, i);
579 148 : 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 148 : sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
581 148 : if (!isnull)
582 : {
583 128 : if (set_data)
584 106 : ecpg_get_data(res, row, i, lineno,
585 106 : 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 148 : offset = next_offset;
591 : }
592 : }
|