Header And Logo

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

Data Structures | Defines | Enumerations | Functions | Variables

extern.h File Reference

#include "postgres_fe.h"
#include "libpq-fe.h"
#include "sqlca.h"
#include "sqlda-native.h"
#include "sqlda-compat.h"
#include "ecpg_config.h"
#include <limits.h>
Include dependency graph for extern.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ECPGgeneric_varchar
struct  ECPGtype_information_cache
struct  statement
struct  prepared_statement
struct  connection
struct  descriptor
struct  descriptor_item
struct  variable
struct  var_list

Defines

#define INFORMIX_MODE(X)   ((X) == ECPG_COMPAT_INFORMIX || (X) == ECPG_COMPAT_INFORMIX_SE)
#define ECPG_IS_ARRAY(X)   ((X) == ECPG_ARRAY_ARRAY || (X) == ECPG_ARRAY_VECTOR)
#define ECPG_SQLSTATE_NO_DATA   "02000"
#define ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS   "07001"
#define ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS   "07002"
#define ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION   "07006"
#define ECPG_SQLSTATE_INVALID_DESCRIPTOR_INDEX   "07009"
#define ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION   "08001"
#define ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST   "08003"
#define ECPG_SQLSTATE_TRANSACTION_RESOLUTION_UNKNOWN   "08007"
#define ECPG_SQLSTATE_CARDINALITY_VIOLATION   "21000"
#define ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER   "22002"
#define ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION   "25001"
#define ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION   "25P01"
#define ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME   "26000"
#define ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME   "33000"
#define ECPG_SQLSTATE_INVALID_CURSOR_NAME   "34000"
#define ECPG_SQLSTATE_SYNTAX_ERROR   "42601"
#define ECPG_SQLSTATE_DATATYPE_MISMATCH   "42804"
#define ECPG_SQLSTATE_DUPLICATE_CURSOR   "42P03"
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR   "YE000"
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY   "YE001"

Enumerations

enum  COMPAT_MODE {
  ECPG_COMPAT_PGSQL = 0, ECPG_COMPAT_INFORMIX, ECPG_COMPAT_INFORMIX_SE, ECPG_COMPAT_PGSQL = 0,
  ECPG_COMPAT_INFORMIX, ECPG_COMPAT_INFORMIX_SE
}
enum  ARRAY_TYPE {
  ECPG_ARRAY_ERROR, ECPG_ARRAY_NOT_SET, ECPG_ARRAY_ARRAY, ECPG_ARRAY_VECTOR,
  ECPG_ARRAY_NONE
}

Functions

