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
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 == ' ')
26 UBC 0 : return true;
27 :
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')
39 UBC 0 : return true;
40 :
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
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 : */
52 284 : if (isarray == ECPG_ARRAY_NONE)
53 : {
54 274 : if (INFORMIX_MODE(compat) && **scan_length == '.')
55 : {
56 : /* skip invalid characters */
57 : do
58 : {
59 UBC 0 : (*scan_length)++;
60 0 : } while (isdigit((unsigned char) **scan_length));
61 : }
62 :
63 CBC 274 : if (**scan_length != ' ' && **scan_length != '\0')
64 UBC 0 : return true;
65 : }
66 CBC 10 : else if (ECPG_IS_ARRAY(isarray) && !array_delimiter(isarray, **scan_length) && !array_boundary(isarray, **scan_length))
67 UBC 0 : return true;
68 :
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
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__))
94 4 : return (double) NAN;
95 : #else
96 : return (double) (0.0 / 0.0);
97 : #endif
98 : }
99 :
100 : static bool
101 45 : check_special_value(char *ptr, double *retval, char **endptr)
102 : {
103 45 : if (pg_strncasecmp(ptr, "NaN", 3) == 0)
104 : {
105 4 : *retval = get_float8_nan();
106 4 : *endptr = ptr + 3;
107 4 : return true;
108 : }
109 41 : else if (pg_strncasecmp(ptr, "Infinity", 8) == 0)
110 : {
111 4 : *retval = get_float8_infinity();
112 4 : *endptr = ptr + 8;
113 4 : return true;
114 : }
115 37 : else if (pg_strncasecmp(ptr, "-Infinity", 9) == 0)
116 : {
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
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
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 : {
176 UBC 0 : s++;
177 0 : continue;
178 : }
179 CBC 4569 : v1 = get_hex(*s++) << 4;
180 4569 : if (s >= srcend)
181 UBC 0 : return -1;
182 :
183 CBC 4569 : v2 = get_hex(*s++);
184 4569 : *p++ = v1 | v2;
185 : }
186 :
187 9 : return p - dst;
188 : }
189 :
190 : unsigned
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
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 : {
211 1411 : struct sqlca_t *sqlca = ECPGget_sqlca();
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 :
218 1411 : if (sqlca == NULL)
219 : {
220 UBC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
221 : ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
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 : */
229 CBC 1411 : if (ecpg_internal_regression_mode)
230 575 : log_offset = -1;
231 : else
232 836 : log_offset = offset;
233 :
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 */
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 : */
243 UBC 0 : ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
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 : */
253 CBC 1411 : if (PQgetisnull(results, act_tuple, act_field))
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;
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;
274 CBC 1271 : case ECPGt_NO_INDICATOR:
275 1271 : if (value_for_indicator == -1)
276 : {
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 : */
283 12 : ECPGset_noind_null(type, var + offset * act_tuple);
284 : }
285 : else
286 : {
287 2 : ecpg_raise(lineno, ECPG_MISSING_INDICATOR,
288 : ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER,
289 : NULL);
290 2 : return false;
291 : }
292 : }
293 1269 : break;
294 UBC 0 : default:
295 0 : ecpg_raise(lineno, ECPG_UNSUPPORTED,
296 : ECPG_SQLSTATE_ECPG_INTERNAL_ERROR,
297 : ecpg_type_name(ind_type));
298 0 : return false;
299 : break;
300 : }
301 :
302 CBC 1409 : if (value_for_indicator == -1)
303 42 : return true;
304 :
305 : /* let's check if it really is an array if it should be one */
306 1367 : if (isarray == ECPG_ARRAY_ARRAY)
307 : {
308 6 : if (*pval != '{')
309 : {
310 UBC 0 : ecpg_raise(lineno, ECPG_DATA_NOT_ARRAY,
311 : ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
312 0 : return false;
313 : }
314 :
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 : {
331 1412 : if (binary)
332 : {
333 4 : if (varcharsize == 0 || varcharsize * offset >= size)
334 4 : memcpy(var + offset * act_tuple, pval, size);
335 : else
336 : {
337 UBC 0 : memcpy(var + offset * act_tuple, pval, varcharsize * offset);
338 :
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 : }
366 CBC 4 : pval += size;
367 : }
368 : else
369 : {
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:
386 239 : res = strtol(pval, &scan_length, 10);
387 239 : if (garbage_left(isarray, &scan_length, compat))
388 : {
389 UBC 0 : ecpg_raise(lineno, ECPG_INT_FORMAT,
390 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
391 0 : return false;
392 : }
393 CBC 239 : pval = scan_length;
394 :
395 : switch (type)
396 : {
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;
406 UBC 0 : default:
407 : /* Cannot happen */
408 0 : break;
409 : }
410 CBC 239 : break;
411 :
412 UBC 0 : case ECPGt_unsigned_short:
413 : case ECPGt_unsigned_int:
414 : case ECPGt_unsigned_long:
415 0 : ures = strtoul(pval, &scan_length, 10);
416 0 : if (garbage_left(isarray, &scan_length, compat))
417 : {
418 0 : ecpg_raise(lineno, ECPG_UINT_FORMAT,
419 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
420 0 : return false;
421 : }
422 0 : pval = scan_length;
423 :
424 : switch (type)
425 : {
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:
442 0 : *((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
443 UIC 0 : if (garbage_left(isarray, &scan_length, compat))
444 EUB : {
445 UBC 0 : ecpg_raise(lineno, ECPG_INT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
446 UIC 0 : return false;
447 EUB : }
448 UIC 0 : pval = scan_length;
449 EUB :
450 UIC 0 : break;
451 :
452 UBC 0 : case ECPGt_unsigned_long_long:
453 UIC 0 : *((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
454 UBC 0 : if (garbage_left(isarray, &scan_length, compat))
455 EUB : {
456 UIC 0 : ecpg_raise(lineno, ECPG_UINT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
457 UBC 0 : return false;
458 : }
459 0 : pval = scan_length;
460 :
461 LBC 0 : break;
462 ECB :
463 GBC 45 : case ECPGt_float:
464 : case ECPGt_double:
465 CBC 45 : if (isarray && *pval == '"')
466 LBC 0 : pval++;
467 :
468 CBC 45 : if (!check_special_value(pval, &dres, &scan_length))
469 GBC 33 : dres = strtod(pval, &scan_length);
470 :
471 GIC 45 : if (isarray && *scan_length == '"')
472 LBC 0 : scan_length++;
473 :
474 EUB : /* no special INFORMIX treatment for floats */
475 GIC 45 : if (garbage_left(isarray, &scan_length, ECPG_COMPAT_PGSQL))
476 EUB : {
477 UIC 0 : ecpg_raise(lineno, ECPG_FLOAT_FORMAT,
478 ECB : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
479 UIC 0 : return false;
480 : }
481 GIC 45 : pval = scan_length;
482 ECB :
483 : switch (type)
484 : {
485 CBC 7 : case ECPGt_float:
486 7 : *((float *) (var + offset * act_tuple)) = dres;
487 7 : break;
488 GBC 38 : case ECPGt_double:
489 GIC 38 : *((double *) (var + offset * act_tuple)) = dres;
490 GBC 38 : break;
491 UIC 0 : default:
492 ECB : /* Cannot happen */
493 UIC 0 : break;
494 ECB : }
495 CBC 45 : break;
496 :
497 12 : case ECPGt_bool:
498 12 : if (pval[0] == 'f' && pval[1] == '\0')
499 ECB : {
500 GIC 5 : *((bool *) (var + offset * act_tuple)) = false;
501 CBC 5 : pval++;
502 GIC 5 : break;
503 ECB : }
504 CBC 7 : else if (pval[0] == 't' && pval[1] == '\0')
505 ECB : {
506 GIC 7 : *((bool *) (var + offset * act_tuple)) = true;
507 GBC 7 : pval++;
508 GIC 7 : break;
509 : }
510 UBC 0 : else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
511 : {
512 : /* NULL is valid */
513 0 : break;
514 : }
515 EUB :
516 UIC 0 : ecpg_raise(lineno, ECPG_CONVERT_BOOL,
517 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
518 LBC 0 : return false;
519 : break;
520 ECB :
521 CBC 9 : case ECPGt_bytea:
522 : {
523 GIC 9 : struct ECPGgeneric_bytea *variable =
524 9 : (struct ECPGgeneric_bytea *) (var + offset * act_tuple);
525 : long dst_size,
526 ECB : src_size,
527 : dec_size;
528 :
529 CBC 9 : dst_size = ecpg_hex_enc_len(varcharsize);
530 GIC 9 : src_size = size - 2; /* exclude backslash + 'x' */
531 CBC 9 : dec_size = src_size < dst_size ? src_size : dst_size;
532 GIC 9 : variable->len = hex_decode(pval + 2, dec_size, variable->arr);
533 ECB :
534 GIC 9 : if (dst_size < src_size)
535 : {
536 3 : long rcv_size = ecpg_hex_dec_len(size - 2);
537 :
538 EUB : /* truncation */
539 : switch (ind_type)
540 : {
541 UBC 0 : case ECPGt_short:
542 ECB : case ECPGt_unsigned_short:
543 UIC 0 : *((short *) (ind + ind_offset * act_tuple)) = rcv_size;
544 LBC 0 : break;
545 CBC 3 : case ECPGt_int:
546 EUB : case ECPGt_unsigned_int:
547 GIC 3 : *((int *) (ind + ind_offset * act_tuple)) = rcv_size;
548 GBC 3 : break;
549 UBC 0 : case ECPGt_long:
550 EUB : case ECPGt_unsigned_long:
551 UIC 0 : *((long *) (ind + ind_offset * act_tuple)) = rcv_size;
552 UBC 0 : break;
553 0 : case ECPGt_long_long:
554 EUB : case ECPGt_unsigned_long_long:
555 UBC 0 : *((long long int *) (ind + ind_offset * act_tuple)) = rcv_size;
556 UIC 0 : break;
557 LBC 0 : default:
558 UIC 0 : break;
559 : }
560 CBC 3 : sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
561 : }
562 ECB :
563 GIC 9 : pval += size;
564 ECB : }
565 GIC 9 : break;
566 :
567 1024 : case ECPGt_char:
568 ECB : case ECPGt_unsigned_char:
569 : case ECPGt_string:
570 : {
571 GIC 1024 : char *str = (char *) (var + offset * act_tuple);
572 :
573 : /*
574 : * If varcharsize is unknown and the offset is that of
575 ECB : * char *, then this variable represents the array of
576 EUB : * character pointers. So, use extra indirection.
577 : */
578 CBC 1024 : if (varcharsize == 0 && offset == sizeof(char *))
579 UIC 0 : str = *(char **) str;
580 :
581 GIC 1024 : if (varcharsize == 0 || varcharsize > size)
582 : {
583 : /*
584 ECB : * compatibility mode, blank pad and null
585 : * terminate char array
586 : */
587 CBC 976 : if (ORACLE_MODE(compat) && (type == ECPGt_char || type == ECPGt_unsigned_char))
588 ECB : {
589 GIC 9 : memset(str, ' ', varcharsize);
590 9 : memcpy(str, pval, size);
591 9 : str[varcharsize - 1] = '\0';
592 :
593 : /*
594 ECB : * compatibility mode empty string gets -1
595 : * indicator but no warning
596 : */
597 GIC 9 : if (size == 0)
598 : {
599 ECB : /* truncation */
600 : switch (ind_type)
601 : {
602 CBC 2 : case ECPGt_short:
603 EUB : case ECPGt_unsigned_short:
604 GIC 2 : *((short *) (ind + ind_offset * act_tuple)) = -1;
605 GBC 2 : break;
606 UBC 0 : case ECPGt_int:
607 EUB : case ECPGt_unsigned_int:
608 UIC 0 : *((int *) (ind + ind_offset * act_tuple)) = -1;
609 UBC 0 : break;
610 0 : case ECPGt_long:
611 EUB : case ECPGt_unsigned_long:
612 UIC 0 : *((long *) (ind + ind_offset * act_tuple)) = -1;
613 UBC 0 : break;
614 0 : case ECPGt_long_long:
615 EUB : case ECPGt_unsigned_long_long:
616 UBC 0 : *((long long int *) (ind + ind_offset * act_tuple)) = -1;
617 UIC 0 : break;
618 0 : default:
619 0 : break;
620 : }
621 : }
622 ECB : }
623 : else
624 : {
625 CBC 967 : strncpy(str, pval, size + 1);
626 : }
627 ECB : /* do the rtrim() */
628 GIC 976 : if (type == ECPGt_string)
629 ECB : {
630 GIC 2 : char *last = str + size;
631 ECB :
632 CBC 13 : while (last > str && (*last == ' ' || *last == '\0'))
633 : {
634 GIC 11 : *last = '\0';
635 11 : last--;
636 : }
637 : }
638 ECB : }
639 : else
640 : {
641 CBC 48 : strncpy(str, pval, varcharsize);
642 :
643 ECB : /* compatibility mode, null terminate char array */
644 CBC 48 : if (ORACLE_MODE(compat) && (varcharsize - 1) < size)
645 : {
646 GIC 3 : if (type == ECPGt_char || type == ECPGt_unsigned_char)
647 CBC 3 : str[varcharsize - 1] = '\0';
648 : }
649 :
650 GIC 48 : if (varcharsize < size || (ORACLE_MODE(compat) && (varcharsize - 1) < size))
651 : {
652 ECB : /* truncation */
653 : switch (ind_type)
654 : {
655 CBC 3 : case ECPGt_short:
656 ECB : case ECPGt_unsigned_short:
657 GIC 3 : *((short *) (ind + ind_offset * act_tuple)) = size;
658 CBC 3 : break;
659 1 : case ECPGt_int:
660 EUB : case ECPGt_unsigned_int:
661 GIC 1 : *((int *) (ind + ind_offset * act_tuple)) = size;
662 GBC 1 : break;
663 UBC 0 : case ECPGt_long:
664 EUB : case ECPGt_unsigned_long:
665 UIC 0 : *((long *) (ind + ind_offset * act_tuple)) = size;
666 UBC 0 : break;
667 0 : case ECPGt_long_long:
668 ECB : case ECPGt_unsigned_long_long:
669 LBC 0 : *((long long int *) (ind + ind_offset * act_tuple)) = size;
670 UIC 0 : break;
671 CBC 2 : default:
672 GIC 2 : break;
673 : }
674 CBC 6 : sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
675 : }
676 ECB : }
677 GIC 1024 : pval += size;
678 ECB : }
679 GIC 1024 : break;
680 ECB :
681 CBC 22 : case ECPGt_varchar:
682 : {
683 22 : struct ECPGgeneric_varchar *variable =
684 22 : (struct ECPGgeneric_varchar *) (var + offset * act_tuple);
685 EUB :
686 GIC 22 : variable->len = size;
687 22 : if (varcharsize == 0)
688 LBC 0 : strncpy(variable->arr, pval, variable->len);
689 : else
690 ECB : {
691 GIC 22 : strncpy(variable->arr, pval, varcharsize);
692 :
693 22 : if (variable->len > varcharsize)
694 : {
695 EUB : /* truncation */
696 : switch (ind_type)
697 : {
698 UBC 0 : case ECPGt_short:
699 EUB : case ECPGt_unsigned_short:
700 UIC 0 : *((short *) (ind + ind_offset * act_tuple)) = variable->len;
701 UBC 0 : break;
702 0 : case ECPGt_int:
703 EUB : case ECPGt_unsigned_int:
704 UIC 0 : *((int *) (ind + ind_offset * act_tuple)) = variable->len;
705 UBC 0 : break;
706 0 : case ECPGt_long:
707 EUB : case ECPGt_unsigned_long:
708 UIC 0 : *((long *) (ind + ind_offset * act_tuple)) = variable->len;
709 UBC 0 : break;
710 0 : case ECPGt_long_long:
711 EUB : case ECPGt_unsigned_long_long:
712 UBC 0 : *((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
713 UIC 0 : break;
714 UBC 0 : default:
715 UIC 0 : break;
716 EUB : }
717 UIC 0 : sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
718 :
719 LBC 0 : variable->len = varcharsize;
720 : }
721 ECB : }
722 GIC 22 : pval += size;
723 ECB : }
724 GIC 22 : break;
725 ECB :
726 CBC 23 : case ECPGt_decimal:
727 ECB : case ECPGt_numeric:
728 CBC 97 : for (endptr = pval; *endptr && *endptr != ',' && *endptr != '}'; endptr++);
729 23 : endchar = *endptr;
730 GIC 23 : *endptr = '\0';
731 23 : nres = PGTYPESnumeric_from_asc(pval, &scan_length);
732 CBC 23 : *endptr = endchar;
733 :
734 EUB : /* did we get an error? */
735 GBC 23 : if (nres == NULL)
736 : {
737 UBC 0 : ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
738 UIC 0 : lineno, pval, errno);
739 :
740 0 : if (INFORMIX_MODE(compat))
741 : {
742 : /*
743 EUB : * Informix wants its own NULL value here instead
744 : * of an error
745 : */
746 UIC 0 : nres = PGTYPESnumeric_new();
747 0 : if (nres)
748 UBC 0 : ECPGset_noind_null(ECPGt_numeric, nres);
749 : else
750 EUB : {
751 UIC 0 : ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
752 : ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
753 0 : return false;
754 : }
755 EUB : }
756 : else
757 : {
758 UIC 0 : ecpg_raise(lineno, ECPG_NUMERIC_FORMAT,
759 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
760 0 : return false;
761 : }
762 ECB : }
763 : else
764 EUB : {
765 GBC 23 : if (!isarray && garbage_left(isarray, &scan_length, compat))
766 : {
767 UBC 0 : free(nres);
768 UIC 0 : ecpg_raise(lineno, ECPG_NUMERIC_FORMAT,
769 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
770 LBC 0 : return false;
771 : }
772 ECB : }
773 CBC 23 : pval = scan_length;
774 :
775 23 : if (type == ECPGt_numeric)
776 GIC 15 : PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
777 ECB : else
778 CBC 8 : PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));
779 :
780 23 : PGTYPESnumeric_free(nres);
781 23 : break;
782 ECB :
783 GIC 10 : case ECPGt_interval:
784 CBC 10 : if (*pval == '"')
785 10 : pval++;
786 ECB :
787 CBC 110 : for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
788 10 : endchar = *endptr;
789 GIC 10 : *endptr = '\0';
790 10 : ires = PGTYPESinterval_from_asc(pval, &scan_length);
791 CBC 10 : *endptr = endchar;
792 :
793 EUB : /* did we get an error? */
794 GBC 10 : if (ires == NULL)
795 : {
796 UBC 0 : ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
797 UIC 0 : lineno, pval, errno);
798 :
799 0 : if (INFORMIX_MODE(compat))
800 : {
801 : /*
802 EUB : * Informix wants its own NULL value here instead
803 : * of an error
804 : */
805 UIC 0 : ires = (interval *) ecpg_alloc(sizeof(interval), lineno);
806 UBC 0 : if (!ires)
807 UIC 0 : return false;
808 :
809 0 : ECPGset_noind_null(ECPGt_interval, ires);
810 EUB : }
811 : else
812 : {
813 UIC 0 : ecpg_raise(lineno, ECPG_INTERVAL_FORMAT,
814 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
815 0 : return false;
816 : }
817 ECB : }
818 : else
819 : {
820 CBC 10 : if (*scan_length == '"')
821 GIC 10 : scan_length++;
822 EUB :
823 GBC 10 : if (!isarray && garbage_left(isarray, &scan_length, compat))
824 : {
825 UBC 0 : free(ires);
826 UIC 0 : ecpg_raise(lineno, ECPG_INTERVAL_FORMAT,
827 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
828 LBC 0 : return false;
829 : }
830 ECB : }
831 CBC 10 : pval = scan_length;
832 ECB :
833 GIC 10 : PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
834 CBC 10 : free(ires);
835 10 : break;
836 EUB :
837 GIC 11 : case ECPGt_date:
838 CBC 11 : if (*pval == '"')
839 LBC 0 : pval++;
840 ECB :
841 CBC 121 : for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
842 11 : endchar = *endptr;
843 GIC 11 : *endptr = '\0';
844 11 : ddres = PGTYPESdate_from_asc(pval, &scan_length);
845 CBC 11 : *endptr = endchar;
846 :
847 EUB : /* did we get an error? */
848 GBC 11 : if (errno != 0)
849 : {
850 UBC 0 : ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
851 UIC 0 : lineno, pval, errno);
852 :
853 0 : if (INFORMIX_MODE(compat))
854 : {
855 : /*
856 EUB : * Informix wants its own NULL value here instead
857 : * of an error
858 : */
859 UIC 0 : ECPGset_noind_null(ECPGt_date, &ddres);
860 EUB : }
861 : else
862 : {
863 UIC 0 : ecpg_raise(lineno, ECPG_DATE_FORMAT,
864 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
865 0 : return false;
866 : }
867 ECB : }
868 EUB : else
869 : {
870 CBC 11 : if (*scan_length == '"')
871 UIC 0 : scan_length++;
872 EUB :
873 GIC 11 : if (!isarray && garbage_left(isarray, &scan_length, compat))
874 EUB : {
875 UIC 0 : ecpg_raise(lineno, ECPG_DATE_FORMAT,
876 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
877 0 : return false;
878 ECB : }
879 : }
880 :
881 GIC 11 : *((date *) (var + offset * act_tuple)) = ddres;
882 CBC 11 : pval = scan_length;
883 11 : break;
884 ECB :
885 GIC 13 : case ECPGt_timestamp:
886 CBC 13 : if (*pval == '"')
887 10 : pval++;
888 ECB :
889 CBC 320 : for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
890 13 : endchar = *endptr;
891 GIC 13 : *endptr = '\0';
892 13 : tres = PGTYPEStimestamp_from_asc(pval, &scan_length);
893 CBC 13 : *endptr = endchar;
894 :
895 EUB : /* did we get an error? */
896 GBC 13 : if (errno != 0)
897 : {
898 UBC 0 : ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
899 UIC 0 : lineno, pval, errno);
900 :
901 0 : if (INFORMIX_MODE(compat))
902 : {
903 : /*
904 EUB : * Informix wants its own NULL value here instead
905 : * of an error
906 : */
907 UIC 0 : ECPGset_noind_null(ECPGt_timestamp, &tres);
908 EUB : }
909 : else
910 : {
911 UIC 0 : ecpg_raise(lineno, ECPG_TIMESTAMP_FORMAT,
912 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
913 0 : return false;
914 : }
915 ECB : }
916 : else
917 : {
918 CBC 13 : if (*scan_length == '"')
919 GIC 10 : scan_length++;
920 EUB :
921 GIC 13 : if (!isarray && garbage_left(isarray, &scan_length, compat))
922 EUB : {
923 UIC 0 : ecpg_raise(lineno, ECPG_TIMESTAMP_FORMAT,
924 : ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
925 0 : return false;
926 ECB : }
927 : }
928 :
929 GIC 13 : *((timestamp *) (var + offset * act_tuple)) = tres;
930 GBC 13 : pval = scan_length;
931 13 : break;
932 :
933 UIC 0 : default:
934 UBC 0 : ecpg_raise(lineno, ECPG_UNSUPPORTED,
935 : ECPG_SQLSTATE_ECPG_INTERNAL_ERROR,
936 : ecpg_type_name(type));
937 LBC 0 : return false;
938 : break;
939 ECB : }
940 GIC 1408 : if (ECPG_IS_ARRAY(isarray))
941 : {
942 CBC 51 : bool string = false;
943 :
944 : /* set array to next entry */
945 GIC 51 : ++act_tuple;
946 :
947 : /* set pval to the next entry */
948 :
949 : /*
950 ECB : * *pval != '\0' should not be needed, but is used as a safety
951 EUB : * guard
952 : */
953 GIC 51 : for (; *pval != '\0' && (string || (!array_delimiter(isarray, *pval) && !array_boundary(isarray, *pval))); ++pval)
954 LBC 0 : if (*pval == '"')
955 0 : string = string ? false : true;
956 :
957 GIC 51 : if (array_delimiter(isarray, *pval))
958 CBC 45 : ++pval;
959 : }
960 ECB : }
961 GIC 1412 : } while (*pval != '\0' && !array_boundary(isarray, *pval));
962 :
963 1367 : return true;
964 : }
|