1 /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.17 2003/09/09 10:46:37 meskes Exp $ */
3 #define POSTGRES_ECPG_INTERNAL
4 #include "postgres_fe.h"
11 #include "ecpgerrno.h"
14 #include "pgtypes_numeric.h"
15 #include "pgtypes_date.h"
16 #include "pgtypes_timestamp.h"
17 #include "pgtypes_interval.h"
20 ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
21 enum ECPGttype type, enum ECPGttype ind_type,
22 char *var, char *ind, long varcharsize, long offset,
23 long ind_offset, bool isarray, enum COMPAT_MODE compat, bool force_indicator)
25 struct sqlca_t *sqlca = ECPGget_sqlca();
26 char *pval = (char *) PQgetvalue(results, act_tuple, act_field);
27 int value_for_indicator = 0;
29 ECPGlog("ECPGget_data line %d: RESULT: %s offset: %ld\n", lineno, pval ? pval : "", offset);
31 /* pval is a pointer to the value */
32 /* let's check is it really is an array if it should be one */
37 ECPGraise(lineno, ECPG_DATA_NOT_ARRAY, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
44 case ECPGt_unsigned_char:
54 /* We will have to decode the value */
57 * check for null value and set indicator accordingly, i.e. -1 if NULL
60 if (PQgetisnull(results, act_tuple, act_field))
61 value_for_indicator = -1;
66 case ECPGt_unsigned_short:
67 *((short *) (ind + ind_offset * act_tuple)) = value_for_indicator;
70 case ECPGt_unsigned_int:
71 *((int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
74 case ECPGt_unsigned_long:
75 *((long *) (ind + ind_offset * act_tuple)) = value_for_indicator;
77 #ifdef HAVE_LONG_LONG_INT_64
79 case ECPGt_unsigned_long_long:
80 *((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
82 #endif /* HAVE_LONG_LONG_INT_64 */
83 case ECPGt_NO_INDICATOR:
84 if (value_for_indicator == -1)
86 if (force_indicator == false)
89 * Informix has an additional way to specify NULLs
90 * note that this uses special values to denote NULL
92 ECPGset_informix_null(type, var + offset * act_tuple);
96 ECPGraise(lineno, ECPG_MISSING_INDICATOR, ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER, NULL);
102 ECPGraise(lineno, ECPG_UNSUPPORTED, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ECPGtype_name(ind_type));
107 if (value_for_indicator == -1)
128 res = strtol(pval, &scan_length, 10);
129 /* INFORMIX allows for selecting a numeric into an int, the result is truncated */
130 if ((isarray && *scan_length != ',' && *scan_length != '}')
131 || (!isarray && !(INFORMIX_MODE(compat) && *scan_length == '.') && *scan_length != '\0' && *scan_length != ' ')) /* Garbage left */
133 ECPGraise(lineno, ECPG_INT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
143 *((short *) (var + offset * act_tuple)) = (short) res;
146 *((int *) (var + offset * act_tuple)) = (int) res;
149 *((long *) (var + offset * act_tuple)) = (long) res;
157 case ECPGt_unsigned_short:
158 case ECPGt_unsigned_int:
159 case ECPGt_unsigned_long:
162 ures = strtoul(pval, &scan_length, 10);
163 if ((isarray && *scan_length != ',' && *scan_length != '}')
164 || (!isarray && !(INFORMIX_MODE(compat) && *scan_length == '.') && *scan_length != '\0' && *scan_length != ' ')) /* Garbage left */
166 ECPGraise(lineno, ECPG_UINT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
175 case ECPGt_unsigned_short:
176 *((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
178 case ECPGt_unsigned_int:
179 *((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
181 case ECPGt_unsigned_long:
182 *((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
190 #ifdef HAVE_LONG_LONG_INT_64
192 case ECPGt_long_long:
195 *((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
196 if ((isarray && *scan_length != ',' && *scan_length != '}')
197 || (!isarray && !(INFORMIX_MODE(compat) && *scan_length == '.') && *scan_length != '\0' && *scan_length != ' ')) /* Garbage left */
199 ECPGraise(lineno, ECPG_INT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
204 *((long long int *) (var + offset * act_tuple)) = (long long) 0;
207 #endif /* HAVE_STRTOLL */
209 case ECPGt_unsigned_long_long:
212 *((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
213 if ((isarray && *scan_length != ',' && *scan_length != '}')
214 || (!isarray && !(INFORMIX_MODE(compat) && *scan_length == '.') && *scan_length != '\0' && *scan_length != ' ')) /* Garbage left */
216 ECPGraise(lineno, ECPG_UINT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
221 *((unsigned long long int *) (var + offset * act_tuple)) = (long long) 0;
224 #endif /* HAVE_STRTOULL */
225 #endif /* HAVE_LONG_LONG_INT_64 */
231 if (isarray && *pval == '"')
232 dres = strtod(pval + 1, &scan_length);
234 dres = strtod(pval, &scan_length);
236 if (isarray && *scan_length == '"')
239 if ((isarray && *scan_length != ',' && *scan_length != '}')
240 || (!isarray && *scan_length != '\0' && *scan_length != ' ')) /* Garbage left */
242 ECPGraise(lineno, ECPG_FLOAT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
252 *((float *) (var + offset * act_tuple)) = dres;
255 *((double *) (var + offset * act_tuple)) = dres;
266 if (pval[0] == 'f' && pval[1] == '\0')
268 if (offset == sizeof(char))
269 *((char *) (var + offset * act_tuple)) = false;
270 else if (offset == sizeof(int))
271 *((int *) (var + offset * act_tuple)) = false;
273 ECPGraise(lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, "different size");
276 else if (pval[0] == 't' && pval[1] == '\0')
278 if (offset == sizeof(char))
279 *((char *) (var + offset * act_tuple)) = true;
280 else if (offset == sizeof(int))
281 *((int *) (var + offset * act_tuple)) = true;
283 ECPGraise(lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, "different size");
286 else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
293 ECPGraise(lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
298 case ECPGt_unsigned_char:
300 if (varcharsize == 0)
301 strncpy((char *) ((long) var + offset * act_tuple), pval, strlen(pval) + 1);
304 strncpy((char *) ((long) var + offset * act_tuple), pval, varcharsize);
306 if (varcharsize < strlen(pval))
312 case ECPGt_unsigned_short:
313 *((short *) (ind + ind_offset * act_tuple)) = strlen(pval);
316 case ECPGt_unsigned_int:
317 *((int *) (ind + ind_offset * act_tuple)) = strlen(pval);
320 case ECPGt_unsigned_long:
321 *((long *) (ind + ind_offset * act_tuple)) = strlen(pval);
323 #ifdef HAVE_LONG_LONG_INT_64
324 case ECPGt_long_long:
325 case ECPGt_unsigned_long_long:
326 *((long long int *) (ind + ind_offset * act_tuple)) = strlen(pval);
328 #endif /* HAVE_LONG_LONG_INT_64 */
332 sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
340 struct ECPGgeneric_varchar *variable =
341 (struct ECPGgeneric_varchar *) ((long) var + offset * act_tuple);
343 variable->len = strlen(pval);
344 if (varcharsize == 0)
345 strncpy(variable->arr, pval, variable->len);
348 strncpy(variable->arr, pval, varcharsize);
350 if (variable->len > varcharsize)
356 case ECPGt_unsigned_short:
357 *((short *) (ind + offset * act_tuple)) = variable->len;
360 case ECPGt_unsigned_int:
361 *((int *) (ind + offset * act_tuple)) = variable->len;
364 case ECPGt_unsigned_long:
365 *((long *) (ind + offset * act_tuple)) = variable->len;
367 #ifdef HAVE_LONG_LONG_INT_64
368 case ECPGt_long_long:
369 case ECPGt_unsigned_long_long:
370 *((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
372 #endif /* HAVE_LONG_LONG_INT_64 */
376 sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
378 variable->len = varcharsize;
388 if (isarray && *pval == '"')
389 nres = PGTYPESnumeric_from_asc(pval + 1, &scan_length);
391 nres = PGTYPESnumeric_from_asc(pval, &scan_length);
393 if (isarray && *scan_length == '"')
396 if ((isarray && *scan_length != ',' && *scan_length != '}')
397 || (!isarray && *scan_length != '\0' && *scan_length != ' ')) /* Garbage left */
399 ECPGraise(lineno, ECPG_NUMERIC_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
404 nres = PGTYPESnumeric_from_asc("0.0", &scan_length);
406 if (type == ECPGt_numeric)
407 PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
409 PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));
415 if (isarray && *pval == '"')
416 ires = PGTYPESinterval_from_asc(pval + 1, &scan_length);
418 ires = PGTYPESinterval_from_asc(pval, &scan_length);
420 if (isarray && *scan_length == '"')
423 if ((isarray && *scan_length != ',' && *scan_length != '}')
424 || (!isarray && *scan_length != '\0' && *scan_length != ' ')) /* Garbage left */
426 ECPGraise(lineno, ECPG_INTERVAL_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
431 ires = PGTYPESinterval_from_asc("0 seconds", NULL);
433 PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
438 if (isarray && *pval == '"')
439 ddres = PGTYPESdate_from_asc(pval + 1, &scan_length);
441 ddres = PGTYPESdate_from_asc(pval, &scan_length);
443 if (isarray && *scan_length == '"')
446 if ((isarray && *scan_length != ',' && *scan_length != '}')
447 || (!isarray && *scan_length != '\0' && *scan_length != ' ')) /* Garbage left */
449 ECPGraise(lineno, ECPG_DATE_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
453 *((date *) (var + offset * act_tuple)) = ddres;
457 case ECPGt_timestamp:
460 if (isarray && *pval == '"')
461 tres = PGTYPEStimestamp_from_asc(pval + 1, &scan_length);
463 tres = PGTYPEStimestamp_from_asc(pval, &scan_length);
465 if (isarray && *scan_length == '"')
468 if ((isarray && *scan_length != ',' && *scan_length != '}')
469 || (!isarray && *scan_length != '\0' && *scan_length != ' ')) /* Garbage left */
471 ECPGraise(lineno, ECPG_TIMESTAMP_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
475 *((timestamp *) (var + offset * act_tuple)) = tres;
480 ECPGraise(lineno, ECPG_UNSUPPORTED, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ECPGtype_name(type));
488 /* set array to next entry */
491 /* set pval to the next entry */
492 for (; string || (*pval != ',' && *pval != '}'); ++pval)
494 string = string ? false : true;
499 } while (isarray && *pval != '}');