void ecpg_add_mem (void *ptr, int lineno)
bool ecpg_get_data (const PGresult *, int, int, int, enum ECPGttype type, enum ECPGttype, char *, char *, long, long, long, enum ARRAY_TYPE, enum COMPAT_MODE, bool)
struct connectionecpg_get_connection (const char *)
char * ecpg_alloc (long, int)
char * ecpg_realloc (void *, long, int)
void ecpg_free (void *)
bool ecpg_init (const struct connection *, const char *, const int)
char * ecpg_strdup (const char *, int)
const char * ecpg_type_name (enum ECPGttype)
int ecpg_dynamic_type (Oid)
int sqlda_dynamic_type (Oid, enum COMPAT_MODE)
void ecpg_free_auto_mem (void)
void ecpg_clear_auto_mem (void)
struct descriptorecpggetdescp (int, char *)
struct descriptorecpg_find_desc (int line, const char *name)
struct prepared_statementecpg_find_prepared_statement (const char *, struct connection *, struct prepared_statement **)
bool ecpg_store_result (const PGresult *results, int act_field, const struct statement *stmt, struct variable *var)
bool ecpg_store_input (const int, const bool, const struct variable *, char **, bool)
bool ecpg_check_PQresult (PGresult *, int, PGconn *, enum COMPAT_MODE)
void ecpg_raise (int line, int code, const char *sqlstate, const char *str)
void ecpg_raise_backend (int line, PGresult *result, PGconn *conn, int compat)
char * ecpg_prepared (const char *, struct connection *)
bool ecpg_deallocate_all_conn (int lineno, enum COMPAT_MODE c, struct connection *conn)
void ecpg_log (const char *format,...) __attribute__((format(PG_PRINTF_ATTRIBUTE
void bool ecpg_auto_prepare (int, const char *, const int, char **, const char *)
void ecpg_init_sqlca (struct sqlca_t *sqlca)
struct sqlda_compatecpg_build_compat_sqlda (int, PGresult *, int, enum COMPAT_MODE)
void ecpg_set_compat_sqlda (int, struct sqlda_compat **, const PGresult *, int, enum COMPAT_MODE)
struct sqlda_structecpg_build_native_sqlda (int, PGresult *, int, enum COMPAT_MODE)
void ecpg_set_native_sqlda (int, struct sqlda_struct **, const PGresult *, int, enum COMPAT_MODE)

Variables

bool ecpg_internal_regression_mode
struct var_listivlist

Define Documentation

#define ECPG_IS_ARRAY (   X  )     ((X) == ECPG_ARRAY_ARRAY || (X) == ECPG_ARRAY_VECTOR)

Definition at line 30 of file extern.h.

Referenced by ecpg_get_data(), ecpg_is_type_an_array(), and garbage_left().

#define ECPG_SQLSTATE_ACTIVE_SQL_TRANSACTION   "25001"

Definition at line 195 of file extern.h.

Referenced by ECPGnoticeReceiver().

#define ECPG_SQLSTATE_CARDINALITY_VIOLATION   "21000"

Definition at line 193 of file extern.h.

Referenced by ecpg_store_result(), and ECPGget_desc().

#define ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST   "08003"

Definition at line 191 of file extern.h.

Referenced by ecpg_init(), and ECPGdescribe().

#define ECPG_SQLSTATE_DATATYPE_MISMATCH   "42804"

Definition at line 201 of file extern.h.

Referenced by ecpg_get_data(), ecpg_store_input(), and ecpg_store_result().

#define ECPG_SQLSTATE_DUPLICATE_CURSOR   "42P03"

Definition at line 202 of file extern.h.

Referenced by ECPGnoticeReceiver().

#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR   "YE000"
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY   "YE001"
#define ECPG_SQLSTATE_INVALID_CURSOR_NAME   "34000"

Definition at line 199 of file extern.h.

Referenced by ECPGnoticeReceiver().

#define ECPG_SQLSTATE_INVALID_DESCRIPTOR_INDEX   "07009"

Definition at line 189 of file extern.h.

Referenced by ECPGget_desc().

#define ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME   "33000"

Definition at line 198 of file extern.h.

Referenced by ecpg_find_desc(), and ECPGdeallocate_desc().

#define ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME   "26000"

Definition at line 197 of file extern.h.

Referenced by deallocate_one(), ECPGdeallocate(), ECPGdescribe(), and ECPGdo().

#define ECPG_SQLSTATE_NO_ACTIVE_SQL_TRANSACTION   "25P01"

Definition at line 196 of file extern.h.

Referenced by ECPGnoticeReceiver().

#define ECPG_SQLSTATE_NO_DATA   "02000"

Definition at line 185 of file extern.h.

Referenced by ecpg_execute(), and ecpg_get_data().

#define ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER   "22002"

Definition at line 194 of file extern.h.

Referenced by ecpg_get_data().

#define ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION   "07006"

Definition at line 188 of file extern.h.

Referenced by get_char_item(), get_int_item(), and set_int_item().

#define ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION   "08001"

Definition at line 190 of file extern.h.

Referenced by ECPGconnect().

#define ECPG_SQLSTATE_SYNTAX_ERROR   "42601"

Definition at line 200 of file extern.h.

#define ECPG_SQLSTATE_TRANSACTION_RESOLUTION_UNKNOWN   "08007"

Definition at line 192 of file extern.h.

#define ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS   "07001"

Definition at line 186 of file extern.h.

Referenced by ecpg_execute().

#define ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_TARGETS   "07002"

Definition at line 187 of file extern.h.

Referenced by ecpg_execute().

#define INFORMIX_MODE (   X  )     ((X) == ECPG_COMPAT_INFORMIX || (X) == ECPG_COMPAT_INFORMIX_SE)

Enumeration Type Documentation

enum ARRAY_TYPE
Enumerator:
ECPG_ARRAY_ERROR 
ECPG_ARRAY_NOT_SET 
ECPG_ARRAY_ARRAY 
ECPG_ARRAY_VECTOR 
ECPG_ARRAY_NONE 

Definition at line 25 of file extern.h.

{
    ECPG_ARRAY_ERROR, ECPG_ARRAY_NOT_SET, ECPG_ARRAY_ARRAY, ECPG_ARRAY_VECTOR, ECPG_ARRAY_NONE
};

Enumerator:
ECPG_COMPAT_PGSQL 
ECPG_COMPAT_INFORMIX 
ECPG_COMPAT_INFORMIX_SE 
ECPG_COMPAT_PGSQL 
ECPG_COMPAT_INFORMIX 
ECPG_COMPAT_INFORMIX_SE 

Definition at line 16 of file extern.h.

{
    ECPG_COMPAT_PGSQL = 0, ECPG_COMPAT_INFORMIX, ECPG_COMPAT_INFORMIX_SE
};


Function Documentation

void ecpg_add_mem ( void *  ptr,
int  lineno 
)

Definition at line 108 of file memory.c.

References ecpg_alloc(), get_auto_allocs, auto_mem::next, auto_mem::pointer, and set_auto_allocs.

Referenced by ecpg_store_result(), and ECPGget_desc().

{
    struct auto_mem *am = (struct auto_mem *) ecpg_alloc(sizeof(struct auto_mem), lineno);

    am->pointer = ptr;
    am->next = get_auto_allocs();
    set_auto_allocs(am);
}

char* ecpg_alloc ( long  ,
int   
)
void bool ecpg_auto_prepare ( int  ,
const char *  ,
const   int,
char **  ,
const char *   
)

Definition at line 468 of file prepare.c.

References AddStmtToCache(), ecpg_find_prepared_statement(), ecpg_get_connection(), ecpg_log(), ecpg_strdup(), ECPGprepare(), stmtCacheEntry::execs, nextStmtID, NULL, prepare_common(), SearchStmtCache(), and stmtCacheEntry::stmtID.

Referenced by ECPGdo().

{
    int         entNo;

    /* search the statement cache for this statement    */
    entNo = SearchStmtCache(query);

    /* if not found - add the statement to the cache    */
    if (entNo)
    {
        char       *stmtID;
        struct connection *con;
        struct prepared_statement *prep;

        ecpg_log("ecpg_auto_prepare on line %d: statement found in cache; entry %d\n", lineno, entNo);

        stmtID = stmtCacheEntries[entNo].stmtID;

        con = ecpg_get_connection(connection_name);
        prep = ecpg_find_prepared_statement(stmtID, con, NULL);
        /* This prepared name doesn't exist on this connection. */
        if (!prep && !prepare_common(lineno, con, stmtID, query))
            return (false);

        *name = ecpg_strdup(stmtID, lineno);
    }
    else
    {
        char        stmtID[STMTID_SIZE];

        ecpg_log("ecpg_auto_prepare on line %d: statement not in cache; inserting\n", lineno);

        /* generate a statement ID */
        sprintf(stmtID, "ecpg%d", nextStmtID++);

        if (!ECPGprepare(lineno, connection_name, 0, stmtID, query))
            return (false);
        if (AddStmtToCache(lineno, stmtID, connection_name, compat, query) < 0)
            return (false);

        *name = ecpg_strdup(stmtID, lineno);
    }

    /* increase usage counter */
    stmtCacheEntries[entNo].execs++;

    return (true);
}

struct sqlda_compat* ecpg_build_compat_sqlda ( int  ,
PGresult ,
int  ,
enum  COMPAT_MODE 
) [read]

Definition at line 202 of file sqlda.c.

References sqlda_compat::desc_occ, ecpg_alloc(), ecpg_log(), i, PQfname(), PQfsize(), PQftype(), PQnfields(), sqlda_compat::sqld, sqlda_compat_total_size(), sqlda_dynamic_type(), sqlvar_compat::sqlname, sqlvar_compat::sqltype, sqlvar_compat::sqltypelen, sqlda_compat::sqlvar, and sqlvar_compat::sqlxid.

Referenced by ecpg_execute(), and ECPGdescribe().

{
    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;
}

struct sqlda_struct* ecpg_build_native_sqlda ( int  ,
PGresult ,
int  ,
enum  COMPAT_MODE 
) [read]

Definition at line 409 of file sqlda.c.

References sqlname::data, ecpg_alloc(), ecpg_log(), i, sqlname::length, PQfname(), PQftype(), PQnfields(), sqlda_struct::sqld, sqlda_dynamic_type(), sqlda_native_total_size(), sqlda_struct::sqldabc, sqlda_struct::sqldaid, sqlda_struct::sqln, sqlvar_struct::sqlname, sqlvar_struct::sqltype, and sqlda_struct::sqlvar.

Referenced by ecpg_execute(), and ECPGdescribe().

{
    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;
}

bool ecpg_check_PQresult ( PGresult ,
int  ,
PGconn ,
enum  COMPAT_MODE 
)

Definition at line 347 of file error.c.

References ECPG_EMPTY, ecpg_log(), ecpg_raise(), ecpg_raise_backend(), ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL, PGRES_BAD_RESPONSE, PGRES_COMMAND_OK, PGRES_COPY_IN, PGRES_COPY_OUT, PGRES_EMPTY_QUERY, PGRES_FATAL_ERROR, PGRES_NONFATAL_ERROR, PGRES_TUPLES_OK, PQclear(), PQendcopy(), PQerrorMessage(), PQresultErrorMessage(), and PQresultStatus().

Referenced by deallocate_one(), ecpg_execute(), ecpg_is_type_an_array(), ECPGdescribe(), ECPGsetcommit(), ECPGtrans(), and prepare_common().

{
    if (results == NULL)
    {
        ecpg_log("ecpg_check_PQresult on line %d: no result - %s", lineno, PQerrorMessage(connection));
        ecpg_raise_backend(lineno, NULL, connection, compat);
        return (false);
    }

    switch (PQresultStatus(results))
    {

        case PGRES_TUPLES_OK:
            return (true);
            break;
        case PGRES_EMPTY_QUERY:
            /* do nothing */
            ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
            PQclear(results);
            return (false);
            break;
        case PGRES_COMMAND_OK:
            return (true);
            break;
        case PGRES_NONFATAL_ERROR:
        case PGRES_FATAL_ERROR:
        case PGRES_BAD_RESPONSE:
            ecpg_log("ecpg_check_PQresult on line %d: bad response - %s", lineno, PQresultErrorMessage(results));
            ecpg_raise_backend(lineno, results, connection, compat);
            PQclear(results);
            return (false);
            break;
        case PGRES_COPY_OUT:
            return (true);
            break;
        case PGRES_COPY_IN:
            ecpg_log("ecpg_check_PQresult on line %d: COPY IN data transfer in progress\n", lineno);
            PQendcopy(connection);
            PQclear(results);
            return (false);
            break;
        default:
            ecpg_log("ecpg_check_PQresult on line %d: unknown execution status type\n",
                     lineno);
            ecpg_raise_backend(lineno, results, connection, compat);
            PQclear(results);
            return (false);
            break;
    }
}

void ecpg_clear_auto_mem ( void   ) 

Definition at line 138 of file memory.c.

References ecpg_free(), get_auto_allocs, auto_mem::next, NULL, and set_auto_allocs.

Referenced by ECPGconnect(), and ECPGdo().

{
    struct auto_mem *am = get_auto_allocs();

    /* only free our own structure */
    if (am)
    {
        do
        {
            struct auto_mem *act = am;

            am = am->next;
            ecpg_free(act);
        } while (am);
        set_auto_allocs(NULL);
    }
}

bool ecpg_deallocate_all_conn ( int  lineno,
enum COMPAT_MODE  c,
struct connection conn 
)

Definition at line 276 of file prepare.c.

References deallocate_one(), NULL, and connection::prep_stmts.

Referenced by ecpg_finish(), and ECPGdeallocate_all().

{
    /* deallocate all prepared statements */
    while (con->prep_stmts)
    {
        if (!deallocate_one(lineno, c, con, NULL, con->prep_stmts))
            return false;
    }

    return true;
}

int ecpg_dynamic_type ( Oid   ) 

Definition at line 72 of file typename.c.

References BOOLOID, BPCHAROID, DATEOID, FLOAT4OID, FLOAT8OID, INT2OID, INT4OID, NUMERICOID, TEXTOID, TIMEOID, TIMESTAMPOID, and VARCHAROID.

Referenced by ecpg_is_type_an_array(), and ECPGget_desc().

{
    switch (type)
    {
        case BOOLOID:
            return SQL3_BOOLEAN;    /* bool */
        case INT2OID:
            return SQL3_SMALLINT;       /* int2 */
        case INT4OID:
            return SQL3_INTEGER;    /* int4 */
        case TEXTOID:
            return SQL3_CHARACTER;      /* text */
        case FLOAT4OID:
            return SQL3_REAL;   /* float4 */
        case FLOAT8OID:
            return SQL3_DOUBLE_PRECISION;       /* float8 */
        case BPCHAROID:
            return SQL3_CHARACTER;      /* bpchar */
        case VARCHAROID:
            return SQL3_CHARACTER_VARYING;      /* varchar */
        case DATEOID:
            return SQL3_DATE_TIME_TIMESTAMP;    /* date */
        case TIMEOID:
            return SQL3_DATE_TIME_TIMESTAMP;    /* time */
        case TIMESTAMPOID:
            return SQL3_DATE_TIME_TIMESTAMP;    /* datetime */
        case NUMERICOID:
            return SQL3_NUMERIC;    /* numeric */
        default:
            return 0;
    }
}

struct descriptor* ecpg_find_desc ( int  line,
const char *  name 
) [read]

Definition at line 773 of file descriptor.c.

References ecpg_raise(), ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, ECPG_UNKNOWN_DESCRIPTOR, get_descriptors, descriptor::name, and descriptor::next.

Referenced by ecpg_execute(), ecpg_result_by_descriptor(), ECPGdescribe(), ECPGset_desc(), and ECPGset_desc_header().

{
    struct descriptor *desc;

    for (desc = get_descriptors(); desc; desc = desc->next)
    {
        if (strcmp(name, desc->name) == 0)
            return desc;
    }

    ecpg_raise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, name);
    return NULL;                /* not found */
}

struct prepared_statement* ecpg_find_prepared_statement ( const char *  ,
struct connection ,
struct prepared_statement **   
) [read]

Definition at line 182 of file prepare.c.

References prepared_statement::next, NULL, and connection::prep_stmts.

Referenced by ecpg_auto_prepare(), ecpg_freeStmtCacheEntry(), ecpg_prepared(), ECPGdeallocate(), ECPGdescribe(), and ECPGprepare().

{
    struct prepared_statement *this,
               *prev;

    for (this = con->prep_stmts, prev = NULL; this != NULL; prev = this, this = this->next)
    {
        if (strcmp(this->name, name) == 0)
        {
            if (prev_)
                *prev_ = prev;
            return this;
        }
    }
    return NULL;
}

void ecpg_free ( void *   ) 
void ecpg_free_auto_mem ( void   ) 
struct connection* ecpg_get_connection ( const char *   )  [read]

Definition at line 74 of file connect.c.

References ecpg_get_connection_nr(), NULL, pthread_getspecific(), pthread_mutex_lock(), and pthread_mutex_unlock().

Referenced by ecpg_auto_prepare(), ecpg_freeStmtCacheEntry(), ECPGconnect(), ECPGdeallocate(), ECPGdeallocate_all(), ECPGdescribe(), ECPGdo(), ECPGget_desc(), ECPGget_PGconn(), ECPGprepare(), ECPGprepared_statement(), ECPGsetcommit(), ECPGsetconn(), ECPGstatus(), ECPGtrans(), and ECPGtransactionStatus().

{
    struct connection *ret = NULL;

    if ((connection_name == NULL) || (strcmp(connection_name, "CURRENT") == 0))
    {
#ifdef ENABLE_THREAD_SAFETY
        ret = pthread_getspecific(actual_connection_key);

        /*
         * if no connection in TSD for this thread, get the global default
         * connection and hope the user knows what they're doing (i.e. using
         * their own mutex to protect that connection from concurrent accesses
         */
        /* if !ret then  we  got the connection from TSD */
        if (NULL == ret)
            /* no TSD connection here either, using global */
            ret = actual_connection;
#else
        ret = actual_connection;
#endif
    }
    else
    {
#ifdef ENABLE_THREAD_SAFETY
        pthread_mutex_lock(&connections_mutex);
#endif

        ret = ecpg_get_connection_nr(connection_name);

#ifdef ENABLE_THREAD_SAFETY
        pthread_mutex_unlock(&connections_mutex);
#endif
    }

    return (ret);
}

bool ecpg_get_data ( const PGresult ,
int  ,
int  ,
int  ,
enum ECPGttype  type,
enum  ECPGttype,
char *  ,
char *  ,
long  ,
long  ,
long  ,
enum  ARRAY_TYPE,
enum  COMPAT_MODE,
bool   
)

Definition at line 123 of file data.c.

References ECPGgeneric_varchar::arr, array_boundary(), array_delimiter(), check_special_value(), ecpg_alloc(), ECPG_ARRAY_ARRAY, ECPG_CONVERT_BOOL, ECPG_DATA_NOT_ARRAY, ECPG_DATE_FORMAT, ECPG_FLOAT_FORMAT, ECPG_INT_FORMAT, ecpg_internal_regression_mode, ECPG_INTERVAL_FORMAT, ECPG_IS_ARRAY, ecpg_log(), ECPG_MISSING_INDICATOR, ECPG_NOT_FOUND, ECPG_NUMERIC_FORMAT, ECPG_OUT_OF_MEMORY, ecpg_raise(), ECPG_SQLSTATE_DATATYPE_MISMATCH, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_NO_DATA, ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER, ECPG_TIMESTAMP_FORMAT, ecpg_type_name(), ECPG_UINT_FORMAT, ECPG_UNSUPPORTED, ECPGget_sqlca(), ECPGset_noind_null(), ECPGt_bool, ECPGt_char, ECPGt_date, ECPGt_decimal, ECPGt_double, ECPGt_float, ECPGt_int, ECPGt_interval, ECPGt_long, ECPGt_long_long, ECPGt_NO_INDICATOR, ECPGt_numeric, ECPGt_short, ECPGt_string, ECPGt_timestamp, ECPGt_unsigned_char, ECPGt_unsigned_int, ECPGt_unsigned_long, ECPGt_unsigned_long_long, ECPGt_unsigned_short, ECPGt_varchar, free, garbage_left(), INFORMIX_MODE, ECPGgeneric_varchar::len, NULL, PGTYPESdate_from_asc(), PGTYPESinterval_copy(), PGTYPESinterval_from_asc(), PGTYPESnumeric_copy(), PGTYPESnumeric_free(), PGTYPESnumeric_from_asc(), PGTYPESnumeric_new(), PGTYPESnumeric_to_decimal(), PGTYPEStimestamp_from_asc(), PQfformat(), PQgetisnull(), PQgetlength(), PQgetvalue(), sqlca, and sqlca_t::sqlwarn.

Referenced by ecpg_set_compat_sqlda(), ecpg_set_native_sqlda(), and ecpg_store_result().

{
    struct sqlca_t *sqlca = ECPGget_sqlca();
    char       *pval = (char *) PQgetvalue(results, act_tuple, act_field);
    int         binary = PQfformat(results, act_field);
    int         size = PQgetlength(results, act_tuple, act_field);
    int         value_for_indicator = 0;
    long        log_offset;

    /*
     * If we are running in a regression test, do not log the offset variable,
     * it depends on the machine's alignment.
     */
    if (ecpg_internal_regression_mode)
        log_offset = -1;
    else
        log_offset = offset;

    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");

    /* pval is a pointer to the value */
    if (!pval)
    {
        /*
         * This should never happen because we already checked that we found
         * at least one tuple, but let's play it safe.
         */
        ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
        return (false);
    }

    /* We will have to decode the value */

    /*
     * check for null value and set indicator accordingly, i.e. -1 if NULL and
     * 0 if not
     */
    if (PQgetisnull(results, act_tuple, act_field))
        value_for_indicator = -1;

    switch (ind_type)
    {
        case ECPGt_short:
        case ECPGt_unsigned_short:
            *((short *) (ind + ind_offset * act_tuple)) = value_for_indicator;
            break;
        case ECPGt_int:
        case ECPGt_unsigned_int:
            *((int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
            break;
        case ECPGt_long:
        case ECPGt_unsigned_long:
            *((long *) (ind + ind_offset * act_tuple)) = value_for_indicator;
            break;
#ifdef HAVE_LONG_LONG_INT
        case ECPGt_long_long:
        case ECPGt_unsigned_long_long:
            *((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
            break;
#endif   /* HAVE_LONG_LONG_INT */
        case ECPGt_NO_INDICATOR:
            if (value_for_indicator == -1)
            {
                if (force_indicator == false)
                {
                    /*
                     * Informix has an additional way to specify NULLs note
                     * that this uses special values to denote NULL
                     */
                    ECPGset_noind_null(type, var + offset * act_tuple);
                }
                else
                {
                    ecpg_raise(lineno, ECPG_MISSING_INDICATOR,
                             ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER,
                               NULL);
                    return (false);
                }
            }
            break;
        default:
            ecpg_raise(lineno, ECPG_UNSUPPORTED,
                       ECPG_SQLSTATE_ECPG_INTERNAL_ERROR,
                       ecpg_type_name(ind_type));
            return (false);
            break;
    }

    if (value_for_indicator == -1)
        return (true);

    /* let's check if it really is an array if it should be one */
    if (isarray == ECPG_ARRAY_ARRAY)
    {
        if (*pval != '{')
        {
            ecpg_raise(lineno, ECPG_DATA_NOT_ARRAY,
                       ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
            return (false);
        }

        switch (type)
        {
            case ECPGt_char:
            case ECPGt_unsigned_char:
            case ECPGt_varchar:
            case ECPGt_string:
                break;

            default:
                pval++;
                break;
        }
    }

    do
    {
        if (binary)
        {
            if (varcharsize == 0 || varcharsize * offset >= size)
                memcpy(var + offset * act_tuple, pval, size);
            else
            {
                memcpy(var + offset * act_tuple, pval, varcharsize * offset);

                if (varcharsize * offset < size)
                {
                    /* truncation */
                    switch (ind_type)
                    {
                        case ECPGt_short:
                        case ECPGt_unsigned_short:
                            *((short *) (ind + ind_offset * act_tuple)) = size;
                            break;
                        case ECPGt_int:
                        case ECPGt_unsigned_int:
                            *((int *) (ind + ind_offset * act_tuple)) = size;
                            break;
                        case ECPGt_long:
                        case ECPGt_unsigned_long:
                            *((long *) (ind + ind_offset * act_tuple)) = size;
                            break;
#ifdef HAVE_LONG_LONG_INT
                        case ECPGt_long_long:
                        case ECPGt_unsigned_long_long:
                            *((long long int *) (ind + ind_offset * act_tuple)) = size;
                            break;
#endif   /* HAVE_LONG_LONG_INT */
                        default:
                            break;
                    }
                    sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
                }
            }
            pval += size;
        }
        else
        {
            switch (type)
            {
                    long        res;
                    unsigned long ures;
                    double      dres;
                    char       *scan_length;
                    numeric    *nres;
                    date        ddres;
                    timestamp   tres;
                    interval   *ires;

                case ECPGt_short:
                case ECPGt_int:
                case ECPGt_long:
                    res = strtol(pval, &scan_length, 10);
                    if (garbage_left(isarray, scan_length, compat))
                    {
                        ecpg_raise(lineno, ECPG_INT_FORMAT,
                                   ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
                        return (false);
                    }
                    pval = scan_length;

                    switch (type)
                    {
                        case ECPGt_short:
                            *((short *) (var + offset * act_tuple)) = (short) res;
                            break;
                        case ECPGt_int:
                            *((int *) (var + offset * act_tuple)) = (int) res;
                            break;
                        case ECPGt_long:
                            *((long *) (var + offset * act_tuple)) = (long) res;
                            break;
                        default:
                            /* Cannot happen */
                            break;
                    }
                    break;

                case ECPGt_unsigned_short:
                case ECPGt_unsigned_int:
                case ECPGt_unsigned_long:
                    ures = strtoul(pval, &scan_length, 10);
                    if (garbage_left(isarray, scan_length, compat))
                    {
                        ecpg_raise(lineno, ECPG_UINT_FORMAT,
                                   ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
                        return (false);
                    }
                    pval = scan_length;

                    switch (type)
                    {
                        case ECPGt_unsigned_short:
                            *((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
                            break;
                        case ECPGt_unsigned_int:
                            *((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
                            break;
                        case ECPGt_unsigned_long:
                            *((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
                            break;
                        default:
                            /* Cannot happen */
                            break;
                    }
                    break;

#ifdef HAVE_LONG_LONG_INT
#ifdef HAVE_STRTOLL
                case ECPGt_long_long:
                    *((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
                    if (garbage_left(isarray, scan_length, compat))
                    {
                        ecpg_raise(lineno, ECPG_INT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
                        return (false);
                    }
                    pval = scan_length;

                    break;
#endif   /* HAVE_STRTOLL */
#ifdef HAVE_STRTOULL
                case ECPGt_unsigned_long_long:
                    *((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
                    if ((isarray && *scan_length != ',' && *scan_length != '}')
                        || (!isarray && !(INFORMIX_MODE(compat) && *scan_length == '.') && *scan_length != '\0' && *scan_length != ' '))        /* Garbage left */
                    {
                        ecpg_raise(lineno, ECPG_UINT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
                        return (false);
                    }
                    pval = scan_length;

                    break;
#endif   /* HAVE_STRTOULL */
#endif   /* HAVE_LONG_LONG_INT */

                case ECPGt_float:
                case ECPGt_double:
                    if (isarray && *pval == '"')
                        pval++;

                    if (!check_special_value(pval, &dres, &scan_length))
                        dres = strtod(pval, &scan_length);

                    if (isarray && *scan_length == '"')
                        scan_length++;

                    if (garbage_left(isarray, scan_length, compat))
                    {
                        ecpg_raise(lineno, ECPG_FLOAT_FORMAT,
                                   ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
                        return (false);
                    }
                    pval = scan_length;

                    switch (type)
                    {
                        case ECPGt_float:
                            *((float *) (var + offset * act_tuple)) = dres;
                            break;
                        case ECPGt_double:
                            *((double *) (var + offset * act_tuple)) = dres;
                            break;
                        default:
                            /* Cannot happen */
                            break;
                    }
                    break;

                case ECPGt_bool:
                    if (pval[0] == 'f' && pval[1] == '\0')
                    {
                        if (offset == sizeof(char))
                            *((char *) (var + offset * act_tuple)) = false;
                        else if (offset == sizeof(int))
                            *((int *) (var + offset * act_tuple)) = false;
                        else
                            ecpg_raise(lineno, ECPG_CONVERT_BOOL,
                                       ECPG_SQLSTATE_DATATYPE_MISMATCH,
                                       NULL);
                        pval++;
                        break;
                    }
                    else if (pval[0] == 't' && pval[1] == '\0')
                    {
                        if (offset == sizeof(char))
                            *((char *) (var + offset * act_tuple)) = true;
                        else if (offset == sizeof(int))
                            *((int *) (var + offset * act_tuple)) = true;
                        else
                            ecpg_raise(lineno, ECPG_CONVERT_BOOL,
                                       ECPG_SQLSTATE_DATATYPE_MISMATCH,
                                       NULL);
                        pval++;
                        break;
                    }
                    else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
                    {
                        /* NULL is valid */
                        break;
                    }

                    ecpg_raise(lineno, ECPG_CONVERT_BOOL,
                               ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
                    return (false);
                    break;

                case ECPGt_char:
                case ECPGt_unsigned_char:
                case ECPGt_string:
                    {
                        char       *str = (char *) (var + offset * act_tuple);

                        if (varcharsize == 0 || varcharsize > size)
                        {
                            strncpy(str, pval, size + 1);
                            /* do the rtrim() */
                            if (type == ECPGt_string)
                            {
                                char       *last = str + size;

                                while (last > str && (*last == ' ' || *last == '\0'))
                                {
                                    *last = '\0';
                                    last--;
                                }
                            }
                        }
                        else
                        {
                            strncpy(str, pval, varcharsize);

                            if (varcharsize < size)
                            {
                                /* truncation */
                                switch (ind_type)
                                {
                                    case ECPGt_short:
                                    case ECPGt_unsigned_short:
                                        *((short *) (ind + ind_offset * act_tuple)) = size;
                                        break;
                                    case ECPGt_int:
                                    case ECPGt_unsigned_int:
                                        *((int *) (ind + ind_offset * act_tuple)) = size;
                                        break;
                                    case ECPGt_long:
                                    case ECPGt_unsigned_long:
                                        *((long *) (ind + ind_offset * act_tuple)) = size;
                                        break;
#ifdef HAVE_LONG_LONG_INT
                                    case ECPGt_long_long:
                                    case ECPGt_unsigned_long_long:
                                        *((long long int *) (ind + ind_offset * act_tuple)) = size;
                                        break;
#endif   /* HAVE_LONG_LONG_INT */
                                    default:
                                        break;
                                }
                                sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
                            }
                        }
                        pval += size;
                    }
                    break;

                case ECPGt_varchar:
                    {
                        struct ECPGgeneric_varchar *variable =
                        (struct ECPGgeneric_varchar *) (var + offset * act_tuple);

                        variable->len = size;
                        if (varcharsize == 0)
                            strncpy(variable->arr, pval, variable->len);
                        else
                        {
                            strncpy(variable->arr, pval, varcharsize);

                            if (variable->len > varcharsize)
                            {
                                /* truncation */
                                switch (ind_type)
                                {
                                    case ECPGt_short:
                                    case ECPGt_unsigned_short:
                                        *((short *) (ind + offset * act_tuple)) = variable->len;
                                        break;
                                    case ECPGt_int:
                                    case ECPGt_unsigned_int:
                                        *((int *) (ind + offset * act_tuple)) = variable->len;
                                        break;
                                    case ECPGt_long:
                                    case ECPGt_unsigned_long:
                                        *((long *) (ind + offset * act_tuple)) = variable->len;
                                        break;
#ifdef HAVE_LONG_LONG_INT
                                    case ECPGt_long_long:
                                    case ECPGt_unsigned_long_long:
                                        *((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
                                        break;
#endif   /* HAVE_LONG_LONG_INT */
                                    default:
                                        break;
                                }
                                sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';

                                variable->len = varcharsize;
                            }
                        }
                        pval += size;
                    }
                    break;

                case ECPGt_decimal:
                case ECPGt_numeric:
                    if (isarray && *pval == '"')
                        nres = PGTYPESnumeric_from_asc(pval + 1, &scan_length);
                    else
                        nres = PGTYPESnumeric_from_asc(pval, &scan_length);

                    /* did we get an error? */
                    if (nres == NULL)
                    {
                        ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
                                 lineno, pval ? pval : "", errno);

                        if (INFORMIX_MODE(compat))
                        {
                            /*
                             * Informix wants its own NULL value here instead
                             * of an error
                             */
                            nres = PGTYPESnumeric_new();
                            if (nres)
                                ECPGset_noind_null(ECPGt_numeric, nres);
                            else
                            {
                                ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
                                     ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
                                return (false);
                            }
                        }
                        else
                        {
                            ecpg_raise(lineno, ECPG_NUMERIC_FORMAT,
                                       ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
                            return (false);
                        }
                    }
                    else
                    {
                        if (isarray && *scan_length == '"')
                            scan_length++;

                        if (garbage_left(isarray, scan_length, compat))
                        {
                            free(nres);
                            ecpg_raise(lineno, ECPG_NUMERIC_FORMAT,
                                       ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
                            return (false);
                        }
                    }
                    pval = scan_length;

                    if (type == ECPGt_numeric)
                        PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
                    else
                        PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));

                    PGTYPESnumeric_free(nres);
                    break;

                case ECPGt_interval:
                    if (isarray && *pval == '"')
                        ires = PGTYPESinterval_from_asc(pval + 1, &scan_length);
                    else
                        ires = PGTYPESinterval_from_asc(pval, &scan_length);

                    /* did we get an error? */
                    if (ires == NULL)
                    {
                        ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
                                 lineno, pval ? pval : "", errno);

                        if (INFORMIX_MODE(compat))
                        {
                            /*
                             * Informix wants its own NULL value here instead
                             * of an error
                             */
                            ires = (interval *) ecpg_alloc(sizeof(interval), lineno);
                            if (!ires)
                                return (false);

                            ECPGset_noind_null(ECPGt_interval, ires);
                        }
                        else
                        {
                            ecpg_raise(lineno, ECPG_INTERVAL_FORMAT,
                                       ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
                            return (false);
                        }
                    }
                    else
                    {
                        if (isarray && *scan_length == '"')
                            scan_length++;

                        if (garbage_left(isarray, scan_length, compat))
                        {
                            free(ires);
                            ecpg_raise(lineno, ECPG_INTERVAL_FORMAT,
                                       ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
                            return (false);
                        }
                    }
                    pval = scan_length;

                    PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
                    free(ires);
                    break;

                case ECPGt_date:
                    if (isarray && *pval == '"')
                        ddres = PGTYPESdate_from_asc(pval + 1, &scan_length);
                    else
                        ddres = PGTYPESdate_from_asc(pval, &scan_length);

                    /* did we get an error? */
                    if (errno != 0)
                    {
                        ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
                                 lineno, pval ? pval : "", errno);

                        if (INFORMIX_MODE(compat))
                        {
                            /*
                             * Informix wants its own NULL value here instead
                             * of an error
                             */
                            ECPGset_noind_null(ECPGt_date, &ddres);
                        }
                        else
                        {
                            ecpg_raise(lineno, ECPG_DATE_FORMAT,
                                       ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
                            return (false);
                        }
                    }
                    else
                    {
                        if (isarray && *scan_length == '"')
                            scan_length++;

                        if (garbage_left(isarray, scan_length, compat))
                        {
                            ecpg_raise(lineno, ECPG_DATE_FORMAT,
                                       ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
                            return (false);
                        }
                    }

                    *((date *) (var + offset * act_tuple)) = ddres;
                    pval = scan_length;
                    break;

                case ECPGt_timestamp:
                    if (isarray && *pval == '"')
                        tres = PGTYPEStimestamp_from_asc(pval + 1, &scan_length);
                    else
                        tres = PGTYPEStimestamp_from_asc(pval, &scan_length);

                    /* did we get an error? */
                    if (errno != 0)
                    {
                        ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
                                 lineno, pval ? pval : "", errno);

                        if (INFORMIX_MODE(compat))
                        {
                            /*
                             * Informix wants its own NULL value here instead
                             * of an error
                             */
                            ECPGset_noind_null(ECPGt_timestamp, &tres);
                        }
                        else
                        {
                            ecpg_raise(lineno, ECPG_TIMESTAMP_FORMAT,
                                       ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
                            return (false);
                        }
                    }
                    else
                    {
                        if (isarray && *scan_length == '"')
                            scan_length++;

                        if (garbage_left(isarray, scan_length, compat))
                        {
                            ecpg_raise(lineno, ECPG_TIMESTAMP_FORMAT,
                                       ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
                            return (false);
                        }
                    }

                    *((timestamp *) (var + offset * act_tuple)) = tres;
                    pval = scan_length;
                    break;

                default:
                    ecpg_raise(lineno, ECPG_UNSUPPORTED,
                               ECPG_SQLSTATE_ECPG_INTERNAL_ERROR,
                               ecpg_type_name(type));
                    return (false);
                    break;
            }
            if (ECPG_IS_ARRAY(isarray))
            {
                bool        string = false;

                /* set array to next entry */
                ++act_tuple;

                /* set pval to the next entry */

                /*
                 * *pval != '\0' should not be needed, but is used as a safety
                 * guard
                 */
                for (; *pval != '\0' && (string || (!array_delimiter(isarray, *pval) && !array_boundary(isarray, *pval))); ++pval)
                    if (*pval == '"')
                        string = string ? false : true;

                if (array_delimiter(isarray, *pval))
                    ++pval;
            }
        }
    } while (*pval != '\0' && !array_boundary(isarray, *pval));

    return (true);
}

bool ecpg_init ( const struct connection ,
const char *  ,
const   int 
)

Definition at line 105 of file misc.c.

References ecpg_gettext, ecpg_init_sqlca(), ECPG_NO_CONN, ecpg_raise(), ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST, ECPGget_sqlca(), and NULL.

Referenced by ECPGdeallocate(), ECPGdisconnect(), ECPGdo(), ECPGprepare(), ECPGsetcommit(), ECPGsetconn(), ECPGstatus(), ECPGtrans(), and main().

{
    struct sqlca_t *sqlca = ECPGget_sqlca();

    ecpg_init_sqlca(sqlca);
    if (con == NULL)
    {
        ecpg_raise(lineno, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST,
                   connection_name ? connection_name : ecpg_gettext("NULL"));
        return (false);
    }

    return (true);
}

void ecpg_init_sqlca ( struct sqlca_t sqlca  ) 

Definition at line 99 of file misc.c.

Referenced by ecpg_init(), ECPGallocate_desc(), ECPGconnect(), ECPGdeallocate_desc(), ECPGdisconnect(), ECPGget_desc(), ECPGget_desc_header(), and ECPGget_sqlca().

{
    memcpy((char *) sqlca, (char *) &sqlca_init, sizeof(struct sqlca_t));
}

void ecpg_log ( const char *  format,
  ... 
)
char* ecpg_prepared ( const char *  ,
struct connection  
)

Definition at line 295 of file prepare.c.

References statement::command, ecpg_find_prepared_statement(), NULL, and prepared_statement::stmt.

Referenced by ECPGdo(), and ECPGprepared_statement().

{
    struct prepared_statement *this;

    this = ecpg_find_prepared_statement(name, con, NULL);
    return this ? this->stmt->command : NULL;
}

void ecpg_raise ( int  line,
int  code,
const char *  sqlstate,
const char *  str 
)

Definition at line 13 of file error.c.

References ECPG_ARRAY_INSERT, ECPG_CONNECT, ECPG_CONVERT_BOOL, ECPG_DATA_NOT_ARRAY, ECPG_EMPTY, ECPG_FLOAT_FORMAT, ecpg_gettext, ECPG_INT_FORMAT, ECPG_INVALID_DESCRIPTOR_INDEX, ECPG_INVALID_STMT, ecpg_log(), ECPG_MISSING_INDICATOR, ECPG_NO_ARRAY, ECPG_NO_CONN, ECPG_NOT_CONN, ECPG_NOT_FOUND, ECPG_OUT_OF_MEMORY, ECPG_TOO_FEW_ARGUMENTS, ECPG_TOO_MANY_ARGUMENTS, ECPG_TRANS, ECPG_UINT_FORMAT, ECPG_UNKNOWN_DESCRIPTOR, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_UNSUPPORTED, ECPG_VAR_NOT_CHAR, ECPG_VAR_NOT_NUMERIC, ECPGfree_auto_mem(), ECPGget_sqlca(), snprintf(), sqlca, sqlca_t::sqlcode, sqlca_t::sqlerrm, sqlca_t::sqlerrmc, sqlca_t::sqlerrml, and sqlca_t::sqlstate.

Referenced by deallocate_one(), ecpg_alloc(), ecpg_check_PQresult(), ecpg_execute(), ecpg_find_desc(), ecpg_get_data(), ecpg_init(), ecpg_realloc(), ecpg_store_input(), ecpg_store_result(), ecpg_strdup(), ECPGallocate_desc(), ECPGconnect(), ECPGdeallocate(), ECPGdeallocate_desc(), ECPGdescribe(), ECPGdo(), ECPGget_desc(), ECPGset_desc(), ECPGstatus(), get_char_item(), get_int_item(), and set_int_item().

{
    struct sqlca_t *sqlca = ECPGget_sqlca();

    sqlca->sqlcode = code;
    strncpy(sqlca->sqlstate, sqlstate, sizeof(sqlca->sqlstate));

    switch (code)
    {
        case ECPG_NOT_FOUND:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("no data found on line %d"), line);
            break;

        case ECPG_OUT_OF_MEMORY:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("out of memory on line %d"), line);
            break;

        case ECPG_UNSUPPORTED:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
              ecpg_gettext("unsupported type \"%s\" on line %d"), str, line);
            break;

        case ECPG_TOO_MANY_ARGUMENTS:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("too many arguments on line %d"), line);
            break;

        case ECPG_TOO_FEW_ARGUMENTS:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("too few arguments on line %d"), line);
            break;

        case ECPG_INT_FORMAT:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("invalid input syntax for type int: \"%s\", on line %d"), str, line);
            break;

        case ECPG_UINT_FORMAT:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("invalid input syntax for type unsigned int: \"%s\", on line %d"), str, line);
            break;

        case ECPG_FLOAT_FORMAT:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("invalid input syntax for floating-point type: \"%s\", on line %d"), str, line);
            break;

        case ECPG_CONVERT_BOOL:
            if (str)
                snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

                /*
                 * translator: this string will be truncated at 149 characters
                 * expanded.
                 */
                         ecpg_gettext("invalid syntax for type boolean: \"%s\", on line %d"), str, line);
            else
                snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

                /*
                 * translator: this string will be truncated at 149 characters
                 * expanded.
                 */
                         ecpg_gettext("could not convert boolean value: size mismatch, on line %d"), line);
            break;

        case ECPG_EMPTY:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("empty query on line %d"), line);
            break;

        case ECPG_MISSING_INDICATOR:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
              ecpg_gettext("null value without indicator on line %d"), line);
            break;

        case ECPG_NO_ARRAY:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("variable does not have an array type on line %d"), line);
            break;

        case ECPG_DATA_NOT_ARRAY:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("data read from server is not an array on line %d"), line);
            break;

        case ECPG_ARRAY_INSERT:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("inserting an array of variables is not supported on line %d"), line);
            break;

        case ECPG_NO_CONN:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("connection \"%s\" does not exist on line %d"), str, line);
            break;

        case ECPG_NOT_CONN:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("not connected to connection \"%s\" on line %d"), str, line);
            break;

        case ECPG_INVALID_STMT:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("invalid statement name \"%s\" on line %d"), str, line);
            break;

        case ECPG_UNKNOWN_DESCRIPTOR:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("descriptor \"%s\" not found on line %d"), str, line);
            break;

        case ECPG_INVALID_DESCRIPTOR_INDEX:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
             ecpg_gettext("descriptor index out of range on line %d"), line);
            break;

        case ECPG_UNKNOWN_DESCRIPTOR_ITEM:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("unrecognized descriptor item \"%s\" on line %d"), str, line);
            break;

        case ECPG_VAR_NOT_NUMERIC:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("variable does not have a numeric type on line %d"), line);
            break;

        case ECPG_VAR_NOT_CHAR:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("variable does not have a character type on line %d"), line);
            break;

        case ECPG_TRANS:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
            ecpg_gettext("error in transaction processing on line %d"), line);
            break;

        case ECPG_CONNECT:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("could not connect to database \"%s\" on line %d"), str, line);
            break;

        default:
            snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc),

            /*
             * translator: this string will be truncated at 149 characters
             * expanded.
             */
                     ecpg_gettext("SQL error %d on line %d"), code, line);
            break;
    }

    sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);
    ecpg_log("raising sqlcode %d on line %d: %s\n", code, line, sqlca->sqlerrm.sqlerrmc);

    /* free all memory we have allocated for the user */
    ECPGfree_auto_mem();
}

