Header And Logo

PostgreSQL
| The world's most advanced open source database.

sqlda.c

Go to the documentation of this file.
00001 /*
00002  * SQLDA support routines
00003  *
00004  * The allocated memory area pointed by an sqlda pointer
00005  * contains both the metadata and the data, so freeing up
00006  * is a simple free(sqlda) as expected by the ESQL/C examples.
00007  */
00008 
00009 #define POSTGRES_ECPG_INTERNAL
00010 #include "postgres_fe.h"
00011 #include "pg_type.h"
00012 
00013 #include "ecpg-pthread-win32.h"
00014 #include "decimal.h"
00015 #include "ecpgtype.h"
00016 #include "ecpglib.h"
00017 #include "ecpgerrno.h"
00018 #include "extern.h"
00019 #include "sqlca.h"
00020 #include "sqlda-native.h"
00021 #include "sqlda-compat.h"
00022 
00023 /*
00024  * Compute the next variable's offset with
00025  * the current variable's size and alignment.
00026  *
00027  *
00028  * Returns:
00029  * - the current variable's offset in *current
00030  * - the next variable's offset in *next
00031  */
00032 static void
00033 ecpg_sqlda_align_add_size(long offset, int alignment, int size, long *current, long *next)
00034 {
00035     if (offset % alignment)
00036         offset += alignment - (offset % alignment);
00037     if (current)
00038         *current = offset;
00039     offset += size;
00040     if (next)
00041         *next = offset;
00042 }
00043 
00044 static long
00045 sqlda_compat_empty_size(const PGresult *res)
00046 {
00047     long        offset;
00048     int         i;
00049     int         sqld = PQnfields(res);
00050 
00051     /* Initial size to store main structure and field structures */
00052     offset = sizeof(struct sqlda_compat) + sqld * sizeof(struct sqlvar_compat);
00053 
00054     /* Add space for field names */
00055     for (i = 0; i < sqld; i++)
00056         offset += strlen(PQfname(res, i)) + 1;
00057 
00058     /* Add padding to the first field value */
00059     ecpg_sqlda_align_add_size(offset, sizeof(int), 0, &offset, NULL);
00060 
00061     return offset;
00062 }
00063 
00064 static long
00065 sqlda_common_total_size(const PGresult *res, int row, enum COMPAT_MODE compat, long offset)
00066 {
00067     int         sqld = PQnfields(res);
00068     int         i;
00069     long        next_offset;
00070 
00071     /* Add space for the field values */
00072     for (i = 0; i < sqld; i++)
00073     {
00074         enum ECPGttype type = sqlda_dynamic_type(PQftype(res, i), compat);
00075 
00076         switch (type)
00077         {
00078             case ECPGt_short:
00079             case ECPGt_unsigned_short:
00080                 ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
00081                 break;
00082             case ECPGt_int:
00083             case ECPGt_unsigned_int:
00084                 ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
00085                 break;
00086             case ECPGt_long:
00087             case ECPGt_unsigned_long:
00088                 ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
00089                 break;
00090             case ECPGt_long_long:
00091             case ECPGt_unsigned_long_long:
00092                 ecpg_sqlda_align_add_size(offset, sizeof(long long), sizeof(long long), &offset, &next_offset);
00093                 break;
00094             case ECPGt_bool:
00095                 ecpg_sqlda_align_add_size(offset, sizeof(bool), sizeof(bool), &offset, &next_offset);
00096                 break;
00097             case ECPGt_float:
00098                 ecpg_sqlda_align_add_size(offset, sizeof(float), sizeof(float), &offset, &next_offset);
00099                 break;
00100             case ECPGt_double:
00101                 ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
00102                 break;
00103             case ECPGt_decimal:
00104                 ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
00105                 break;
00106             case ECPGt_numeric:
00107 
00108                 /*
00109                  * Let's align both the numeric struct and the digits array to
00110                  * int Unfortunately we need to do double work here to compute
00111                  * the size of the space needed for the numeric structure.
00112                  */
00113                 ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
00114                 if (!PQgetisnull(res, row, i))
00115                 {
00116                     char       *val = PQgetvalue(res, row, i);
00117                     numeric    *num;
00118 
00119                     num = PGTYPESnumeric_from_asc(val, NULL);
00120                     if (!num)
00121                         break;
00122                     if (num->ndigits)
00123                         ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->ndigits + 1, &offset, &next_offset);
00124                     PGTYPESnumeric_free(num);
00125                 }
00126                 break;
00127             case ECPGt_date:
00128                 ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
00129                 break;
00130             case ECPGt_timestamp:
00131                 ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(timestamp), &offset, &next_offset);
00132                 break;
00133             case ECPGt_interval:
00134                 ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
00135                 break;
00136             case ECPGt_char:
00137             case ECPGt_unsigned_char:
00138             case ECPGt_string:
00139             default:
00140                 {
00141                     long        datalen = strlen(PQgetvalue(res, row, i)) + 1;
00142 
00143                     ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
00144                     break;
00145                 }
00146         }
00147         offset = next_offset;
00148     }
00149     return offset;
00150 }
00151 
00152 
00153 static long
00154 sqlda_compat_total_size(const PGresult *res, int row, enum COMPAT_MODE compat)
00155 {
00156     long        offset;
00157 
00158     offset = sqlda_compat_empty_size(res);
00159 
00160     if (row < 0)
00161         return offset;
00162 
00163     offset = sqlda_common_total_size(res, row, compat, offset);
00164     return offset;
00165 }
00166 
00167 static long
00168 sqlda_native_empty_size(const PGresult *res)
00169 {
00170     long        offset;
00171     int         sqld = PQnfields(res);
00172 
00173     /* Initial size to store main structure and field structures */
00174     offset = sizeof(struct sqlda_struct) + (sqld - 1) * sizeof(struct sqlvar_struct);
00175 
00176     /* Add padding to the first field value */
00177     ecpg_sqlda_align_add_size(offset, sizeof(int), 0, &offset, NULL);
00178 
00179     return offset;
00180 }
00181 
00182 static long
00183 sqlda_native_total_size(const PGresult *res, int row, enum COMPAT_MODE compat)
00184 {
00185     long        offset;
00186 
00187     offset = sqlda_native_empty_size(res);
00188 
00189     if (row < 0)
00190         return offset;
00191 
00192     offset = sqlda_common_total_size(res, row, compat, offset);
00193     return offset;
00194 }
00195 
00196 /*
00197  * Build "struct sqlda_compat" (metadata only) from PGresult
00198  * leaving enough space for the field values in
00199  * the given row number
00200  */
00201 struct sqlda_compat *
00202 ecpg_build_compat_sqlda(int line, PGresult *res, int row, enum COMPAT_MODE compat)
00203 {
00204     struct sqlda_compat *sqlda;
00205     struct sqlvar_compat *sqlvar;
00206     char       *fname;
00207     long        size;
00208     int         sqld;
00209     int         i;
00210 
00211     size = sqlda_compat_total_size(res, row, compat);
00212     sqlda = (struct sqlda_compat *) ecpg_alloc(size, line);
00213     if (!sqlda)
00214         return NULL;
00215 
00216     memset(sqlda, 0, size);
00217     sqlvar = (struct sqlvar_compat *) (sqlda + 1);
00218     sqld = PQnfields(res);
00219     fname = (char *) (sqlvar + sqld);
00220 
00221     sqlda->sqld = sqld;
00222     ecpg_log("ecpg_build_compat_sqlda on line %d sqld = %d\n", line, sqld);
00223     sqlda->desc_occ = size;     /* cheat here, keep the full allocated size */
00224     sqlda->sqlvar = sqlvar;
00225 
00226     for (i = 0; i < sqlda->sqld; i++)
00227     {
00228         sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
00229         strcpy(fname, PQfname(res, i));
00230         sqlda->sqlvar[i].sqlname = fname;
00231         fname += strlen(sqlda->sqlvar[i].sqlname) + 1;
00232 
00233         /*
00234          * this is reserved for future use, so we leave it empty for the time
00235          * being
00236          */
00237         /* sqlda->sqlvar[i].sqlformat = (char *) (long) PQfformat(res, i); */
00238         sqlda->sqlvar[i].sqlxid = PQftype(res, i);
00239         sqlda->sqlvar[i].sqltypelen = PQfsize(res, i);
00240     }
00241 
00242     return sqlda;
00243 }
00244 
00245 /*
00246  * Sets values from PGresult.
00247  */
00248 static int16 value_is_null = -1;
00249 static int16 value_is_not_null = 0;
00250 
00251 void
00252 ecpg_set_compat_sqlda(int lineno, struct sqlda_compat ** _sqlda, const PGresult *res, int row, enum COMPAT_MODE compat)
00253 {
00254     struct sqlda_compat *sqlda = (*_sqlda);
00255     int         i;
00256     long        offset,
00257                 next_offset;
00258 
00259     if (row < 0)
00260         return;
00261 
00262     /* Offset for the first field value */
00263     offset = sqlda_compat_empty_size(res);
00264 
00265     /*
00266      * Set sqlvar[i]->sqldata pointers and convert values to correct format
00267      */
00268     for (i = 0; i < sqlda->sqld; i++)
00269     {
00270         int         isnull;
00271         int         datalen;
00272         bool        set_data = true;
00273 
00274         switch (sqlda->sqlvar[i].sqltype)
00275         {
00276             case ECPGt_short:
00277             case ECPGt_unsigned_short:
00278                 ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
00279                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00280                 sqlda->sqlvar[i].sqllen = sizeof(short);
00281                 break;
00282             case ECPGt_int:
00283             case ECPGt_unsigned_int:
00284                 ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
00285                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00286                 sqlda->sqlvar[i].sqllen = sizeof(int);
00287                 break;
00288             case ECPGt_long:
00289             case ECPGt_unsigned_long:
00290                 ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
00291                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00292                 sqlda->sqlvar[i].sqllen = sizeof(long);
00293                 break;
00294             case ECPGt_long_long:
00295             case ECPGt_unsigned_long_long:
00296                 ecpg_sqlda_align_add_size(offset, sizeof(long long), sizeof(long long), &offset, &next_offset);
00297                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00298                 sqlda->sqlvar[i].sqllen = sizeof(long long);
00299                 break;
00300             case ECPGt_bool:
00301                 ecpg_sqlda_align_add_size(offset, sizeof(bool), sizeof(bool), &offset, &next_offset);
00302                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00303                 sqlda->sqlvar[i].sqllen = sizeof(bool);
00304                 break;
00305             case ECPGt_float:
00306                 ecpg_sqlda_align_add_size(offset, sizeof(float), sizeof(float), &offset, &next_offset);
00307                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00308                 sqlda->sqlvar[i].sqllen = sizeof(float);
00309                 break;
00310             case ECPGt_double:
00311                 ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
00312                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00313                 sqlda->sqlvar[i].sqllen = sizeof(double);
00314                 break;
00315             case ECPGt_decimal:
00316                 ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
00317                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00318                 sqlda->sqlvar[i].sqllen = sizeof(decimal);
00319                 break;
00320             case ECPGt_numeric:
00321                 {
00322                     numeric    *num;
00323                     char       *val;
00324 
00325                     set_data = false;
00326 
00327                     ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
00328                     sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00329                     sqlda->sqlvar[i].sqllen = sizeof(numeric);
00330 
00331                     if (PQgetisnull(res, row, i))
00332                     {
00333                         ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
00334                         break;
00335                     }
00336 
00337                     val = PQgetvalue(res, row, i);
00338                     num = PGTYPESnumeric_from_asc(val, NULL);
00339                     if (!num)
00340                     {
00341                         ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
00342                         break;
00343                     }
00344 
00345                     memcpy(sqlda->sqlvar[i].sqldata, num, sizeof(numeric));
00346 
00347                     if (num->ndigits)
00348                     {
00349                         ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->ndigits + 1, &offset, &next_offset);
00350                         memcpy((char *) sqlda + offset, num->buf, num->ndigits + 1);
00351 
00352                         ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + offset;
00353                         ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda + offset + (num->digits - num->buf);
00354                     }
00355 
00356                     PGTYPESnumeric_free(num);
00357 
00358                     break;
00359                 }
00360             case ECPGt_date:
00361                 ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
00362                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00363                 sqlda->sqlvar[i].sqllen = sizeof(date);
00364                 break;
00365             case ECPGt_timestamp:
00366                 ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(timestamp), &offset, &next_offset);
00367                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00368                 sqlda->sqlvar[i].sqllen = sizeof(timestamp);
00369                 break;
00370             case ECPGt_interval:
00371                 ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
00372                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00373                 sqlda->sqlvar[i].sqllen = sizeof(interval);
00374                 break;
00375             case ECPGt_char:
00376             case ECPGt_unsigned_char:
00377             case ECPGt_string:
00378             default:
00379                 datalen = strlen(PQgetvalue(res, row, i)) + 1;
00380                 ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
00381                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00382                 sqlda->sqlvar[i].sqllen = datalen;
00383                 if (datalen > 32768)
00384                     sqlda->sqlvar[i].sqlilongdata = sqlda->sqlvar[i].sqldata;
00385                 break;
00386         }
00387 
00388         isnull = PQgetisnull(res, row, i);
00389         ecpg_log("ecpg_set_compat_sqlda on line %d row %d col %d %s\n", lineno, row, i, isnull ? "IS NULL" : "IS NOT NULL");
00390         sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
00391         sqlda->sqlvar[i].sqlitype = ECPGt_short;
00392         sqlda->sqlvar[i].sqlilen = sizeof(short);
00393         if (!isnull)
00394         {
00395             if (set_data)
00396                 ecpg_get_data(res, row, i, lineno,
00397                               sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
00398                               sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
00399                               ECPG_ARRAY_NONE, compat, false);
00400         }
00401         else
00402             ECPGset_noind_null(sqlda->sqlvar[i].sqltype, sqlda->sqlvar[i].sqldata);
00403 
00404         offset = next_offset;
00405     }
00406 }
00407 
00408 struct sqlda_struct *
00409 ecpg_build_native_sqlda(int line, PGresult *res, int row, enum COMPAT_MODE compat)
00410 {
00411     struct sqlda_struct *sqlda;
00412     long        size;
00413     int         i;
00414 
00415     size = sqlda_native_total_size(res, row, compat);
00416     sqlda = (struct sqlda_struct *) ecpg_alloc(size, line);
00417     if (!sqlda)
00418         return NULL;
00419 
00420     memset(sqlda, 0, size);
00421 
00422     sprintf(sqlda->sqldaid, "SQLDA  ");
00423     sqlda->sqld = sqlda->sqln = PQnfields(res);
00424     ecpg_log("ecpg_build_native_sqlda on line %d sqld = %d\n", line, sqlda->sqld);
00425     sqlda->sqldabc = sizeof(struct sqlda_struct) + (sqlda->sqld - 1) * sizeof(struct sqlvar_struct);
00426 
00427     for (i = 0; i < sqlda->sqld; i++)
00428     {
00429         char       *fname;
00430 
00431         sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
00432         fname = PQfname(res, i);
00433         sqlda->sqlvar[i].sqlname.length = strlen(fname);
00434         strcpy(sqlda->sqlvar[i].sqlname.data, fname);
00435     }
00436 
00437     return sqlda;
00438 }
00439 
00440 void
00441 ecpg_set_native_sqlda(int lineno, struct sqlda_struct ** _sqlda, const PGresult *res, int row, enum COMPAT_MODE compat)
00442 {
00443     struct sqlda_struct *sqlda = (*_sqlda);
00444     int         i;
00445     long        offset,
00446                 next_offset;
00447 
00448     if (row < 0)
00449         return;
00450 
00451     /* Offset for the first field value */
00452     offset = sqlda_native_empty_size(res);
00453 
00454     /*
00455      * Set sqlvar[i]->sqldata pointers and convert values to correct format
00456      */
00457     for (i = 0; i < sqlda->sqld; i++)
00458     {
00459         int         isnull;
00460         int         datalen;
00461         bool        set_data = true;
00462 
00463         switch (sqlda->sqlvar[i].sqltype)
00464         {
00465             case ECPGt_short:
00466             case ECPGt_unsigned_short:
00467                 ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
00468                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00469                 sqlda->sqlvar[i].sqllen = sizeof(short);
00470                 break;
00471             case ECPGt_int:
00472             case ECPGt_unsigned_int:
00473                 ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
00474                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00475                 sqlda->sqlvar[i].sqllen = sizeof(int);
00476                 break;
00477             case ECPGt_long:
00478             case ECPGt_unsigned_long:
00479                 ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
00480                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00481                 sqlda->sqlvar[i].sqllen = sizeof(long);
00482                 break;
00483             case ECPGt_long_long:
00484             case ECPGt_unsigned_long_long:
00485                 ecpg_sqlda_align_add_size(offset, sizeof(long long), sizeof(long long), &offset, &next_offset);
00486                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00487                 sqlda->sqlvar[i].sqllen = sizeof(long long);
00488                 break;
00489             case ECPGt_bool:
00490                 ecpg_sqlda_align_add_size(offset, sizeof(bool), sizeof(bool), &offset, &next_offset);
00491                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00492                 sqlda->sqlvar[i].sqllen = sizeof(bool);
00493                 break;
00494             case ECPGt_float:
00495                 ecpg_sqlda_align_add_size(offset, sizeof(float), sizeof(float), &offset, &next_offset);
00496                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00497                 sqlda->sqlvar[i].sqllen = sizeof(float);
00498                 break;
00499             case ECPGt_double:
00500                 ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
00501                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00502                 sqlda->sqlvar[i].sqllen = sizeof(double);
00503                 break;
00504             case ECPGt_decimal:
00505                 ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
00506                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00507                 sqlda->sqlvar[i].sqllen = sizeof(decimal);
00508                 break;
00509             case ECPGt_numeric:
00510                 {
00511                     numeric    *num;
00512                     char       *val;
00513 
00514                     set_data = false;
00515 
00516                     ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
00517                     sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00518                     sqlda->sqlvar[i].sqllen = sizeof(numeric);
00519 
00520                     if (PQgetisnull(res, row, i))
00521                     {
00522                         ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
00523                         break;
00524                     }
00525 
00526                     val = PQgetvalue(res, row, i);
00527                     num = PGTYPESnumeric_from_asc(val, NULL);
00528                     if (!num)
00529                     {
00530                         ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
00531                         break;
00532                     }
00533 
00534                     memcpy(sqlda->sqlvar[i].sqldata, num, sizeof(numeric));
00535 
00536                     if (num->ndigits)
00537                     {
00538                         ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->ndigits + 1, &offset, &next_offset);
00539                         memcpy((char *) sqlda + offset, num->buf, num->ndigits + 1);
00540 
00541                         ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + offset;
00542                         ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda + offset + (num->digits - num->buf);
00543                     }
00544 
00545                     PGTYPESnumeric_free(num);
00546 
00547                     break;
00548                 }
00549             case ECPGt_date:
00550                 ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
00551                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00552                 sqlda->sqlvar[i].sqllen = sizeof(date);
00553                 break;
00554             case ECPGt_timestamp:
00555                 ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(timestamp), &offset, &next_offset);
00556                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00557                 sqlda->sqlvar[i].sqllen = sizeof(timestamp);
00558                 break;
00559             case ECPGt_interval:
00560                 ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
00561                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00562                 sqlda->sqlvar[i].sqllen = sizeof(interval);
00563                 break;
00564             case ECPGt_char:
00565             case ECPGt_unsigned_char:
00566             case ECPGt_string:
00567             default:
00568                 datalen = strlen(PQgetvalue(res, row, i)) + 1;
00569                 ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
00570                 sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
00571                 sqlda->sqlvar[i].sqllen = datalen;
00572                 break;
00573         }
00574 
00575         isnull = PQgetisnull(res, row, i);
00576         ecpg_log("ecpg_set_native_sqlda on line %d row %d col %d %s\n", lineno, row, i, isnull ? "IS NULL" : "IS NOT NULL");
00577         sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
00578         if (!isnull)
00579         {
00580             if (set_data)
00581                 ecpg_get_data(res, row, i, lineno,
00582                               sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
00583                               sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
00584                               ECPG_ARRAY_NONE, compat, false);
00585         }
00586 
00587         offset = next_offset;
00588     }
00589 }