LCOV - code coverage report
Current view: top level - src/interfaces/ecpg/ecpglib - data.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 455 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 12 0
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.3.2-1