void ecpg_raise_backend ( int  line,
PGresult result,
PGconn conn,
int  compat 
)

Definition at line 290 of file error.c.

References CONNECTION_BAD, ecpg_gettext, ECPG_INFORMIX_DUPLICATE_KEY, ECPG_INFORMIX_SUBSELECT_NOT_ONE, ecpg_log(), ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ECPGfree_auto_mem(), ECPGget_sqlca(), INFORMIX_MODE, NULL, PG_DIAG_MESSAGE_PRIMARY, PG_DIAG_SQLSTATE, PQerrorMessage(), PQresultErrorField(), PQstatus(), snprintf(), sqlca, sqlca_t::sqlcode, sqlca_t::sqlerrm, sqlca_t::sqlerrmc, sqlca_t::sqlerrml, and sqlca_t::sqlstate.

Referenced by ecpg_check_PQresult(), and ecpg_execute().

{
    struct sqlca_t *sqlca = ECPGget_sqlca();
    char       *sqlstate;
    char       *message;

    if (result)
    {
        sqlstate = PQresultErrorField(result, PG_DIAG_SQLSTATE);
        if (sqlstate == NULL)
            sqlstate = ECPG_SQLSTATE_ECPG_INTERNAL_ERROR;
        message = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY);
    }
    else
    {
        sqlstate = ECPG_SQLSTATE_ECPG_INTERNAL_ERROR;
        message = PQerrorMessage(conn);
    }

    if (strcmp(sqlstate, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR) == 0)
    {
        /*
         * we might get here if the connection breaks down, so let's check for
         * this instead of giving just the generic internal error
         */
        if (PQstatus(conn) == CONNECTION_BAD)
        {
            sqlstate = "57P02";
            message = ecpg_gettext("the connection to the server was lost");
        }
    }

    /* copy error message */
    snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), "%s on line %d", message, line);
    sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);

    /* copy SQLSTATE */
    strncpy(sqlca->sqlstate, sqlstate, sizeof(sqlca->sqlstate));

    /* assign SQLCODE for backward compatibility */
    if (strncmp(sqlca->sqlstate, "23505", sizeof(sqlca->sqlstate)) == 0)
        sqlca->sqlcode = INFORMIX_MODE(compat) ? ECPG_INFORMIX_DUPLICATE_KEY : ECPG_DUPLICATE_KEY;
    else if (strncmp(sqlca->sqlstate, "21000", sizeof(sqlca->sqlstate)) == 0)
        sqlca->sqlcode = INFORMIX_MODE(compat) ? ECPG_INFORMIX_SUBSELECT_NOT_ONE : ECPG_SUBSELECT_NOT_ONE;
    else
        sqlca->sqlcode = ECPG_PGSQL;

    /* %.*s is safe here as long as sqlstate is all-ASCII */
    ecpg_log("raising sqlstate %.*s (sqlcode %ld): %s\n",
             (int) sizeof(sqlca->sqlstate), sqlca->sqlstate, sqlca->sqlcode, sqlca->sqlerrm.sqlerrmc);

    /* free all memory we have allocated for the user */
    ECPGfree_auto_mem();
}

