Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  sqlda.c

  Sprache: C
 

/*
 * SQLDA support routines
 *
 * The allocated memory area pointed by an sqlda pointer
 * contains both the metadata and the data, so freeing up
 * is a simple free(sqlda) as expected by the ESQL/C examples.
 */


#define POSTGRES_ECPG_INTERNAL
#include "postgres_fe.h"

#include "catalog/pg_type_d.h"
#include "decimal.h"
#include "ecpg-pthread-win32.h"
#include "ecpgerrno.h"
#include "ecpglib.h"
#include "ecpglib_extern.h"
#include "ecpgtype.h"
#include "sqlca.h"
#include "sqlda-compat.h"
#include "sqlda-native.h"

/*
 * Compute the next variable's offset with
 * the current variable's size and alignment.
 *
 *
 * Returns:
 * - the current variable's offset in *current
 * - the next variable's offset in *next
 */

static void
ecpg_sqlda_align_add_size(long offset, int alignment, int size, long *current, long *next)
{
 if (offset % alignment)
  offset += alignment - (offset % alignment);
 if (current)
  *current = offset;
 offset += size;
 if (next)
  *next = offset;
}

static long
sqlda_compat_empty_size(const PGresult *res)
{
 long  offset;
 int   i;
 int   sqld = PQnfields(res);

 /* Initial size to store main structure and field structures */
 offset = sizeof(struct sqlda_compat) + sqld * sizeof(struct sqlvar_compat);

 /* Add space for field names */
 for (i = 0; i < sqld; i++)
  offset += strlen(PQfname(res, i)) + 1;

 /* Add padding to the first field value */
 ecpg_sqlda_align_add_size(offset, sizeof(int), 0, &offset, NULL);

 return offset;
}

static long
sqlda_common_total_size(const PGresult *res, int row, enum COMPAT_MODE compat, long offset)
{
 int   sqld = PQnfields(res);
 int   i;
 long  next_offset;

 /* Add space for the field values */
 for (i = 0; i < sqld; i++)
 {
  enum ECPGttype type = sqlda_dynamic_type(PQftype(res, i), compat);

  switch (type)
  {
   case ECPGt_short:
   case ECPGt_unsigned_short:
    ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
    break;
   case ECPGt_int:
   case ECPGt_unsigned_int:
    ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
    break;
   case ECPGt_long:
   case ECPGt_unsigned_long:
    ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
    break;
   case ECPGt_long_long:
   case ECPGt_unsigned_long_long:
    ecpg_sqlda_align_add_size(offset, sizeof(long long), sizeof(long long), &offset, &next_offset);
    break;
   case ECPGt_bool:
    ecpg_sqlda_align_add_size(offset, sizeof(bool), sizeof(bool), &offset, &next_offset);
    break;
   case ECPGt_float:
    ecpg_sqlda_align_add_size(offset, sizeof(float), sizeof(float), &offset, &next_offset);
    break;
   case ECPGt_double:
    ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
    break;
   case ECPGt_decimal:
    ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
    break;
   case ECPGt_numeric:

    /*
     * We align the numeric struct to allow it to store a pointer,
     * while the digits array is aligned to int (which seems like
     * overkill, but let's keep compatibility here).
     *
     * Unfortunately we need to deconstruct the value twice to
     * find out the digits array's size and then later fill it.
 */

    ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
    if (!PQgetisnull(res, row, i))
    {
     char    *val = PQgetvalue(res, row, i);
     numeric    *num;

     num = PGTYPESnumeric_from_asc(val, NULL);
     if (!num)
      break;
     if (num->buf)
      ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->digits - num->buf + num->ndigits, &offset, &next_offset);
     PGTYPESnumeric_free(num);
    }
    break;
   case ECPGt_date:
    ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
    break;
   case ECPGt_timestamp:
    ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(timestamp), &offset, &next_offset);
    break;
   case ECPGt_interval:
    ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
    break;
   case ECPGt_char:
   case ECPGt_unsigned_char:
   case ECPGt_string:
   default:
    {
     long  datalen = strlen(PQgetvalue(res, row, i)) + 1;

     ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
     break;
    }
  }
  offset = next_offset;
 }
 return offset;
}


