LCOV - differential code coverage report
Current view: top level - src/interfaces/ecpg/ecpglib - data.c (source / functions) Coverage Total Hit LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB
Current: Differential Code Coverage HEAD vs 15 Lines: 60.0 % 447 268 15 62 102 16 67 185 58 68 3
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 12 12 1 11
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a