LCOV - code coverage report
Current view: top level - src/interfaces/ecpg/ecpglib - sqlda.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 182 288 63.2 %
Date: 2019-08-24 15:07:19 Functions: 10 10 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * SQLDA support routines
       3             :  *
       4             :  * The allocated memory area pointed by an sqlda pointer
       5             :  * contains both the metadata and the data, so freeing up
       6             :  * is a simple free(sqlda) as expected by the ESQL/C examples.
       7             :  */
       8             : 
       9             : #define POSTGRES_ECPG_INTERNAL
      10             : #include "postgres_fe.h"
      11             : 
      12             : #include "catalog/pg_type_d.h"
      13             : 
      14             : #include "ecpg-pthread-win32.h"
      15             : #include "decimal.h"
      16             : #include "ecpgtype.h"
      17             : #include "ecpglib.h"
      18             : #include "ecpgerrno.h"
      19             : #include "ecpglib_extern.h"
      20             : #include "sqlca.h"
      21             : #include "sqlda-native.h"
      22             : #include "sqlda-compat.h"
      23             : 
      24             : /*
      25             :  * Compute the next variable's offset with
      26             :  * the current variable's size and alignment.
      27             :  *
      28             :  *
      29             :  * Returns:
      30             :  * - the current variable's offset in *current
      31             :  * - the next variable's offset in *next
      32             :  */
      33             : static void
      34        1152 : ecpg_sqlda_align_add_size(long offset, int alignment, int size, long *current, long *next)
      35             : {
      36        1152 :     if (offset % alignment)
      37         440 :         offset += alignment - (offset % alignment);
      38        1152 :     if (current)
      39        1152 :         *current = offset;
      40        1152 :     offset += size;
      41        1152 :     if (next)
      42         944 :         *next = offset;
      43        1152 : }
      44             : 
      45             : static long
      46          88 : sqlda_compat_empty_size(const PGresult *res)
      47             : {
      48             :     long        offset;
      49             :     int         i;
      50          88 :     int         sqld = PQnfields(res);
      51             : 
      52             :     /* Initial size to store main structure and field structures */
      53          88 :     offset = sizeof(struct sqlda_compat) + sqld * sizeof(struct sqlvar_compat);
      54             : 
      55             :     /* Add space for field names */
      56         456 :     for (i = 0; i < sqld; i++)
      57         368 :         offset += strlen(PQfname(res, i)) + 1;
      58             : 
      59             :     /* Add padding to the first field value */
      60          88 :     ecpg_sqlda_align_add_size(offset, sizeof(int), 0, &offset, NULL);
      61             : 
      62          88 :     return offset;
      63             : }
      64             : 
      65             : static long
      66          80 : sqlda_common_total_size(const PGresult *res, int row, enum COMPAT_MODE compat, long offset)
      67             : {
      68          80 :     int         sqld = PQnfields(res);
      69             :     int         i;
      70             :     long        next_offset;
      71             : 
      72             :     /* Add space for the field values */
      73         528 :     for (i = 0; i < sqld; i++)
      74             :     {
      75         448 :         enum ECPGttype type = sqlda_dynamic_type(PQftype(res, i), compat);
      76             : 
      77         448 :         switch (type)
      78             :         {
      79             :             case ECPGt_short:
      80             :             case ECPGt_unsigned_short:
      81           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
      82           0 :                 break;
      83             :             case ECPGt_int:
      84             :             case ECPGt_unsigned_int:
      85          80 :                 ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
      86          80 :                 break;
      87             :             case ECPGt_long:
      88             :             case ECPGt_unsigned_long:
      89          48 :                 ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
      90          48 :                 break;
      91             :             case ECPGt_long_long:
      92             :             case ECPGt_unsigned_long_long:
      93           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(long long), sizeof(long long), &offset, &next_offset);
      94           0 :                 break;
      95             :             case ECPGt_bool:
      96           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(bool), sizeof(bool), &offset, &next_offset);
      97           0 :                 break;
      98             :             case ECPGt_float:
      99           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(float), sizeof(float), &offset, &next_offset);
     100           0 :                 break;
     101             :             case ECPGt_double:
     102          80 :                 ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
     103          80 :                 break;
     104             :             case ECPGt_decimal:
     105          32 :                 ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
     106          32 :                 break;
     107             :             case ECPGt_numeric:
     108             : 
     109             :                 /*
     110             :                  * We align the numeric struct to allow it to store a pointer,
     111             :                  * while the digits array is aligned to int (which seems like
     112             :                  * overkill, but let's keep compatibility here).
     113             :                  *
     114             :                  * Unfortunately we need to deconstruct the value twice to
     115             :                  * find out the digits array's size and then later fill it.
     116             :                  */
     117          48 :                 ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
     118          48 :                 if (!PQgetisnull(res, row, i))
     119             :                 {
     120          40 :                     char       *val = PQgetvalue(res, row, i);
     121             :                     numeric    *num;
     122             : 
     123          40 :                     num = PGTYPESnumeric_from_asc(val, NULL);
     124          40 :                     if (!num)
     125           0 :                         break;
     126          40 :                     if (num->buf)
     127          24 :                         ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->digits - num->buf + num->ndigits, &offset, &next_offset);
     128          40 :                     PGTYPESnumeric_free(num);
     129             :                 }
     130          48 :                 break;
     131             :             case ECPGt_date:
     132           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
     133           0 :                 break;
     134             :             case ECPGt_timestamp:
     135           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(timestamp), &offset, &next_offset);
     136           0 :                 break;
     137             :             case ECPGt_interval:
     138           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
     139           0 :                 break;
     140             :             case ECPGt_char:
     141             :             case ECPGt_unsigned_char:
     142             :             case ECPGt_string:
     143             :             default:
     144             :                 {
     145         160 :                     long        datalen = strlen(PQgetvalue(res, row, i)) + 1;
     146             : 
     147         160 :                     ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
     148         160 :                     break;
     149             :                 }
     150             :         }
     151         448 :         offset = next_offset;
     152             :     }
     153          80 :     return offset;
     154             : }
     155             : 
     156             : 
     157             : static long
     158          56 : sqlda_compat_total_size(const PGresult *res, int row, enum COMPAT_MODE compat)
     159             : {
     160             :     long        offset;
     161             : 
     162          56 :     offset = sqlda_compat_empty_size(res);
     163             : 
     164          56 :     if (row < 0)
     165          24 :         return offset;
     166             : 
     167          32 :     offset = sqlda_common_total_size(res, row, compat, offset);
     168          32 :     return offset;
     169             : }
     170             : 
     171             : static long
     172         120 : sqlda_native_empty_size(const PGresult *res)
     173             : {
     174             :     long        offset;
     175         120 :     int         sqld = PQnfields(res);
     176             : 
     177             :     /* Initial size to store main structure and field structures */
     178         120 :     offset = sizeof(struct sqlda_struct) + (sqld - 1) * sizeof(struct sqlvar_struct);
     179             : 
     180             :     /* Add padding to the first field value */
     181         120 :     ecpg_sqlda_align_add_size(offset, sizeof(int), 0, &offset, NULL);
     182             : 
     183         120 :     return offset;
     184             : }
     185             : 
     186             : static long
     187          72 : sqlda_native_total_size(const PGresult *res, int row, enum COMPAT_MODE compat)
     188             : {
     189             :     long        offset;
     190             : 
     191          72 :     offset = sqlda_native_empty_size(res);
     192             : 
     193          72 :     if (row < 0)
     194          24 :         return offset;
     195             : 
     196          48 :     offset = sqlda_common_total_size(res, row, compat, offset);
     197          48 :     return offset;
     198             : }
     199             : 
     200             : /*
     201             :  * Build "struct sqlda_compat" (metadata only) from PGresult
     202             :  * leaving enough space for the field values in
     203             :  * the given row number
     204             :  */
     205             : struct sqlda_compat *
     206          56 : ecpg_build_compat_sqlda(int line, PGresult *res, int row, enum COMPAT_MODE compat)
     207             : {
     208             :     struct sqlda_compat *sqlda;
     209             :     struct sqlvar_compat *sqlvar;
     210             :     char       *fname;
     211             :     long        size;
     212             :     int         sqld;
     213             :     int         i;
     214             : 
     215          56 :     size = sqlda_compat_total_size(res, row, compat);
     216          56 :     sqlda = (struct sqlda_compat *) ecpg_alloc(size, line);
     217          56 :     if (!sqlda)
     218           0 :         return NULL;
     219             : 
     220          56 :     memset(sqlda, 0, size);
     221          56 :     sqlvar = (struct sqlvar_compat *) (sqlda + 1);
     222          56 :     sqld = PQnfields(res);
     223          56 :     fname = (char *) (sqlvar + sqld);
     224             : 
     225          56 :     sqlda->sqld = sqld;
     226          56 :     ecpg_log("ecpg_build_compat_sqlda on line %d sqld = %d\n", line, sqld);
     227          56 :     sqlda->desc_occ = size;      /* cheat here, keep the full allocated size */
     228          56 :     sqlda->sqlvar = sqlvar;
     229             : 
     230         264 :     for (i = 0; i < sqlda->sqld; i++)
     231             :     {
     232         208 :         sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
     233         208 :         strcpy(fname, PQfname(res, i));
     234         208 :         sqlda->sqlvar[i].sqlname = fname;
     235         208 :         fname += strlen(sqlda->sqlvar[i].sqlname) + 1;
     236             : 
     237             :         /*
     238             :          * this is reserved for future use, so we leave it empty for the time
     239             :          * being
     240             :          */
     241             :         /* sqlda->sqlvar[i].sqlformat = (char *) (long) PQfformat(res, i); */
     242         208 :         sqlda->sqlvar[i].sqlxid = PQftype(res, i);
     243         208 :         sqlda->sqlvar[i].sqltypelen = PQfsize(res, i);
     244             :     }
     245             : 
     246          56 :     return sqlda;
     247             : }
     248             : 
     249             : /*
     250             :  * Sets values from PGresult.
     251             :  */
     252             : static int16 value_is_null = -1;
     253             : static int16 value_is_not_null = 0;
     254             : 
     255             : void
     256          32 : ecpg_set_compat_sqlda(int lineno, struct sqlda_compat **_sqlda, const PGresult *res, int row, enum COMPAT_MODE compat)
     257             : {
     258          32 :     struct sqlda_compat *sqlda = (*_sqlda);
     259             :     int         i;
     260             :     long        offset,
     261             :                 next_offset;
     262             : 
     263          32 :     if (row < 0)
     264           0 :         return;
     265             : 
     266             :     /* Offset for the first field value */
     267          32 :     offset = sqlda_compat_empty_size(res);
     268             : 
     269             :     /*
     270             :      * Set sqlvar[i]->sqldata pointers and convert values to correct format
     271             :      */
     272         192 :     for (i = 0; i < sqlda->sqld; i++)
     273             :     {
     274             :         int         isnull;
     275             :         int         datalen;
     276         160 :         bool        set_data = true;
     277             : 
     278         160 :         switch (sqlda->sqlvar[i].sqltype)
     279             :         {
     280             :             case ECPGt_short:
     281             :             case ECPGt_unsigned_short:
     282           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
     283           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     284           0 :                 sqlda->sqlvar[i].sqllen = sizeof(short);
     285           0 :                 break;
     286             :             case ECPGt_int:
     287             :             case ECPGt_unsigned_int:
     288          32 :                 ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
     289          32 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     290          32 :                 sqlda->sqlvar[i].sqllen = sizeof(int);
     291          32 :                 break;
     292             :             case ECPGt_long:
     293             :             case ECPGt_unsigned_long:
     294           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
     295           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     296           0 :                 sqlda->sqlvar[i].sqllen = sizeof(long);
     297           0 :                 break;
     298             :             case ECPGt_long_long:
     299             :             case ECPGt_unsigned_long_long:
     300           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(long long), sizeof(long long), &offset, &next_offset);
     301           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     302           0 :                 sqlda->sqlvar[i].sqllen = sizeof(long long);
     303           0 :                 break;
     304             :             case ECPGt_bool:
     305           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(bool), sizeof(bool), &offset, &next_offset);
     306           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     307           0 :                 sqlda->sqlvar[i].sqllen = sizeof(bool);
     308           0 :                 break;
     309             :             case ECPGt_float:
     310           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(float), sizeof(float), &offset, &next_offset);
     311           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     312           0 :                 sqlda->sqlvar[i].sqllen = sizeof(float);
     313           0 :                 break;
     314             :             case ECPGt_double:
     315          32 :                 ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
     316          32 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     317          32 :                 sqlda->sqlvar[i].sqllen = sizeof(double);
     318          32 :                 break;
     319             :             case ECPGt_decimal:
     320          32 :                 ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
     321          32 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     322          32 :                 sqlda->sqlvar[i].sqllen = sizeof(decimal);
     323          32 :                 break;
     324             :             case ECPGt_numeric:
     325             :                 {
     326             :                     numeric    *num;
     327             :                     char       *val;
     328             : 
     329           0 :                     set_data = false;
     330             : 
     331           0 :                     ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
     332           0 :                     sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     333           0 :                     sqlda->sqlvar[i].sqllen = sizeof(numeric);
     334             : 
     335           0 :                     if (PQgetisnull(res, row, i))
     336             :                     {
     337           0 :                         ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
     338           0 :                         break;
     339             :                     }
     340             : 
     341           0 :                     val = PQgetvalue(res, row, i);
     342           0 :                     num = PGTYPESnumeric_from_asc(val, NULL);
     343           0 :                     if (!num)
     344             :                     {
     345           0 :                         ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
     346           0 :                         break;
     347             :                     }
     348             : 
     349           0 :                     memcpy(sqlda->sqlvar[i].sqldata, num, sizeof(numeric));
     350             : 
     351           0 :                     if (num->buf)
     352             :                     {
     353           0 :                         ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->digits - num->buf + num->ndigits, &offset, &next_offset);
     354           0 :                         memcpy((char *) sqlda + offset, num->buf, num->digits - num->buf + num->ndigits);
     355             : 
     356           0 :                         ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + offset;
     357           0 :                         ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda + offset + (num->digits - num->buf);
     358             :                     }
     359             : 
     360           0 :                     PGTYPESnumeric_free(num);
     361             : 
     362           0 :                     break;
     363             :                 }
     364             :             case ECPGt_date:
     365           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
     366           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     367           0 :                 sqlda->sqlvar[i].sqllen = sizeof(date);
     368           0 :                 break;
     369             :             case ECPGt_timestamp:
     370           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(timestamp), &offset, &next_offset);
     371           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     372           0 :                 sqlda->sqlvar[i].sqllen = sizeof(timestamp);
     373           0 :                 break;
     374             :             case ECPGt_interval:
     375           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
     376           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     377           0 :                 sqlda->sqlvar[i].sqllen = sizeof(interval);
     378           0 :                 break;
     379             :             case ECPGt_char:
     380             :             case ECPGt_unsigned_char:
     381             :             case ECPGt_string:
     382             :             default:
     383          64 :                 datalen = strlen(PQgetvalue(res, row, i)) + 1;
     384          64 :                 ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
     385          64 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     386          64 :                 sqlda->sqlvar[i].sqllen = datalen;
     387          64 :                 if (datalen > 32768)
     388           0 :                     sqlda->sqlvar[i].sqlilongdata = sqlda->sqlvar[i].sqldata;
     389          64 :                 break;
     390             :         }
     391             : 
     392         160 :         isnull = PQgetisnull(res, row, i);
     393         160 :         ecpg_log("ecpg_set_compat_sqlda on line %d row %d col %d %s\n", lineno, row, i, isnull ? "IS NULL" : "IS NOT NULL");
     394         160 :         sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
     395         160 :         sqlda->sqlvar[i].sqlitype = ECPGt_short;
     396         160 :         sqlda->sqlvar[i].sqlilen = sizeof(short);
     397         160 :         if (!isnull)
     398             :         {
     399         128 :             if (set_data)
     400         256 :                 ecpg_get_data(res, row, i, lineno,
     401         128 :                               sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
     402         128 :                               sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
     403             :                               ECPG_ARRAY_NONE, compat, false);
     404             :         }
     405             :         else
     406          32 :             ECPGset_noind_null(sqlda->sqlvar[i].sqltype, sqlda->sqlvar[i].sqldata);
     407             : 
     408         160 :         offset = next_offset;
     409             :     }
     410             : }
     411             : 
     412             : struct sqlda_struct *
     413          72 : ecpg_build_native_sqlda(int line, PGresult *res, int row, enum COMPAT_MODE compat)
     414             : {
     415             :     struct sqlda_struct *sqlda;
     416             :     long        size;
     417             :     int         i;
     418             : 
     419          72 :     size = sqlda_native_total_size(res, row, compat);
     420          72 :     sqlda = (struct sqlda_struct *) ecpg_alloc(size, line);
     421          72 :     if (!sqlda)
     422           0 :         return NULL;
     423             : 
     424          72 :     memset(sqlda, 0, size);
     425             : 
     426          72 :     sprintf(sqlda->sqldaid, "SQLDA  ");
     427          72 :     sqlda->sqld = sqlda->sqln = PQnfields(res);
     428          72 :     ecpg_log("ecpg_build_native_sqlda on line %d sqld = %d\n", line, sqlda->sqld);
     429          72 :     sqlda->sqldabc = sizeof(struct sqlda_struct) + (sqlda->sqld - 1) * sizeof(struct sqlvar_struct);
     430             : 
     431         408 :     for (i = 0; i < sqlda->sqld; i++)
     432             :     {
     433             :         char       *fname;
     434             : 
     435         336 :         sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
     436         336 :         fname = PQfname(res, i);
     437         336 :         sqlda->sqlvar[i].sqlname.length = strlen(fname);
     438         336 :         strcpy(sqlda->sqlvar[i].sqlname.data, fname);
     439             :     }
     440             : 
     441          72 :     return sqlda;
     442             : }
     443             : 
     444             : void
     445          48 : ecpg_set_native_sqlda(int lineno, struct sqlda_struct **_sqlda, const PGresult *res, int row, enum COMPAT_MODE compat)
     446             : {
     447          48 :     struct sqlda_struct *sqlda = (*_sqlda);
     448             :     int         i;
     449             :     long        offset,
     450             :                 next_offset;
     451             : 
     452          48 :     if (row < 0)
     453           0 :         return;
     454             : 
     455             :     /* Offset for the first field value */
     456          48 :     offset = sqlda_native_empty_size(res);
     457             : 
     458             :     /*
     459             :      * Set sqlvar[i]->sqldata pointers and convert values to correct format
     460             :      */
     461         336 :     for (i = 0; i < sqlda->sqld; i++)
     462             :     {
     463             :         int         isnull;
     464             :         int         datalen;
     465         288 :         bool        set_data = true;
     466             : 
     467         288 :         switch (sqlda->sqlvar[i].sqltype)
     468             :         {
     469             :             case ECPGt_short:
     470             :             case ECPGt_unsigned_short:
     471           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
     472           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     473           0 :                 sqlda->sqlvar[i].sqllen = sizeof(short);
     474           0 :                 break;
     475             :             case ECPGt_int:
     476             :             case ECPGt_unsigned_int:
     477          48 :                 ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
     478          48 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     479          48 :                 sqlda->sqlvar[i].sqllen = sizeof(int);
     480          48 :                 break;
     481             :             case ECPGt_long:
     482             :             case ECPGt_unsigned_long:
     483          48 :                 ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
     484          48 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     485          48 :                 sqlda->sqlvar[i].sqllen = sizeof(long);
     486          48 :                 break;
     487             :             case ECPGt_long_long:
     488             :             case ECPGt_unsigned_long_long:
     489           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(long long), sizeof(long long), &offset, &next_offset);
     490           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     491           0 :                 sqlda->sqlvar[i].sqllen = sizeof(long long);
     492           0 :                 break;
     493             :             case ECPGt_bool:
     494           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(bool), sizeof(bool), &offset, &next_offset);
     495           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     496           0 :                 sqlda->sqlvar[i].sqllen = sizeof(bool);
     497           0 :                 break;
     498             :             case ECPGt_float:
     499           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(float), sizeof(float), &offset, &next_offset);
     500           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     501           0 :                 sqlda->sqlvar[i].sqllen = sizeof(float);
     502           0 :                 break;
     503             :             case ECPGt_double:
     504          48 :                 ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
     505          48 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     506          48 :                 sqlda->sqlvar[i].sqllen = sizeof(double);
     507          48 :                 break;
     508             :             case ECPGt_decimal:
     509           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
     510           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     511           0 :                 sqlda->sqlvar[i].sqllen = sizeof(decimal);
     512           0 :                 break;
     513             :             case ECPGt_numeric:
     514             :                 {
     515             :                     numeric    *num;
     516             :                     char       *val;
     517             : 
     518          48 :                     set_data = false;
     519             : 
     520          48 :                     ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
     521          48 :                     sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     522          48 :                     sqlda->sqlvar[i].sqllen = sizeof(numeric);
     523             : 
     524          48 :                     if (PQgetisnull(res, row, i))
     525             :                     {
     526           8 :                         ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
     527           8 :                         break;
     528             :                     }
     529             : 
     530          40 :                     val = PQgetvalue(res, row, i);
     531          40 :                     num = PGTYPESnumeric_from_asc(val, NULL);
     532          40 :                     if (!num)
     533             :                     {
     534           0 :                         ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
     535           0 :                         break;
     536             :                     }
     537             : 
     538          40 :                     memcpy(sqlda->sqlvar[i].sqldata, num, sizeof(numeric));
     539             : 
     540          40 :                     if (num->buf)
     541             :                     {
     542          24 :                         ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->digits - num->buf + num->ndigits, &offset, &next_offset);
     543          24 :                         memcpy((char *) sqlda + offset, num->buf, num->digits - num->buf + num->ndigits);
     544             : 
     545          24 :                         ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + offset;
     546          24 :                         ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda + offset + (num->digits - num->buf);
     547             :                     }
     548             : 
     549          40 :                     PGTYPESnumeric_free(num);
     550             : 
     551          40 :                     break;
     552             :                 }
     553             :             case ECPGt_date:
     554           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
     555           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     556           0 :                 sqlda->sqlvar[i].sqllen = sizeof(date);
     557           0 :                 break;
     558             :             case ECPGt_timestamp:
     559           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(timestamp), &offset, &next_offset);
     560           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     561           0 :                 sqlda->sqlvar[i].sqllen = sizeof(timestamp);
     562           0 :                 break;
     563             :             case ECPGt_interval:
     564           0 :                 ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
     565           0 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     566           0 :                 sqlda->sqlvar[i].sqllen = sizeof(interval);
     567           0 :                 break;
     568             :             case ECPGt_char:
     569             :             case ECPGt_unsigned_char:
     570             :             case ECPGt_string:
     571             :             default:
     572          96 :                 datalen = strlen(PQgetvalue(res, row, i)) + 1;
     573          96 :                 ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
     574          96 :                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     575          96 :                 sqlda->sqlvar[i].sqllen = datalen;
     576          96 :                 break;
     577             :         }
     578             : 
     579         288 :         isnull = PQgetisnull(res, row, i);
     580         288 :         ecpg_log("ecpg_set_native_sqlda on line %d row %d col %d %s\n", lineno, row, i, isnull ? "IS NULL" : "IS NOT NULL");
     581         288 :         sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
     582         288 :         if (!isnull)
     583             :         {
     584         248 :             if (set_data)
     585         416 :                 ecpg_get_data(res, row, i, lineno,
     586         208 :                               sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
     587             :                               sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
     588             :                               ECPG_ARRAY_NONE, compat, false);
     589             :         }
     590             : 
     591         288 :         offset = next_offset;
     592             :     }
     593             : }

Generated by: LCOV version 1.13