char* ecpg_realloc ( void *  ,
long  ,
int   
)

Definition at line 33 of file memory.c.

References ECPG_OUT_OF_MEMORY, ecpg_raise(), ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL, and realloc.

Referenced by ecpg_execute(), and ecpg_store_input().

{
    char       *new = (char *) realloc(ptr, size);

    if (!new)
    {
        ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
        return NULL;
    }

    return (new);
}

void ecpg_set_compat_sqlda ( int  ,
struct sqlda_compat **  ,
const PGresult ,
int  ,
enum  COMPAT_MODE 
)

Definition at line 252 of file sqlda.c.

References numeric::buf, numeric::digits, ECPG_ARRAY_NONE, ecpg_get_data(), ecpg_log(), ecpg_sqlda_align_add_size(), ECPGset_noind_null(), ECPGt_bool, ECPGt_char, ECPGt_date, ECPGt_decimal, ECPGt_double, ECPGt_float, ECPGt_int, ECPGt_interval, ECPGt_long, ECPGt_long_long, ECPGt_NO_INDICATOR, ECPGt_numeric, ECPGt_short, ECPGt_string, ECPGt_timestamp, ECPGt_unsigned_char, ECPGt_unsigned_int, ECPGt_unsigned_long, ECPGt_unsigned_long_long, ECPGt_unsigned_short, i, numeric::ndigits, NULL, PGTYPESnumeric_free(), PGTYPESnumeric_from_asc(), PQgetisnull(), PQgetvalue(), sqlda_compat::sqld, sqlda_compat_empty_size(), sqlvar_compat::sqldata, sqlvar_compat::sqlilen, sqlvar_compat::sqlilongdata, sqlvar_compat::sqlind, sqlvar_compat::sqlitype, sqlvar_compat::sqllen, sqlvar_compat::sqltype, sqlda_compat::sqlvar, val, value_is_not_null, and value_is_null.

