Age Owner TLA Line data Source code
1 : /* src/interfaces/ecpg/ecpglib/data.c */
2 :
3 : #define POSTGRES_ECPG_INTERNAL
4 : #include "postgres_fe.h"
5 :
6 : #include <math.h>
7 :
8 : #include "ecpgerrno.h"
9 : #include "ecpglib.h"
10 : #include "ecpglib_extern.h"
11 : #include "ecpgtype.h"
12 : #include "pgtypes_date.h"
13 : #include "pgtypes_interval.h"
14 : #include "pgtypes_numeric.h"
15 : #include "pgtypes_timestamp.h"
16 : #include "sqlca.h"
17 :
18 : /* returns true if character c is a delimiter for the given array type */
19 : static bool
4812 meskes 20 CBC 111 : array_delimiter(enum ARRAY_TYPE isarray, char c)
21 : {
22 111 : if (isarray == ECPG_ARRAY_ARRAY && c == ',')
23 99 : return true;
24 :
25 12 : if (isarray == ECPG_ARRAY_VECTOR && c == ' ')
4812 meskes 26 UBC 0 : return true;
27 :
4812 meskes 28 CBC 12 : return false;
29 : }
30 :
31 : /* returns true if character c marks the boundary for the given array type */
32 : static bool
33 56 : array_boundary(enum ARRAY_TYPE isarray, char c)
34 : {
35 56 : if (isarray == ECPG_ARRAY_ARRAY && c == '}')
36 11 : return true;
37 :
38 45 : if (isarray == ECPG_ARRAY_VECTOR && c == '\0')
4812 meskes 39 UBC 0 : return true;
40 :
4812 meskes 41 CBC 45 : return false;
42 : }
43 :
44 : /* returns true if some garbage is found at the end of the scanned string */
45 : static bool
1985 46 284 : garbage_left(enum ARRAY_TYPE isarray, char **scan_length, enum COMPAT_MODE compat)
47 : {
48 : /*
49 : * INFORMIX allows for selecting a numeric into an int, the result is
50 : * truncated
51 : */
4812 52 284 : if (isarray == ECPG_ARRAY_NONE)
53 : {
1985 54 274 : if (INFORMIX_MODE(compat) && **scan_length == '.')
55 : {
56 : /* skip invalid characters */
57 : do
58 : {
1985 meskes 59 UBC 0 : (*scan_length)++;
1979 tgl 60 0 : } while (isdigit((unsigned char) **scan_length));
61 : }
62 :
1985 meskes 63 CBC 274 : if (**scan_length != ' ' && **scan_length != '\0')
4812 meskes 64 UBC 0 : return true;
65 : }
1985 meskes 66 CBC 10 : else if (ECPG_IS_ARRAY(isarray) && !array_delimiter(isarray, **scan_length) && !array_boundary(isarray, **scan_length))
7092 meskes 67 UBC 0 : return true;
68 :
7092 meskes 69 CBC 284 : return false;
70 : }
71 :
72 : /* stolen code from src/backend/utils/adt/float.c */
73 : #if defined(WIN32) && !defined(NAN)
74 : static const uint32 nan[2] = {0xffffffff, 0x7fffffff};
75 :
76 : #define NAN (*(const double *) nan)
77 : #endif
78 :
79 : static double
4814 80 8 : get_float8_infinity(void)
81 : {
82 : #ifdef INFINITY
83 8 : return (double) INFINITY;
84 : #else
85 : return (double) (HUGE_VAL * HUGE_VAL);
86 : #endif
87 : }
88 :
89 : static double
90 4 : get_float8_nan(void)
91 : {
92 : /* (double) NAN doesn't work on some NetBSD/MIPS releases */
93 : #if defined(NAN) && !(defined(__NetBSD__) && defined(__mips__))
4790 bruce 94 4 : return (double) NAN;
95 : #else
96 : return (double) (0.0 / 0.0);
97 : #endif
98 : }
99 :
100 : static bool
4814 meskes 101 45 : check_special_value(char *ptr, double *retval, char **endptr)
102 : {
4121 peter_e 103 45 : if (pg_strncasecmp(ptr, "NaN", 3) == 0)
104 : {
4814 meskes 105 4 : *retval = get_float8_nan();
106 4 : *endptr = ptr + 3;
107 4 : return true;
108 : }
4121 peter_e 109 41 : else if (pg_strncasecmp(ptr, "Infinity", 8) == 0)
110 : {
4814 meskes 111 4 : *retval = get_float8_infinity();
112 4 : *endptr = ptr + 8;
113 4 : return true;
114 : }
4121 peter_e 115 37 : else if (pg_strncasecmp(ptr, "-Infinity", 9) == 0)
116 : {
4814 meskes 117 4 : *retval = -get_float8_infinity();
118 4 : *endptr = ptr + 9;
119 4 : return true;
120 : }
121 :
122 33 : return false;
123 : }
124 :
125 : /* imported from src/backend/utils/adt/encode.c */
126 :
127 : unsigned
1511 128 35 : ecpg_hex_enc_len(unsigned srclen)
129 : {
130 35 : return srclen << 1;
131 : }
132 :
133 : unsigned
134 3 : ecpg_hex_dec_len(unsigned srclen)
135 : {
136 3 : return srclen >> 1;
137 : }
138 :
139 : static inline char
836 bruce 140 9138 : get_hex(char c)
141 : {
142 : static const int8 hexlookup[128] = {
143 : -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
144 : -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
145 : -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
146 : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
147 : -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
148 : -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
149 : -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
150 : -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
151 : };
152 9138 : int res = -1;
153 :
154 9138 : if (c > 0 && c < 127)
155 9138 : res = hexlookup[(unsigned char) c];
156 :
157 9138 : return (char) res;
158 : }
159 :
160 : static unsigned
161 9 : hex_decode(const char *src, unsigned len, char *dst)
162 : {
163 : const char *s,
164 : *srcend;
165 : char v1,
166 : v2,
167 : *p;
168 :
169 9 : srcend = src + len;
170 9 : s = src;
171 9 : p = dst;
172 4578 : while (s < srcend)
173 : {
174 4569 : if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '\r')
175 : {
836 bruce 176 UBC 0 : s++;
177 0 : continue;
178 : }
836 bruce 179 CBC 4569 : v1 = get_hex(*s++) << 4;
180 4569 : if (s >= srcend)
836 bruce 181 UBC 0 : return -1;
182 :
836 bruce 183 CBC 4569 : v2 = get_hex(*s++);
184 4569 : *p++ = v1 | v2;
185 : }
186 :
187 9 : return p - dst;
188 : }
189 :
190 : unsigned
1511 meskes 191 13 : ecpg_hex_encode(const char *src, unsigned len, char *dst)
192 : {
193 : static const char hextbl[] = "0123456789abcdef";
194 13 : const char *end = src + len;
195 :
196 6669 : while (src < end)
197 : {
198 6656 : *dst++ = hextbl[(*src >> 4) & 0xF];
199 6656 : *dst++ = hextbl[*src & 0xF];
200 6656 : src++;
201 : }
202 13 : return len * 2;
203 : }
204 :
205 : bool
5667 206 1411 : ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
207 : enum ECPGttype type, enum ECPGttype ind_type,
208 : char *var, char *ind, long varcharsize, long offset,
209 : long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)
210 : {
7238 bruce 211 1411 : struct sqlca_t *sqlca = ECPGget_sqlca();
6031 212 1411 : char *pval = (char *) PQgetvalue(results, act_tuple, act_field);
213 1411 : int binary = PQfformat(results, act_field);
214 1411 : int size = PQgetlength(results, act_tuple, act_field);
215 1411 : int value_for_indicator = 0;
216 : long log_offset;
217 :
2855 meskes 218 1411 : if (sqlca == NULL)
219 : {
2855 meskes 220 UBC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
221 : ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
2061 peter_e 222 0 : return false;
223 : }
224 :
225 : /*
226 : * If we are running in a regression test, do not log the offset variable,
227 : * it depends on the machine's alignment.
228 : */
5932 meskes 229 CBC 1411 : if (ecpg_internal_regression_mode)
6088 230 575 : log_offset = -1;
231 : else
232 836 : log_offset = offset;
233 :
4812 234 1411 : ecpg_log("ecpg_get_data on line %d: RESULT: %s offset: %ld; array: %s\n", lineno, pval ? (binary ? "BINARY" : pval) : "EMPTY", log_offset, ECPG_IS_ARRAY(isarray) ? "yes" : "no");
235 :
236 : /* pval is a pointer to the value */
4790 bruce 237 1411 : if (!pval)
238 : {
239 : /*
240 : * This should never happen because we already checked that we found
241 : * at least one tuple, but let's play it safe.
242 : */
4881 meskes 243 UBC 0 : ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
2061 peter_e 244 0 : return false;
245 : }
246 :
247 : /* We will have to decode the value */
248 :
249 : /*
250 : * check for null value and set indicator accordingly, i.e. -1 if NULL and
251 : * 0 if not
252 : */
7228 meskes 253 CBC 1411 : if (PQgetisnull(results, act_tuple, act_field))
7215 254 44 : value_for_indicator = -1;
255 :
256 1411 : switch (ind_type)
257 : {
258 50 : case ECPGt_short:
259 : case ECPGt_unsigned_short:
260 50 : *((short *) (ind + ind_offset * act_tuple)) = value_for_indicator;
261 50 : break;
262 80 : case ECPGt_int:
263 : case ECPGt_unsigned_int:
264 80 : *((int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
265 80 : break;
266 10 : case ECPGt_long:
267 : case ECPGt_unsigned_long:
268 10 : *((long *) (ind + ind_offset * act_tuple)) = value_for_indicator;
269 10 : break;
7215 meskes 270 UBC 0 : case ECPGt_long_long:
271 : case ECPGt_unsigned_long_long:
272 0 : *((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
273 0 : break;
7215 meskes 274 CBC 1271 : case ECPGt_NO_INDICATOR:
275 1271 : if (value_for_indicator == -1)
276 : {
7227 277 14 : if (force_indicator == false)
278 : {
279 : /*
280 : * Informix has an additional way to specify NULLs note
281 : * that this uses special values to denote NULL
282 : */
6860 283 12 : ECPGset_noind_null(type, var + offset * act_tuple);
284 : }
285 : else
286 : {
5667 287 2 : ecpg_raise(lineno, ECPG_MISSING_INDICATOR,
288 : ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER,
289 : NULL);
2061 peter_e 290 2 : return false;
291 : }
292 : }
7215 meskes 293 1269 : break;
7215 meskes 294 UBC 0 : default:
5667 295 0 : ecpg_raise(lineno, ECPG_UNSUPPORTED,
296 : ECPG_SQLSTATE_ECPG_INTERNAL_ERROR,
297 : ecpg_type_name(ind_type));
2061 peter_e 298 0 : return false;
299 : break;
300 : }
301 :
7215 meskes 302 CBC 1409 : if (value_for_indicator == -1)
2061 peter_e 303 42 : return true;
304 :
305 : /* let's check if it really is an array if it should be one */
6437 meskes 306 1367 : if (isarray == ECPG_ARRAY_ARRAY)
307 : {
4881 308 6 : if (*pval != '{')
309 : {
5667 meskes 310 UBC 0 : ecpg_raise(lineno, ECPG_DATA_NOT_ARRAY,
311 : ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
2061 peter_e 312 0 : return false;
313 : }
314 :
6437 meskes 315 CBC 6 : switch (type)
316 : {
317 1 : case ECPGt_char:
318 : case ECPGt_unsigned_char:
319 : case ECPGt_varchar:
320 : case ECPGt_string:
321 1 : break;
322 :
323 5 : default:
324 5 : pval++;
325 5 : break;
326 : }
327 : }
328 :
329 : do
330 : {
6291 331 1412 : if (binary)
332 : {
4881 333 4 : if (varcharsize == 0 || varcharsize * offset >= size)
4847 tgl 334 4 : memcpy(var + offset * act_tuple, pval, size);
335 : else
336 : {
4847 tgl 337 UBC 0 : memcpy(var + offset * act_tuple, pval, varcharsize * offset);
338 :
4881 meskes 339 0 : if (varcharsize * offset < size)
340 : {
341 : /* truncation */
342 0 : switch (ind_type)
343 : {
344 0 : case ECPGt_short:
345 : case ECPGt_unsigned_short:
346 0 : *((short *) (ind + ind_offset * act_tuple)) = size;
347 0 : break;
348 0 : case ECPGt_int:
349 : case ECPGt_unsigned_int:
350 0 : *((int *) (ind + ind_offset * act_tuple)) = size;
351 0 : break;
352 0 : case ECPGt_long:
353 : case ECPGt_unsigned_long:
354 0 : *((long *) (ind + ind_offset * act_tuple)) = size;
355 0 : break;
356 0 : case ECPGt_long_long:
357 : case ECPGt_unsigned_long_long:
358 0 : *((long long int *) (ind + ind_offset * act_tuple)) = size;
359 0 : break;
360 0 : default:
361 0 : break;
362 : }
363 0 : sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
364 : }
365 : }
4881 meskes 366 CBC 4 : pval += size;
367 : }
368 : else
369 : {
6031 bruce 370 1408 : switch (type)
371 : {
372 : long res;
373 : unsigned long ures;
374 : double dres;
375 : char *scan_length;
376 : numeric *nres;
377 : date ddres;
378 : timestamp tres;
379 : interval *ires;
380 : char *endptr,
381 : endchar;
382 :
383 239 : case ECPGt_short:
384 : case ECPGt_int:
385 : case ECPGt_long:
4881 meskes 386 239 : res = strtol(pval, &scan_length, 10);
1985 387 239 : if (garbage_left(isarray, &scan_length, compat))
388 : {
4881 meskes 389 UBC 0 : ecpg_raise(lineno, ECPG_INT_FORMAT,
390 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
2061 peter_e 391 0 : return false;
392 : }
4881 meskes 393 CBC 239 : pval = scan_length;
394 :
395 : switch (type)
396 : {
6031 bruce 397 16 : case ECPGt_short:
398 16 : *((short *) (var + offset * act_tuple)) = (short) res;
399 16 : break;
400 210 : case ECPGt_int:
401 210 : *((int *) (var + offset * act_tuple)) = (int) res;
402 210 : break;
403 13 : case ECPGt_long:
404 13 : *((long *) (var + offset * act_tuple)) = (long) res;
405 13 : break;
6031 bruce 406 UBC 0 : default:
407 : /* Cannot happen */
408 0 : break;
409 : }
6031 bruce 410 CBC 239 : break;
411 :
6031 bruce 412 UBC 0 : case ECPGt_unsigned_short:
413 : case ECPGt_unsigned_int:
414 : case ECPGt_unsigned_long:
4881 meskes 415 0 : ures = strtoul(pval, &scan_length, 10);
1985 416 0 : if (garbage_left(isarray, &scan_length, compat))
417 : {
4881 418 0 : ecpg_raise(lineno, ECPG_UINT_FORMAT,
419 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
2061 peter_e 420 0 : return false;
421 : }
4881 meskes 422 0 : pval = scan_length;
423 :
424 : switch (type)
425 : {
6031 bruce 426 0 : case ECPGt_unsigned_short:
427 0 : *((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
428 0 : break;
429 0 : case ECPGt_unsigned_int:
430 0 : *((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
431 0 : break;
432 0 : case ECPGt_unsigned_long:
433 0 : *((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
434 0 : break;
435 0 : default:
436 : /* Cannot happen */
437 0 : break;
438 : }
439 0 : break;
440 :
441 0 : case ECPGt_long_long:
4881 meskes 442 0 : *((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
1985 meskes 443 UIC 0 : if (garbage_left(isarray, &scan_length, compat))
7329 meskes 444 EUB : {
4881 meskes 445 UBC 0 : ecpg_raise(lineno, ECPG_INT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
2061 peter_e 446 UIC 0 : return false;
7329 meskes 447 EUB : }
4881 meskes 448 UIC 0 : pval = scan_length;
7329 meskes 449 EUB :
6031 bruce 450 UIC 0 : break;
451 :
6031 bruce 452 UBC 0 : case ECPGt_unsigned_long_long:
4881 meskes 453 UIC 0 : *((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
1985 meskes 454 UBC 0 : if (garbage_left(isarray, &scan_length, compat))
7329 meskes 455 EUB : {
4881 meskes 456 UIC 0 : ecpg_raise(lineno, ECPG_UINT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
2061 peter_e 457 UBC 0 : return false;
458 : }
4881 meskes 459 0 : pval = scan_length;
460 :
6031 bruce 461 LBC 0 : break;
7329 meskes 462 ECB :
6031 bruce 463 GBC 45 : case ECPGt_float:
464 : case ECPGt_double:
4881 meskes 465 CBC 45 : if (isarray && *pval == '"')
4814 meskes 466 LBC 0 : pval++;
467 :
4814 meskes 468 CBC 45 : if (!check_special_value(pval, &dres, &scan_length))
4881 meskes 469 GBC 33 : dres = strtod(pval, &scan_length);
470 :
4881 meskes 471 GIC 45 : if (isarray && *scan_length == '"')
4881 meskes 472 LBC 0 : scan_length++;
473 :
1984 meskes 474 EUB : /* no special INFORMIX treatment for floats */
1984 meskes 475 GIC 45 : if (garbage_left(isarray, &scan_length, ECPG_COMPAT_PGSQL))
4881 meskes 476 EUB : {
4881 meskes 477 UIC 0 : ecpg_raise(lineno, ECPG_FLOAT_FORMAT,
4881 meskes 478 ECB : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
2061 peter_e 479 UIC 0 : return false;
480 : }
4881 meskes 481 GIC 45 : pval = scan_length;
6031 bruce 482 ECB :
483 : switch (type)
7329 meskes 484 : {
6031 bruce 485 CBC 7 : case ECPGt_float:
486 7 : *((float *) (var + offset * act_tuple)) = dres;
487 7 : break;
6031 bruce 488 GBC 38 : case ECPGt_double:
6031 bruce 489 GIC 38 : *((double *) (var + offset * act_tuple)) = dres;
6031 bruce 490 GBC 38 : break;
6031 bruce 491 UIC 0 : default:
6031 bruce 492 ECB : /* Cannot happen */
6031 bruce 493 UIC 0 : break;
7329 meskes 494 ECB : }
6031 bruce 495 CBC 45 : break;
496 :
497 12 : case ECPGt_bool:
4881 meskes 498 12 : if (pval[0] == 'f' && pval[1] == '\0')
7329 meskes 499 ECB : {
2761 meskes 500 GIC 5 : *((bool *) (var + offset * act_tuple)) = false;
3838 meskes 501 CBC 5 : pval++;
4881 meskes 502 GIC 5 : break;
4881 meskes 503 ECB : }
4881 meskes 504 CBC 7 : else if (pval[0] == 't' && pval[1] == '\0')
4881 meskes 505 ECB : {
2761 meskes 506 GIC 7 : *((bool *) (var + offset * act_tuple)) = true;
3838 meskes 507 GBC 7 : pval++;
4881 meskes 508 GIC 7 : break;
509 : }
4881 meskes 510 UBC 0 : else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
511 : {
512 : /* NULL is valid */
513 0 : break;
514 : }
7329 meskes 515 EUB :
5667 meskes 516 UIC 0 : ecpg_raise(lineno, ECPG_CONVERT_BOOL,
517 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
2061 peter_e 518 LBC 0 : return false;
519 : break;
7329 meskes 520 ECB :
1511 meskes 521 CBC 9 : case ECPGt_bytea:
522 : {
986 michael 523 GIC 9 : struct ECPGgeneric_bytea *variable =
524 9 : (struct ECPGgeneric_bytea *) (var + offset * act_tuple);
525 : long dst_size,
1511 meskes 526 ECB : src_size,
527 : dec_size;
528 :
1511 meskes 529 CBC 9 : dst_size = ecpg_hex_enc_len(varcharsize);
1511 meskes 530 GIC 9 : src_size = size - 2; /* exclude backslash + 'x' */
1511 meskes 531 CBC 9 : dec_size = src_size < dst_size ? src_size : dst_size;
1511 meskes 532 GIC 9 : variable->len = hex_decode(pval + 2, dec_size, variable->arr);
1511 meskes 533 ECB :
1511 meskes 534 GIC 9 : if (dst_size < src_size)
535 : {
536 3 : long rcv_size = ecpg_hex_dec_len(size - 2);
537 :
1511 meskes 538 EUB : /* truncation */
539 : switch (ind_type)
540 : {
1511 meskes 541 UBC 0 : case ECPGt_short:
1511 meskes 542 ECB : case ECPGt_unsigned_short:
1511 meskes 543 UIC 0 : *((short *) (ind + ind_offset * act_tuple)) = rcv_size;
1511 meskes 544 LBC 0 : break;
1511 meskes 545 CBC 3 : case ECPGt_int:
1511 meskes 546 EUB : case ECPGt_unsigned_int:
1511 meskes 547 GIC 3 : *((int *) (ind + ind_offset * act_tuple)) = rcv_size;
1511 meskes 548 GBC 3 : break;
1511 meskes 549 UBC 0 : case ECPGt_long:
1511 meskes 550 EUB : case ECPGt_unsigned_long:
1511 meskes 551 UIC 0 : *((long *) (ind + ind_offset * act_tuple)) = rcv_size;
1511 meskes 552 UBC 0 : break;
553 0 : case ECPGt_long_long:
1511 meskes 554 EUB : case ECPGt_unsigned_long_long:
1511 meskes 555 UBC 0 : *((long long int *) (ind + ind_offset * act_tuple)) = rcv_size;
1511 meskes 556 UIC 0 : break;
1511 meskes 557 LBC 0 : default:
1511 meskes 558 UIC 0 : break;
559 : }
1511 meskes 560 CBC 3 : sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
561 : }
1511 meskes 562 ECB :
1511 meskes 563 GIC 9 : pval += size;
1511 meskes 564 ECB : }
1511 meskes 565 GIC 9 : break;
566 :
6031 bruce 567 1024 : case ECPGt_char:
6031 bruce 568 ECB : case ECPGt_unsigned_char:
569 : case ECPGt_string:
570 : {
4790 bruce 571 GIC 1024 : char *str = (char *) (var + offset * act_tuple);
572 :
573 : /*
574 : * If varcharsize is unknown and the offset is that of
3260 meskes 575 ECB : * char *, then this variable represents the array of
3260 meskes 576 EUB : * character pointers. So, use extra indirection.
577 : */
3260 meskes 578 CBC 1024 : if (varcharsize == 0 && offset == sizeof(char *))
3260 bruce 579 UIC 0 : str = *(char **) str;
580 :
6031 bruce 581 GIC 1024 : if (varcharsize == 0 || varcharsize > size)
582 : {
583 : /*
1809 tgl 584 ECB : * compatibility mode, blank pad and null
585 : * terminate char array
586 : */
1852 meskes 587 CBC 976 : if (ORACLE_MODE(compat) && (type == ECPGt_char || type == ECPGt_unsigned_char))
1852 meskes 588 ECB : {
1852 meskes 589 GIC 9 : memset(str, ' ', varcharsize);
590 9 : memcpy(str, pval, size);
1809 tgl 591 9 : str[varcharsize - 1] = '\0';
592 :
593 : /*
1809 tgl 594 ECB : * compatibility mode empty string gets -1
595 : * indicator but no warning
596 : */
1809 tgl 597 GIC 9 : if (size == 0)
598 : {
1852 meskes 599 ECB : /* truncation */
600 : switch (ind_type)
601 : {
1852 meskes 602 CBC 2 : case ECPGt_short:
1852 meskes 603 EUB : case ECPGt_unsigned_short:
1852 meskes 604 GIC 2 : *((short *) (ind + ind_offset * act_tuple)) = -1;
1852 meskes 605 GBC 2 : break;
1852 meskes 606 UBC 0 : case ECPGt_int:
1852 meskes 607 EUB : case ECPGt_unsigned_int:
1852 meskes 608 UIC 0 : *((int *) (ind + ind_offset * act_tuple)) = -1;
1852 meskes 609 UBC 0 : break;
610 0 : case ECPGt_long:
1852 meskes 611 EUB : case ECPGt_unsigned_long:
1852 meskes 612 UIC 0 : *((long *) (ind + ind_offset * act_tuple)) = -1;
1852 meskes 613 UBC 0 : break;
614 0 : case ECPGt_long_long:
1852 meskes 615 EUB : case ECPGt_unsigned_long_long:
1852 meskes 616 UBC 0 : *((long long int *) (ind + ind_offset * act_tuple)) = -1;
1852 meskes 617 UIC 0 : break;
618 0 : default:
619 0 : break;
620 : }
621 : }
1852 meskes 622 ECB : }
623 : else
624 : {
1852 meskes 625 CBC 967 : strncpy(str, pval, size + 1);
626 : }
4993 meskes 627 ECB : /* do the rtrim() */
4993 meskes 628 GIC 976 : if (type == ECPGt_string)
4993 meskes 629 ECB : {
4790 bruce 630 GIC 2 : char *last = str + size;
4790 bruce 631 ECB :
4993 meskes 632 CBC 13 : while (last > str && (*last == ' ' || *last == '\0'))
633 : {
4993 meskes 634 GIC 11 : *last = '\0';
635 11 : last--;
636 : }
637 : }
4993 meskes 638 ECB : }
639 : else
640 : {
4993 meskes 641 CBC 48 : strncpy(str, pval, varcharsize);
642 :
1852 meskes 643 ECB : /* compatibility mode, null terminate char array */
1852 meskes 644 CBC 48 : if (ORACLE_MODE(compat) && (varcharsize - 1) < size)
645 : {
1852 meskes 646 GIC 3 : if (type == ECPGt_char || type == ECPGt_unsigned_char)
1809 tgl 647 CBC 3 : str[varcharsize - 1] = '\0';
648 : }
649 :
1852 meskes 650 GIC 48 : if (varcharsize < size || (ORACLE_MODE(compat) && (varcharsize - 1) < size))
651 : {
6031 bruce 652 ECB : /* truncation */
653 : switch (ind_type)
654 : {
6031 bruce 655 CBC 3 : case ECPGt_short:
6031 bruce 656 ECB : case ECPGt_unsigned_short:
6031 bruce 657 GIC 3 : *((short *) (ind + ind_offset * act_tuple)) = size;
6031 bruce 658 CBC 3 : break;
659 1 : case ECPGt_int:
6031 bruce 660 EUB : case ECPGt_unsigned_int:
6031 bruce 661 GIC 1 : *((int *) (ind + ind_offset * act_tuple)) = size;
6031 bruce 662 GBC 1 : break;
6031 bruce 663 UBC 0 : case ECPGt_long:
6031 bruce 664 EUB : case ECPGt_unsigned_long:
6031 bruce 665 UIC 0 : *((long *) (ind + ind_offset * act_tuple)) = size;
6031 bruce 666 UBC 0 : break;
667 0 : case ECPGt_long_long:
6031 bruce 668 ECB : case ECPGt_unsigned_long_long:
6031 bruce 669 LBC 0 : *((long long int *) (ind + ind_offset * act_tuple)) = size;
6031 bruce 670 UIC 0 : break;
6031 bruce 671 CBC 2 : default:
6031 bruce 672 GIC 2 : break;
673 : }
6031 bruce 674 CBC 6 : sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
675 : }
7329 meskes 676 ECB : }
6031 bruce 677 GIC 1024 : pval += size;
7329 meskes 678 ECB : }
6031 bruce 679 GIC 1024 : break;
7329 meskes 680 ECB :
6031 bruce 681 CBC 22 : case ECPGt_varchar:
682 : {
683 22 : struct ECPGgeneric_varchar *variable =
4847 tgl 684 22 : (struct ECPGgeneric_varchar *) (var + offset * act_tuple);
7329 meskes 685 EUB :
6031 bruce 686 GIC 22 : variable->len = size;
687 22 : if (varcharsize == 0)
6031 bruce 688 LBC 0 : strncpy(variable->arr, pval, variable->len);
689 : else
7329 meskes 690 ECB : {
6031 bruce 691 GIC 22 : strncpy(variable->arr, pval, varcharsize);
692 :
693 22 : if (variable->len > varcharsize)
694 : {
6031 bruce 695 EUB : /* truncation */
696 : switch (ind_type)
697 : {
6031 bruce 698 UBC 0 : case ECPGt_short:
6031 bruce 699 EUB : case ECPGt_unsigned_short:
3421 meskes 700 UIC 0 : *((short *) (ind + ind_offset * act_tuple)) = variable->len;
6031 bruce 701 UBC 0 : break;
702 0 : case ECPGt_int:
6031 bruce 703 EUB : case ECPGt_unsigned_int:
3421 meskes 704 UIC 0 : *((int *) (ind + ind_offset * act_tuple)) = variable->len;
6031 bruce 705 UBC 0 : break;
706 0 : case ECPGt_long:
6031 bruce 707 EUB : case ECPGt_unsigned_long:
3421 meskes 708 UIC 0 : *((long *) (ind + ind_offset * act_tuple)) = variable->len;
6031 bruce 709 UBC 0 : break;
710 0 : case ECPGt_long_long:
6031 bruce 711 EUB : case ECPGt_unsigned_long_long:
6031 bruce 712 UBC 0 : *((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
6031 bruce 713 UIC 0 : break;
6031 bruce 714 UBC 0 : default:
6031 bruce 715 UIC 0 : break;
6031 bruce 716 EUB : }
6031 bruce 717 UIC 0 : sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
718 :
6031 bruce 719 LBC 0 : variable->len = varcharsize;
720 : }
7234 meskes 721 ECB : }
6031 bruce 722 GIC 22 : pval += size;
7329 meskes 723 ECB : }
6031 bruce 724 GIC 22 : break;
7329 meskes 725 ECB :
6031 bruce 726 CBC 23 : case ECPGt_decimal:
6031 bruce 727 ECB : case ECPGt_numeric:
2980 meskes 728 CBC 97 : for (endptr = pval; *endptr && *endptr != ',' && *endptr != '}'; endptr++);
729 23 : endchar = *endptr;
2980 meskes 730 GIC 23 : *endptr = '\0';
731 23 : nres = PGTYPESnumeric_from_asc(pval, &scan_length);
2980 meskes 732 CBC 23 : *endptr = endchar;
733 :
4881 meskes 734 EUB : /* did we get an error? */
4881 meskes 735 GBC 23 : if (nres == NULL)
736 : {
4881 meskes 737 UBC 0 : ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
2965 meskes 738 UIC 0 : lineno, pval, errno);
739 :
4881 740 0 : if (INFORMIX_MODE(compat))
741 : {
742 : /*
4790 bruce 743 EUB : * Informix wants its own NULL value here instead
744 : * of an error
4881 meskes 745 : */
4881 meskes 746 UIC 0 : nres = PGTYPESnumeric_new();
747 0 : if (nres)
4881 meskes 748 UBC 0 : ECPGset_noind_null(ECPGt_numeric, nres);
749 : else
6136 meskes 750 EUB : {
4881 meskes 751 UIC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
752 : ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
2061 peter_e 753 0 : return false;
754 : }
7143 meskes 755 EUB : }
756 : else
757 : {
4881 meskes 758 UIC 0 : ecpg_raise(lineno, ECPG_NUMERIC_FORMAT,
759 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
2061 peter_e 760 0 : return false;
761 : }
7329 meskes 762 ECB : }
763 : else
4881 meskes 764 EUB : {
1985 meskes 765 GBC 23 : if (!isarray && garbage_left(isarray, &scan_length, compat))
766 : {
4881 meskes 767 UBC 0 : free(nres);
4881 meskes 768 UIC 0 : ecpg_raise(lineno, ECPG_NUMERIC_FORMAT,
769 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
2061 peter_e 770 LBC 0 : return false;
771 : }
4881 meskes 772 ECB : }
4881 meskes 773 CBC 23 : pval = scan_length;
774 :
6031 bruce 775 23 : if (type == ECPGt_numeric)
6031 bruce 776 GIC 15 : PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
7318 meskes 777 ECB : else
6031 bruce 778 CBC 8 : PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));
779 :
4938 meskes 780 23 : PGTYPESnumeric_free(nres);
6031 bruce 781 23 : break;
7318 meskes 782 ECB :
6031 bruce 783 GIC 10 : case ECPGt_interval:
2980 meskes 784 CBC 10 : if (*pval == '"')
785 10 : pval++;
2980 meskes 786 ECB :
2980 meskes 787 CBC 110 : for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
788 10 : endchar = *endptr;
2980 meskes 789 GIC 10 : *endptr = '\0';
790 10 : ires = PGTYPESinterval_from_asc(pval, &scan_length);
2980 meskes 791 CBC 10 : *endptr = endchar;
792 :
4881 meskes 793 EUB : /* did we get an error? */
4881 meskes 794 GBC 10 : if (ires == NULL)
795 : {
4881 meskes 796 UBC 0 : ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
2965 meskes 797 UIC 0 : lineno, pval, errno);
798 :
4881 799 0 : if (INFORMIX_MODE(compat))
800 : {
801 : /*
4790 bruce 802 EUB : * Informix wants its own NULL value here instead
803 : * of an error
4881 meskes 804 : */
4881 meskes 805 UIC 0 : ires = (interval *) ecpg_alloc(sizeof(interval), lineno);
4881 meskes 806 UBC 0 : if (!ires)
2061 peter_e 807 UIC 0 : return false;
808 :
4881 meskes 809 0 : ECPGset_noind_null(ECPGt_interval, ires);
7143 meskes 810 EUB : }
811 : else
812 : {
4881 meskes 813 UIC 0 : ecpg_raise(lineno, ECPG_INTERVAL_FORMAT,
814 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
2061 peter_e 815 0 : return false;
816 : }
7318 meskes 817 ECB : }
7325 818 : else
819 : {
2980 meskes 820 CBC 10 : if (*scan_length == '"')
4881 meskes 821 GIC 10 : scan_length++;
4881 meskes 822 EUB :
1985 meskes 823 GBC 10 : if (!isarray && garbage_left(isarray, &scan_length, compat))
824 : {
4881 meskes 825 UBC 0 : free(ires);
4881 meskes 826 UIC 0 : ecpg_raise(lineno, ECPG_INTERVAL_FORMAT,
827 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
2061 peter_e 828 LBC 0 : return false;
829 : }
4881 meskes 830 ECB : }
4881 meskes 831 CBC 10 : pval = scan_length;
7325 meskes 832 ECB :
6031 bruce 833 GIC 10 : PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
6031 bruce 834 CBC 10 : free(ires);
835 10 : break;
4881 meskes 836 EUB :
6031 bruce 837 GIC 11 : case ECPGt_date:
2980 meskes 838 CBC 11 : if (*pval == '"')
2980 meskes 839 LBC 0 : pval++;
2980 meskes 840 ECB :
2980 meskes 841 CBC 121 : for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
842 11 : endchar = *endptr;
2980 meskes 843 GIC 11 : *endptr = '\0';
844 11 : ddres = PGTYPESdate_from_asc(pval, &scan_length);
2980 meskes 845 CBC 11 : *endptr = endchar;
846 :
4881 meskes 847 EUB : /* did we get an error? */
4881 meskes 848 GBC 11 : if (errno != 0)
849 : {
4881 meskes 850 UBC 0 : ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
2965 meskes 851 UIC 0 : lineno, pval, errno);
852 :
4881 853 0 : if (INFORMIX_MODE(compat))
854 : {
855 : /*
4790 bruce 856 EUB : * Informix wants its own NULL value here instead
857 : * of an error
858 : */
4881 meskes 859 UIC 0 : ECPGset_noind_null(ECPGt_date, &ddres);
7143 meskes 860 EUB : }
861 : else
7142 862 : {
4881 meskes 863 UIC 0 : ecpg_raise(lineno, ECPG_DATE_FORMAT,
864 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
2061 peter_e 865 0 : return false;
866 : }
4881 meskes 867 ECB : }
4881 meskes 868 EUB : else
869 : {
2980 meskes 870 CBC 11 : if (*scan_length == '"')
4881 meskes 871 UIC 0 : scan_length++;
7329 meskes 872 EUB :
1985 meskes 873 GIC 11 : if (!isarray && garbage_left(isarray, &scan_length, compat))
4881 meskes 874 EUB : {
4881 meskes 875 UIC 0 : ecpg_raise(lineno, ECPG_DATE_FORMAT,
876 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
2061 peter_e 877 0 : return false;
4881 meskes 878 ECB : }
6031 bruce 879 : }
4881 meskes 880 :
4881 meskes 881 GIC 11 : *((date *) (var + offset * act_tuple)) = ddres;
4881 meskes 882 CBC 11 : pval = scan_length;
6031 bruce 883 11 : break;
7325 meskes 884 ECB :
6031 bruce 885 GIC 13 : case ECPGt_timestamp:
2980 meskes 886 CBC 13 : if (*pval == '"')
887 10 : pval++;
2980 meskes 888 ECB :
2980 meskes 889 CBC 320 : for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
890 13 : endchar = *endptr;
2980 meskes 891 GIC 13 : *endptr = '\0';
892 13 : tres = PGTYPEStimestamp_from_asc(pval, &scan_length);
2980 meskes 893 CBC 13 : *endptr = endchar;
894 :
4881 meskes 895 EUB : /* did we get an error? */
4881 meskes 896 GBC 13 : if (errno != 0)
897 : {
4881 meskes 898 UBC 0 : ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
2965 meskes 899 UIC 0 : lineno, pval, errno);
900 :
4881 901 0 : if (INFORMIX_MODE(compat))
902 : {
903 : /*
4790 bruce 904 EUB : * Informix wants its own NULL value here instead
905 : * of an error
906 : */
4881 meskes 907 UIC 0 : ECPGset_noind_null(ECPGt_timestamp, &tres);
7143 meskes 908 EUB : }
909 : else
7142 910 : {
4881 meskes 911 UIC 0 : ecpg_raise(lineno, ECPG_TIMESTAMP_FORMAT,
912 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
2061 peter_e 913 0 : return false;
914 : }
4881 meskes 915 ECB : }
916 : else
917 : {
2980 meskes 918 CBC 13 : if (*scan_length == '"')
4881 meskes 919 GIC 10 : scan_length++;
7325 meskes 920 EUB :
1985 meskes 921 GIC 13 : if (!isarray && garbage_left(isarray, &scan_length, compat))
4881 meskes 922 EUB : {
4881 meskes 923 UIC 0 : ecpg_raise(lineno, ECPG_TIMESTAMP_FORMAT,
924 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
2061 peter_e 925 0 : return false;
4881 meskes 926 ECB : }
6031 bruce 927 : }
4881 meskes 928 :
4881 meskes 929 GIC 13 : *((timestamp *) (var + offset * act_tuple)) = tres;
4881 meskes 930 GBC 13 : pval = scan_length;
6031 bruce 931 13 : break;
932 :
6031 bruce 933 UIC 0 : default:
5667 meskes 934 UBC 0 : ecpg_raise(lineno, ECPG_UNSUPPORTED,
935 : ECPG_SQLSTATE_ECPG_INTERNAL_ERROR,
936 : ecpg_type_name(type));
2061 peter_e 937 LBC 0 : return false;
938 : break;
6031 bruce 939 ECB : }
4812 meskes 940 GIC 1408 : if (ECPG_IS_ARRAY(isarray))
941 : {
6031 bruce 942 CBC 51 : bool string = false;
943 :
944 : /* set array to next entry */
6031 bruce 945 GIC 51 : ++act_tuple;
946 :
947 : /* set pval to the next entry */
948 :
949 : /*
4790 bruce 950 ECB : * *pval != '\0' should not be needed, but is used as a safety
4790 bruce 951 EUB : * guard
952 : */
4812 meskes 953 GIC 51 : for (; *pval != '\0' && (string || (!array_delimiter(isarray, *pval) && !array_boundary(isarray, *pval))); ++pval)
6031 bruce 954 LBC 0 : if (*pval == '"')
955 0 : string = string ? false : true;
956 :
4812 meskes 957 GIC 51 : if (array_delimiter(isarray, *pval))
6031 bruce 958 CBC 45 : ++pval;
959 : }
6291 meskes 960 ECB : }
3838 meskes 961 GIC 1412 : } while (*pval != '\0' && !array_boundary(isarray, *pval));
962 :
2061 peter_e 963 1367 : return true;
964 : }
|