static long
sqlda_compat_total_size(const PGresult *res, int row, enum COMPAT_MODE compat)
{
 long  offset;

 offset = sqlda_compat_empty_size(res);

 if (row < 0)
  return offset;

 offset = sqlda_common_total_size(res, row, compat, offset);
 return offset;
}

static long
sqlda_native_empty_size(const PGresult *res)
{
 long  offset;
 int   sqld = PQnfields(res);

 /* Initial size to store main structure and field structures */
 offset = sizeof(struct sqlda_struct) + (sqld - 1) * sizeof(struct sqlvar_struct);

 /* Add padding to the first field value */
 ecpg_sqlda_align_add_size(offset, sizeof(int), 0, &offset, NULL);

 return offset;
}

static long
sqlda_native_total_size(const PGresult *res, int row, enum COMPAT_MODE compat)
{
 long  offset;

 offset = sqlda_native_empty_size(res);

 if (row < 0)
  return offset;

 offset = sqlda_common_total_size(res, row, compat, offset);
 return offset;
}

/*
 * Build "struct sqlda_compat" (metadata only) from PGresult
 * leaving enough space for the field values in
 * the given row number
 */

struct sqlda_compat *
ecpg_build_compat_sqlda(int line, PGresult *res, int row, enum COMPAT_MODE compat)
{
 struct sqlda_compat *sqlda;
 struct sqlvar_compat *sqlvar;
 char    *fname;
 long  size;
 int   sqld;
 int   i;

 size = sqlda_compat_total_size(res, row, compat);
 sqlda = (struct sqlda_compat *) ecpg_alloc(size, line);
 if (!sqlda)
  return NULL;

 memset(sqlda, 0, size);
 sqlvar = (struct sqlvar_compat *) (sqlda + 1);
 sqld = PQnfields(res);
 fname = (char *) (sqlvar + sqld);

 sqlda->sqld = sqld;
 ecpg_log("ecpg_build_compat_sqlda on line %d sqld = %d\n", line, sqld);
 sqlda->desc_occ = size;  /* cheat here, keep the full allocated size */
 sqlda->sqlvar = sqlvar;

 for (i = 0; i < sqlda->sqld; i++)
 {
  sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
  strcpy(fname, PQfname(res, i));
  sqlda->sqlvar[i].sqlname = fname;
  fname += strlen(sqlda->sqlvar[i].sqlname) + 1;

  /*
   * this is reserved for future use, so we leave it empty for the time
   * being
 */

  /* sqlda->sqlvar[i].sqlformat = (char *) (long) PQfformat(res, i); */
  sqlda->sqlvar[i].sqlxid = PQftype(res, i);
  sqlda->sqlvar[i].sqltypelen = PQfsize(res, i);
 }

 return sqlda;
}

/*
 * Sets values from PGresult.
 */

static int16 value_is_null = -1;
static int16 value_is_not_null = 0;