Referenced by ecpg_execute().

{
    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->ndigits)
                    {
                        ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->ndigits + 1, &offset, &next_offset);
                        memcpy((char *) sqlda + offset, num->buf, num->ndigits + 1);

                        ((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, 0, 0, 0,
                              ECPG_ARRAY_NONE, compat, false);
        }
        else
            ECPGset_noind_null(sqlda->sqlvar[i].sqltype, sqlda->sqlvar[i].sqldata);

        offset = next_offset;
    }
}

void ecpg_set_native_sqlda ( int  ,
struct sqlda_struct **  ,
const PGresult ,
int  ,
enum  COMPAT_MODE 
)

Definition at line 441 of file sqlda.c.

References numeric::buf, numeric::digits, ECPG_ARRAY_NONE, ecpg_get_data(), ecpg_log(), ecpg_sqlda_align_add_size(), ECPGset_noind_null(), ECPGt_bool, ECPGt_char, ECPGt_date, ECPGt_decimal, ECPGt_double, ECPGt_float, ECPGt_int, ECPGt_interval, ECPGt_long, ECPGt_long_long, ECPGt_NO_INDICATOR, ECPGt_numeric, ECPGt_short, ECPGt_string, ECPGt_timestamp, ECPGt_unsigned_char, ECPGt_unsigned_int, ECPGt_unsigned_long, ECPGt_unsigned_long_long, ECPGt_unsigned_short, i, numeric::ndigits, NULL, PGTYPESnumeric_free(), PGTYPESnumeric_from_asc(), PQgetisnull(), PQgetvalue(), sqlda_struct::sqld, sqlda_native_empty_size(), sqlvar_struct::sqldata, sqlvar_struct::sqlind, sqlvar_struct::sqllen, sqlvar_struct::sqltype, sqlda_struct::sqlvar, val, value_is_not_null, and value_is_null.

