Branch data 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 : : }
|