void
ecpg_set_compat_sqlda(int lineno, struct sqlda_compat **_sqlda, const PGresult *res, int row, enum COMPAT_MODE compat)
{
 struct sqlda_compat *sqlda = (*_sqlda);
 int   i;
 long  offset,
    next_offset;

 if (row < 0)
  return;

 /* Offset for the first field value */
 offset = sqlda_compat_empty_size(res);

 /*
  * Set sqlvar[i]->sqldata pointers and convert values to correct format
 */

 for (i = 0; i < sqlda->sqld; i++)
 {
  int   isnull;
  int   datalen;
  bool  set_data = true;

  switch (sqlda->sqlvar[i].sqltype)
  {
   case ECPGt_short:
   case ECPGt_unsigned_short:
    ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(short);
    break;
   case ECPGt_int:
   case ECPGt_unsigned_int:
    ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(int);
    break;
   case ECPGt_long:
   case ECPGt_unsigned_long:
    ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(long);
    break;
   case ECPGt_long_long:
   case ECPGt_unsigned_long_long:
    ecpg_sqlda_align_add_size(offset, sizeof(long long), sizeof(long long), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(long long);
    break;
   case ECPGt_bool:
    ecpg_sqlda_align_add_size(offset, sizeof(bool), sizeof(bool), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(bool);
    break;
   case ECPGt_float:
    ecpg_sqlda_align_add_size(offset, sizeof(float), sizeof(float), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(float);
    break;
   case ECPGt_double:
    ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(double);
    break;
   case ECPGt_decimal:
    ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(decimal);
    break;
   case ECPGt_numeric:
    {
     numeric    *num;
     char    *val;

     set_data = false;

     ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
     sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     sqlda->sqlvar[i].sqllen = sizeof(numeric);

     if (PQgetisnull(res, row, i))
     {
      ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
      break;
     }

     val = PQgetvalue(res, row, i);
     num = PGTYPESnumeric_from_asc(val, NULL);
     if (!num)
     {
      ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
      break;
     }

     memcpy(sqlda->sqlvar[i].sqldata, num, sizeof(numeric));

     if (num->buf)
     {
      ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->digits - num->buf + num->ndigits, &offset, &next_offset);
      memcpy((char *) sqlda + offset, num->buf, num->digits - num->buf + num->ndigits);

      ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + offset;
      ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda + offset + (num->digits - num->buf);
     }

     PGTYPESnumeric_free(num);

     break;
    }
   case ECPGt_date:
    ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(date);
    break;
   case ECPGt_timestamp:
    ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(timestamp), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(timestamp);
    break;
   case ECPGt_interval:
    ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(interval);
    break;
   case ECPGt_char:
   case ECPGt_unsigned_char:
   case ECPGt_string:
   default:
    datalen = strlen(PQgetvalue(res, row, i)) + 1;
    ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = datalen;
    if (datalen > 32768)
     sqlda->sqlvar[i].sqlilongdata = sqlda->sqlvar[i].sqldata;
    break;
  }

  isnull = PQgetisnull(res, row, i);
  ecpg_log("ecpg_set_compat_sqlda on line %d row %d col %d %s\n", lineno, row, i, isnull ? "IS NULL" : "IS NOT NULL");
  sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
  sqlda->sqlvar[i].sqlitype = ECPGt_short;
  sqlda->sqlvar[i].sqlilen = sizeof(short);
  if (!isnull)
  {
   if (set_data)
    ecpg_get_data(res, row, i, lineno,
         sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
         sqlda->sqlvar[i].sqldata, NULL, 000,
         ECPG_ARRAY_NONE, compat, false);
  }
  else
   ECPGset_noind_null(sqlda->sqlvar[i].sqltype, sqlda->sqlvar[i].sqldata);

  offset = next_offset;
 }
}

struct sqlda_struct *
ecpg_build_native_sqlda(int line, PGresult *res, int row, enum COMPAT_MODE compat)
{
 struct sqlda_struct *sqlda;
 long  size;
 int   i;

 size = sqlda_native_total_size(res, row, compat);
 sqlda = (struct sqlda_struct *) ecpg_alloc(size, line);
 if (!sqlda)
  return NULL;

 memset(sqlda, 0, size);

 sprintf(sqlda->sqldaid, "SQLDA  ");
 sqlda->sqld = sqlda->sqln = PQnfields(res);
 ecpg_log("ecpg_build_native_sqlda on line %d sqld = %d\n", line, sqlda->sqld);
 sqlda->sqldabc = sizeof(struct sqlda_struct) + (sqlda->sqld - 1) * sizeof(struct sqlvar_struct);

 for (i = 0; i < sqlda->sqld; i++)
 {
  char    *fname;

  sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
  fname = PQfname(res, i);
  sqlda->sqlvar[i].sqlname.length = strlen(fname);
  strcpy(sqlda->sqlvar[i].sqlname.data, fname);
 }

 return sqlda;
}

void
ecpg_set_native_sqlda(int lineno, struct sqlda_struct **_sqlda, const PGresult *res, int row, enum COMPAT_MODE compat)
{
 struct sqlda_struct *sqlda = (*_sqlda);
 int   i;
 long  offset,
    next_offset;

 if (row < 0)
  return;

 /* Offset for the first field value */
 offset = sqlda_native_empty_size(res);

 /*
  * Set sqlvar[i]->sqldata pointers and convert values to correct format
 */

 for (i = 0; i < sqlda->sqld; i++)
 {
  int   isnull;
  int   datalen;
  bool  set_data = true;

  switch (sqlda->sqlvar[i].sqltype)
  {
   case ECPGt_short:
   case ECPGt_unsigned_short:
    ecpg_sqlda_align_add_size(offset, sizeof(short), sizeof(short), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(short);
    break;
   case ECPGt_int:
   case ECPGt_unsigned_int:
    ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(int), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(int);
    break;
   case ECPGt_long:
   case ECPGt_unsigned_long:
    ecpg_sqlda_align_add_size(offset, sizeof(long), sizeof(long), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(long);
    break;
   case ECPGt_long_long:
   case ECPGt_unsigned_long_long:
    ecpg_sqlda_align_add_size(offset, sizeof(long long), sizeof(long long), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(long long);
    break;
   case ECPGt_bool:
    ecpg_sqlda_align_add_size(offset, sizeof(bool), sizeof(bool), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(bool);
    break;
   case ECPGt_float:
    ecpg_sqlda_align_add_size(offset, sizeof(float), sizeof(float), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(float);
    break;
   case ECPGt_double:
    ecpg_sqlda_align_add_size(offset, sizeof(double), sizeof(double), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(double);
    break;
   case ECPGt_decimal:
    ecpg_sqlda_align_add_size(offset, sizeof(int), sizeof(decimal), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(decimal);
    break;
   case ECPGt_numeric:
    {
     numeric    *num;
     char    *val;

     set_data = false;

     ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset);
     sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
     sqlda->sqlvar[i].sqllen = sizeof(numeric);

     if (PQgetisnull(res, row, i))
     {
      ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
      break;
     }

     val = PQgetvalue(res, row, i);
     num = PGTYPESnumeric_from_asc(val, NULL);
     if (!num)
     {
      ECPGset_noind_null(ECPGt_numeric, sqlda->sqlvar[i].sqldata);
      break;
     }

     memcpy(sqlda->sqlvar[i].sqldata, num, sizeof(numeric));

     if (num->buf)
     {
      ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->digits - num->buf + num->ndigits, &offset, &next_offset);
      memcpy((char *) sqlda + offset, num->buf, num->digits - num->buf + num->ndigits);

      ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + offset;
      ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda + offset + (num->digits - num->buf);
     }

     PGTYPESnumeric_free(num);

     break;
    }
   case ECPGt_date:
    ecpg_sqlda_align_add_size(offset, sizeof(date), sizeof(date), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(date);
    break;
   case ECPGt_timestamp:
    ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(timestamp), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(timestamp);
    break;
   case ECPGt_interval:
    ecpg_sqlda_align_add_size(offset, sizeof(int64), sizeof(interval), &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = sizeof(interval);
    break;
   case ECPGt_char:
   case ECPGt_unsigned_char:
   case ECPGt_string:
   default:
    datalen = strlen(PQgetvalue(res, row, i)) + 1;
    ecpg_sqlda_align_add_size(offset, sizeof(int), datalen, &offset, &next_offset);
    sqlda->sqlvar[i].sqldata = (char *) sqlda + offset;
    sqlda->sqlvar[i].sqllen = datalen;
    break;
  }

  isnull = PQgetisnull(res, row, i);
  ecpg_log("ecpg_set_native_sqlda on line %d row %d col %d %s\n", lineno, row, i, isnull ? "IS NULL" : "IS NOT NULL");
  sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
  if (!isnull)
  {
   if (set_data)
    ecpg_get_data(res, row, i, lineno,
         sqlda->sqlvar[i].sqltype, ECPGt_NO_INDICATOR,
         sqlda->sqlvar[i].sqldata, NULL, 000,
         ECPG_ARRAY_NONE, compat, false);
  }

  offset = next_offset;
 }
}

Messung V0.5 in Prozent
C=88 H=95 G=91

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002