Referenced by ecpg_execute().

{
    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->ndigits)
                    {
                        ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->ndigits + 1, &offset, &next_offset);
                        memcpy((char *) sqlda + offset, num->buf, num->ndigits + 1);

                        ((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, 0, 0, 0,
                              ECPG_ARRAY_NONE, compat, false);
        }

        offset = next_offset;
    }
}

bool ecpg_store_input ( const   int,
const   bool,
const struct variable ,
char **  ,
bool   
)

Definition at line 501 of file execute.c.

References ECPGgeneric_varchar::arr, variable::arrsize, numeric::dscale, ecpg_alloc(), ECPG_ARRAY_INSERT, ECPG_CONVERT_BOOL, ecpg_free(), ecpg_raise(), ecpg_realloc(), ECPG_SQLSTATE_DATATYPE_MISMATCH, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ecpg_strdup(), ecpg_type_name(), ECPG_UNSUPPORTED, ECPGis_noind_null(), ECPGt_bool, ECPGt_char, ECPGt_char_variable, ECPGt_const, ECPGt_date, ECPGt_decimal, ECPGt_descriptor, ECPGt_double, ECPGt_float, ECPGt_int, ECPGt_interval, ECPGt_long, ECPGt_long_long, ECPGt_NO_INDICATOR, ECPGt_numeric, ECPGt_short, ECPGt_sqlda, ECPGt_string, ECPGt_timestamp, ECPGt_unsigned_char, ECPGt_unsigned_int, ECPGt_unsigned_long, ECPGt_unsigned_long_long, ECPGt_unsigned_short, ECPGt_varchar, free, variable::ind_type, variable::ind_value, ECPGgeneric_varchar::len, NULL, variable::offset, PGTYPESdate_to_asc(), PGTYPESinterval_to_asc(), PGTYPESnumeric_copy(), PGTYPESnumeric_free(), PGTYPESnumeric_from_decimal(), PGTYPESnumeric_new(), PGTYPESnumeric_to_asc(), PGTYPEStimestamp_to_asc(), quote_postgres(), sprintf_double_value(), sprintf_float_value(), variable::type, variable::value, and variable::varcharsize.

Referenced by ecpg_execute(), and ECPGset_desc().

{
    char       *mallocedval = NULL;
    char       *newcopy = NULL;

    /*
     * arrays are not possible unless the attribute is an array too FIXME: we
     * do not know if the attribute is an array here
     */
#if 0
    if (var->arrsize > 1 &&...)
    {
        ecpg_raise(lineno, ECPG_ARRAY_INSERT, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
        return false;
    }
#endif

    /*
     * Some special treatment is needed for records since we want their
     * contents to arrive in a comma-separated list on insert (I think).
     */

    *tobeinserted_p = "";

    /* check for null value and set input buffer accordingly */
    switch (var->ind_type)
    {
        case ECPGt_short:
        case ECPGt_unsigned_short:
            if (*(short *) var->ind_value < 0)
                *tobeinserted_p = NULL;
            break;
        case ECPGt_int:
        case ECPGt_unsigned_int:
            if (*(int *) var->ind_value < 0)
                *tobeinserted_p = NULL;
            break;
        case ECPGt_long:
        case ECPGt_unsigned_long:
            if (*(long *) var->ind_value < 0L)
                *tobeinserted_p = NULL;
            break;
#ifdef HAVE_LONG_LONG_INT
        case ECPGt_long_long:
        case ECPGt_unsigned_long_long:
            if (*(long long int *) var->ind_value < (long long) 0)
                *tobeinserted_p = NULL;
            break;
#endif   /* HAVE_LONG_LONG_INT */
        case ECPGt_NO_INDICATOR:
            if (force_indicator == false)
            {
                if (ECPGis_noind_null(var->type, var->value))
                    *tobeinserted_p = NULL;
            }
            break;
        default:
            break;
    }
    if (*tobeinserted_p != NULL)
    {
        int         asize = var->arrsize ? var->arrsize : 1;

        switch (var->type)
        {
                int         element;

            case ECPGt_short:
                if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
                    return false;

                if (asize > 1)
                {
                    strcpy(mallocedval, "array [");

                    for (element = 0; element < asize; element++)
                        sprintf(mallocedval + strlen(mallocedval), "%hd,", ((short *) var->value)[element]);

                    strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                }
                else
                    sprintf(mallocedval, "%hd", *((short *) var->value));

                *tobeinserted_p = mallocedval;
                break;

            case ECPGt_int:
                if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
                    return false;

                if (asize > 1)
                {
                    strcpy(mallocedval, "{");

                    for (element = 0; element < asize; element++)
                        sprintf(mallocedval + strlen(mallocedval), "%d,", ((int *) var->value)[element]);

                    strcpy(mallocedval + strlen(mallocedval) - 1, "}");
                }
                else
                    sprintf(mallocedval, "%d", *((int *) var->value));

                *tobeinserted_p = mallocedval;
                break;

            case ECPGt_unsigned_short:
                if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
                    return false;

                if (asize > 1)
                {
                    strcpy(mallocedval, "array [");

                    for (element = 0; element < asize; element++)
                        sprintf(mallocedval + strlen(mallocedval), "%hu,", ((unsigned short *) var->value)[element]);

                    strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                }
                else
                    sprintf(mallocedval, "%hu", *((unsigned short *) var->value));

                *tobeinserted_p = mallocedval;
                break;

            case ECPGt_unsigned_int:
                if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
                    return false;

                if (asize > 1)
                {
                    strcpy(mallocedval, "array [");

                    for (element = 0; element < asize; element++)
                        sprintf(mallocedval + strlen(mallocedval), "%u,", ((unsigned int *) var->value)[element]);

                    strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                }
                else
                    sprintf(mallocedval, "%u", *((unsigned int *) var->value));

                *tobeinserted_p = mallocedval;
                break;

            case ECPGt_long:
                if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
                    return false;

                if (asize > 1)
                {
                    strcpy(mallocedval, "array [");

                    for (element = 0; element < asize; element++)
                        sprintf(mallocedval + strlen(mallocedval), "%ld,", ((long *) var->value)[element]);

                    strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                }
                else
                    sprintf(mallocedval, "%ld", *((long *) var->value));

                *tobeinserted_p = mallocedval;
                break;

            case ECPGt_unsigned_long:
                if (!(mallocedval = ecpg_alloc(asize * 20, lineno)))
                    return false;

                if (asize > 1)
                {
                    strcpy(mallocedval, "array [");

                    for (element = 0; element < asize; element++)
                        sprintf(mallocedval + strlen(mallocedval), "%lu,", ((unsigned long *) var->value)[element]);

                    strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                }
                else
                    sprintf(mallocedval, "%lu", *((unsigned long *) var->value));

                *tobeinserted_p = mallocedval;
                break;
#ifdef HAVE_LONG_LONG_INT
            case ECPGt_long_long:
                if (!(mallocedval = ecpg_alloc(asize * 30, lineno)))
                    return false;

                if (asize > 1)
                {
                    strcpy(mallocedval, "array [");

                    for (element = 0; element < asize; element++)
                        sprintf(mallocedval + strlen(mallocedval), "%lld,", ((long long int *) var->value)[element]);

                    strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                }
                else
                    sprintf(mallocedval, "%lld", *((long long int *) var->value));

                *tobeinserted_p = mallocedval;
                break;

            case ECPGt_unsigned_long_long:
                if (!(mallocedval = ecpg_alloc(asize * 30, lineno)))
                    return false;

                if (asize > 1)
                {
                    strcpy(mallocedval, "array [");

                    for (element = 0; element < asize; element++)
                        sprintf(mallocedval + strlen(mallocedval), "%llu,", ((unsigned long long int *) var->value)[element]);

                    strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                }
                else
                    sprintf(mallocedval, "%llu", *((unsigned long long int *) var->value));

                *tobeinserted_p = mallocedval;
                break;
#endif   /* HAVE_LONG_LONG_INT */
            case ECPGt_float:
                if (!(mallocedval = ecpg_alloc(asize * 25, lineno)))
                    return false;

                if (asize > 1)
                {
                    strcpy(mallocedval, "array [");

                    for (element = 0; element < asize; element++)
                        sprintf_float_value(mallocedval + strlen(mallocedval), ((float *) var->value)[element], ",");

                    strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                }
                else
                    sprintf_float_value(mallocedval, *((float *) var->value), "");

                *tobeinserted_p = mallocedval;
                break;

            case ECPGt_double:
                if (!(mallocedval = ecpg_alloc(asize * 25, lineno)))
                    return false;

                if (asize > 1)
                {
                    strcpy(mallocedval, "array [");

                    for (element = 0; element < asize; element++)
                        sprintf_double_value(mallocedval + strlen(mallocedval), ((double *) var->value)[element], ",");

                    strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                }
                else
                    sprintf_double_value(mallocedval, *((double *) var->value), "");

                *tobeinserted_p = mallocedval;
                break;

            case ECPGt_bool:
                if (!(mallocedval = ecpg_alloc(var->arrsize + sizeof("array []"), lineno)))
                    return false;

                if (var->arrsize > 1)
                {
                    strcpy(mallocedval, "array [");

                    if (var->offset == sizeof(char))
                        for (element = 0; element < var->arrsize; element++)
                            sprintf(mallocedval + strlen(mallocedval), "%c,", (((char *) var->value)[element]) ? 't' : 'f');

                    /*
                     * this is necessary since sizeof(C++'s bool)==sizeof(int)
                     */
                    else if (var->offset == sizeof(int))
                        for (element = 0; element < var->arrsize; element++)
                            sprintf(mallocedval + strlen(mallocedval), "%c,", (((int *) var->value)[element]) ? 't' : 'f');
                    else
                        ecpg_raise(lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);

                    strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                }
                else
                {
                    if (var->offset == sizeof(char))
                        sprintf(mallocedval, "%c", (*((char *) var->value)) ? 't' : 'f');
                    else if (var->offset == sizeof(int))
                        sprintf(mallocedval, "%c", (*((int *) var->value)) ? 't' : 'f');
                    else
                        ecpg_raise(lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
                }

                *tobeinserted_p = mallocedval;
                break;

            case ECPGt_char:
            case ECPGt_unsigned_char:
            case ECPGt_string:
                {
                    /* set slen to string length if type is char * */
                    int         slen = (var->varcharsize == 0) ? strlen((char *) var->value) : (unsigned int) var->varcharsize;

                    if (!(newcopy = ecpg_alloc(slen + 1, lineno)))
                        return false;

                    strncpy(newcopy, (char *) var->value, slen);
                    newcopy[slen] = '\0';

                    mallocedval = quote_postgres(newcopy, quote, lineno);
                    if (!mallocedval)
                        return false;

                    *tobeinserted_p = mallocedval;
                }
                break;
            case ECPGt_const:
            case ECPGt_char_variable:
                {
                    int         slen = strlen((char *) var->value);

                    if (!(mallocedval = ecpg_alloc(slen + 1, lineno)))
                        return false;

                    strncpy(mallocedval, (char *) var->value, slen);
                    mallocedval[slen] = '\0';

                    *tobeinserted_p = mallocedval;
                }
                break;
            case ECPGt_varchar:
                {
                    struct ECPGgeneric_varchar *variable =
                    (struct ECPGgeneric_varchar *) (var->value);

                    if (!(newcopy = (char *) ecpg_alloc(variable->len + 1, lineno)))
                        return false;

                    strncpy(newcopy, variable->arr, variable->len);
                    newcopy[variable->len] = '\0';

                    mallocedval = quote_postgres(newcopy, quote, lineno);
                    if (!mallocedval)
                        return false;

                    *tobeinserted_p = mallocedval;
                }
                break;

            case ECPGt_decimal:
            case ECPGt_numeric:
                {
                    char       *str = NULL;
                    int         slen;
                    numeric    *nval;

                    if (var->arrsize > 1)
                    {
                        if (!(mallocedval = ecpg_strdup("array [", lineno)))
                            return false;

                        for (element = 0; element < var->arrsize; element++)
                        {
                            nval = PGTYPESnumeric_new();
                            if (!nval)
                                return false;

                            if (var->type == ECPGt_numeric)
                                PGTYPESnumeric_copy((numeric *) ((var + var->offset * element)->value), nval);
                            else
                                PGTYPESnumeric_from_decimal((decimal *) ((var + var->offset * element)->value), nval);

                            str = PGTYPESnumeric_to_asc(nval, nval->dscale);
                            slen = strlen(str);
                            PGTYPESnumeric_free(nval);

                            if (!(mallocedval = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
                            {
                                ecpg_free(str);
                                return false;
                            }

                            strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
                            strcpy(mallocedval + strlen(mallocedval), ",");
                            ecpg_free(str);
                        }
                        strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                    }
                    else
                    {
                        nval = PGTYPESnumeric_new();
                        if (!nval)
                            return false;

                        if (var->type == ECPGt_numeric)
                            PGTYPESnumeric_copy((numeric *) (var->value), nval);
                        else
                            PGTYPESnumeric_from_decimal((decimal *) (var->value), nval);

                        str = PGTYPESnumeric_to_asc(nval, nval->dscale);
                        slen = strlen(str);
                        PGTYPESnumeric_free(nval);

                        if (!(mallocedval = ecpg_alloc(slen + 1, lineno)))
                        {
                            free(str);
                            return false;
                        }

                        strncpy(mallocedval, str, slen);
                        mallocedval[slen] = '\0';
                        ecpg_free(str);
                    }

                    *tobeinserted_p = mallocedval;
                }
                break;

            case ECPGt_interval:
                {
                    char       *str = NULL;
                    int         slen;

                    if (var->arrsize > 1)
                    {
                        if (!(mallocedval = ecpg_strdup("array [", lineno)))
                            return false;

                        for (element = 0; element < var->arrsize; element++)
                        {
                            str = quote_postgres(PGTYPESinterval_to_asc((interval *) ((var + var->offset * element)->value)), quote, lineno);
                            if (!str)
                                return false;
                            slen = strlen(str);

                            if (!(mallocedval = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
                            {
                                ecpg_free(str);
                                return false;
                            }

                            strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
                            strcpy(mallocedval + strlen(mallocedval), ",");
                            ecpg_free(str);
                        }
                        strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                    }
                    else
                    {
                        str = quote_postgres(PGTYPESinterval_to_asc((interval *) (var->value)), quote, lineno);
                        if (!str)
                            return false;
                        slen = strlen(str);

                        if (!(mallocedval = ecpg_alloc(slen + sizeof("interval ") + 1, lineno)))
                        {
                            ecpg_free(str);
                            return false;
                        }

                        /* also copy trailing '\0' */
                        strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
                        ecpg_free(str);
                    }

                    *tobeinserted_p = mallocedval;
                }
                break;

            case ECPGt_date:
                {
                    char       *str = NULL;
                    int         slen;

                    if (var->arrsize > 1)
                    {
                        if (!(mallocedval = ecpg_strdup("array [", lineno)))
                            return false;

                        for (element = 0; element < var->arrsize; element++)
                        {
                            str = quote_postgres(PGTYPESdate_to_asc(*(date *) ((var + var->offset * element)->value)), quote, lineno);
                            if (!str)
                                return false;
                            slen = strlen(str);

                            if (!(mallocedval = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
                            {
                                ecpg_free(str);
                                return false;
                            }

                            strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
                            strcpy(mallocedval + strlen(mallocedval), ",");
                            ecpg_free(str);
                        }
                        strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                    }
                    else
                    {
                        str = quote_postgres(PGTYPESdate_to_asc(*(date *) (var->value)), quote, lineno);
                        if (!str)
                            return false;
                        slen = strlen(str);

                        if (!(mallocedval = ecpg_alloc(slen + sizeof("date ") + 1, lineno)))
                        {
                            ecpg_free(str);
                            return false;
                        }

                        /* also copy trailing '\0' */
                        strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
                        ecpg_free(str);
                    }

                    *tobeinserted_p = mallocedval;
                }
                break;

            case ECPGt_timestamp:
                {
                    char       *str = NULL;
                    int         slen;

                    if (var->arrsize > 1)
                    {
                        if (!(mallocedval = ecpg_strdup("array [", lineno)))
                            return false;

                        for (element = 0; element < var->arrsize; element++)
                        {
                            str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) ((var + var->offset * element)->value)), quote, lineno);
                            if (!str)
                                return false;

                            slen = strlen(str);

                            if (!(mallocedval = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
                            {
                                ecpg_free(str);
                                return false;
                            }

                            strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
                            strcpy(mallocedval + strlen(mallocedval), ",");
                            ecpg_free(str);
                        }
                        strcpy(mallocedval + strlen(mallocedval) - 1, "]");
                    }
                    else
                    {
                        str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) (var->value)), quote, lineno);
                        if (!str)
                            return false;
                        slen = strlen(str);

                        if (!(mallocedval = ecpg_alloc(slen + sizeof("timestamp") + 1, lineno)))
                        {
                            ecpg_free(str);
                            return false;
                        }

                        /* also copy trailing '\0' */
                        strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
                        ecpg_free(str);
                    }

                    *tobeinserted_p = mallocedval;
                }
                break;

            case ECPGt_descriptor:
            case ECPGt_sqlda:
                break;

            default:
                /* Not implemented yet */
                ecpg_raise(lineno, ECPG_UNSUPPORTED, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ecpg_type_name(var->type));
                return false;
                break;
        }
    }
    return true;
}

bool ecpg_store_result ( const PGresult results,
int  act_field,
const struct statement stmt,
struct variable var 
)

Definition at line 314 of file execute.c.

References variable::arrsize, statement::compat, ecpg_add_mem(), ecpg_alloc(), ECPG_ARRAY_ERROR, ECPG_ARRAY_NONE, ecpg_get_data(), ECPG_INFORMIX_SUBSELECT_NOT_ONE, ecpg_is_type_an_array(), ecpg_log(), ECPG_NO_ARRAY, ECPG_OUT_OF_MEMORY, ecpg_raise(), ECPG_SQLSTATE_CARDINALITY_VIOLATION, ECPG_SQLSTATE_DATATYPE_MISMATCH, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, ECPG_TOO_MANY_MATCHES, ECPGt_char, ECPGt_string, ECPGt_unsigned_char, ECPGt_varchar, statement::force_indicator, variable::ind_arrsize, variable::ind_offset, variable::ind_pointer, variable::ind_type, variable::ind_value, variable::ind_varcharsize, INFORMIX_MODE, ECPGtype_information_cache::isarray, statement::lineno, NULL, variable::offset, variable::pointer, PQfformat(), PQftype(), PQgetlength(), PQgetvalue(), PQntuples(), status(), variable::type, variable::value, and variable::varcharsize.

Referenced by ecpg_execute(), and ECPGget_desc().

{
    enum ARRAY_TYPE isarray;
    int         act_tuple,
                ntuples = PQntuples(results);
    bool        status = true;

    if ((isarray = ecpg_is_type_an_array(PQftype(results, act_field), stmt, var)) == ECPG_ARRAY_ERROR)
    {
        ecpg_raise(stmt->lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
        return false;
    }

    if (isarray == ECPG_ARRAY_NONE)
    {
        /*
         * if we don't have enough space, we cannot read all tuples
         */
        if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize))
        {
            ecpg_log("ecpg_store_result on line %d: incorrect number of matches; %d don't fit into array of %ld\n",
                     stmt->lineno, ntuples, var->arrsize);
            ecpg_raise(stmt->lineno, INFORMIX_MODE(stmt->compat) ? ECPG_INFORMIX_SUBSELECT_NOT_ONE : ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);
            return false;
        }
    }
    else
    {
        /*
         * since we read an array, the variable has to be an array too
         */
        if (var->arrsize == 0)
        {
            ecpg_raise(stmt->lineno, ECPG_NO_ARRAY, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
            return false;
        }
    }

    /*
     * allocate memory for NULL pointers
     */
    if ((var->arrsize == 0 || var->varcharsize == 0) && var->value == NULL)
    {
        int         len = 0;

        if (!PQfformat(results, act_field))
        {
            switch (var->type)
            {
                case ECPGt_char:
                case ECPGt_unsigned_char:
                case ECPGt_string:
                    if (!var->varcharsize && !var->arrsize)
                    {
                        /* special mode for handling char**foo=0 */
                        for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
                            len += strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
                        len *= var->offset;     /* should be 1, but YMNK */
                        len += (ntuples + 1) * sizeof(char *);
                    }
                    else
                    {
                        var->varcharsize = 0;
                        /* check strlen for each tuple */
                        for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
                        {
                            int         len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;

                            if (len > var->varcharsize)
                                var->varcharsize = len;
                        }
                        var->offset *= var->varcharsize;
                        len = var->offset * ntuples;
                    }
                    break;
                case ECPGt_varchar:
                    len = ntuples * (var->varcharsize + sizeof(int));
                    break;
                default:
                    len = var->offset * ntuples;
                    break;
            }
        }
        else
        {
            for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
                len += PQgetlength(results, act_tuple, act_field);
        }

        ecpg_log("ecpg_store_result on line %d: allocating memory for %d tuples\n", stmt->lineno, ntuples);
        var->value = (char *) ecpg_alloc(len, stmt->lineno);
        if (!var->value)
            return false;
        *((char **) var->pointer) = var->value;
        ecpg_add_mem(var->value, stmt->lineno);
    }

    /* allocate indicator variable if needed */
    if ((var->ind_arrsize == 0 || var->ind_varcharsize == 0) && var->ind_value == NULL && var->ind_pointer != NULL)
    {
        int         len = var->ind_offset * ntuples;

        var->ind_value = (char *) ecpg_alloc(len, stmt->lineno);
        if (!var->ind_value)
            return false;
        *((char **) var->ind_pointer) = var->ind_value;
        ecpg_add_mem(var->ind_value, stmt->lineno);
    }

    /* fill the variable with the tuple(s) */
    if (!var->varcharsize && !var->arrsize &&
        (var->type == ECPGt_char || var->type == ECPGt_unsigned_char || var->type == ECPGt_string))
    {
        /* special mode for handling char**foo=0 */

        /* filling the array of (char*)s */
        char      **current_string = (char **) var->value;

        /* storing the data (after the last array element) */
        char       *current_data_location = (char *) &current_string[ntuples + 1];

        for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
        {
            int         len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;

            if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
                             var->type, var->ind_type, current_data_location,
                               var->ind_value, len, 0, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
                status = false;
            else
            {
                *current_string = current_data_location;
                current_data_location += len;
                current_string++;
            }
        }

        /* terminate the list */
        *current_string = NULL;
    }
    else
    {
        for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
        {
            if (!ecpg_get_data(results, act_tuple, act_field, stmt->lineno,
                               var->type, var->ind_type, var->value,
                               var->ind_value, var->varcharsize, var->offset, var->ind_offset, isarray, stmt->compat, stmt->force_indicator))
                status = false;
        }
    }
    return status;
}

char* ecpg_strdup ( const char *  ,
int   
)

Definition at line 47 of file memory.c.

References ECPG_OUT_OF_MEMORY, ecpg_raise(), ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, and NULL.

Referenced by AddStmtToCache(), ecpg_auto_prepare(), ecpg_store_input(), ECPGconnect(), ECPGdo(), ECPGget_desc(), and prepare_common().

{
    char       *new;

    if (string == NULL)
        return NULL;

    new = strdup(string);
    if (!new)
    {
        ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
        return NULL;
    }

    return (new);
}

const char* ecpg_type_name ( enum  ECPGttype  ) 

Definition at line 18 of file typename.c.

Referenced by ecpg_get_data(), ecpg_store_input(), and ECPGdump_a_simple().

{
    switch (typ)
    {
        case ECPGt_char:
        case ECPGt_string:
            return "char";
        case ECPGt_unsigned_char:
            return "unsigned char";
        case ECPGt_short:
            return "short";
        case ECPGt_unsigned_short:
            return "unsigned short";
        case ECPGt_int:
            return "int";
        case ECPGt_unsigned_int:
            return "unsigned int";
        case ECPGt_long:
            return "long";
        case ECPGt_unsigned_long:
            return "unsigned long";
        case ECPGt_long_long:
            return "long long";
        case ECPGt_unsigned_long_long:
            return "unsigned long long";
        case ECPGt_float:
            return "float";
        case ECPGt_double:
            return "double";
        case ECPGt_bool:
            return "bool";
        case ECPGt_varchar:
            return "varchar";
        case ECPGt_char_variable:
            return "char";
        case ECPGt_decimal:
            return "decimal";
        case ECPGt_numeric:
            return "numeric";
        case ECPGt_date:
            return "date";
        case ECPGt_timestamp:
            return "timestamp";
        case ECPGt_interval:
            return "interval";
        case ECPGt_const:
            return "Const";
        default:
            abort();
    }
    return ""; /* keep MSC compiler happy */
}

struct descriptor* ecpggetdescp ( int  ,
char *   
) [read]
int sqlda_dynamic_type ( Oid  ,
enum  COMPAT_MODE 
)

Definition at line 106 of file typename.c.

References BPCHAROID, CHAROID, DATEOID, ECPGt_decimal, FLOAT4OID, FLOAT8OID, INFORMIX_MODE, INT2OID, INT4OID, INT8OID, INTERVALOID, NUMERICOID, TEXTOID, TIMESTAMPOID, TIMESTAMPTZOID, and VARCHAROID.

Referenced by ecpg_build_compat_sqlda(), ecpg_build_native_sqlda(), and sqlda_common_total_size().

{
    switch (type)
    {
        case CHAROID:
        case VARCHAROID:
        case BPCHAROID:
        case TEXTOID:
            return ECPGt_char;
        case INT2OID:
            return ECPGt_short;
        case INT4OID:
            return ECPGt_int;
        case FLOAT8OID:
            return ECPGt_double;
        case FLOAT4OID:
            return ECPGt_float;
        case NUMERICOID:
            return INFORMIX_MODE(compat) ? ECPGt_decimal : ECPGt_numeric;
        case DATEOID:
            return ECPGt_date;
        case TIMESTAMPOID:
        case TIMESTAMPTZOID:
            return ECPGt_timestamp;
        case INTERVALOID:
            return ECPGt_interval;
        case INT8OID:
#ifdef HAVE_LONG_LONG_INT_64
            return ECPGt_long_long;
#endif
#ifdef HAVE_LONG_INT_64
            return ECPGt_long;
#endif
            /* Unhandled types always return a string */
        default:
            return ECPGt_char;
    }
}


Variable Documentation

Definition at line 30 of file misc.c.

Referenced by ecpg_get_data(), ecpg_log(), ECPGconnect(), and ECPGdebug().

struct var_list* ivlist

Definition at line 504 of file misc.c.

Referenced by ecpg_finish().