Header And Logo

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

Defines | Functions | Variables

misc.c File Reference

#include "postgres_fe.h"
#include <limits.h>
#include <unistd.h>
#include "ecpg-pthread-win32.h"
#include "ecpgtype.h"
#include "ecpglib.h"
#include "ecpgerrno.h"
#include "extern.h"
#include "sqlca.h"
#include "pgtypes_numeric.h"
#include "pgtypes_date.h"
#include "pgtypes_timestamp.h"
#include "pgtypes_interval.h"
#include "pg_config_paths.h"
Include dependency graph for misc.c:

Go to the source code of this file.

Defines

#define POSTGRES_ECPG_INTERNAL

Functions

void ecpg_init_sqlca (struct sqlca_t *sqlca)
bool ecpg_init (const struct connection *con, const char *connection_name, const int lineno)
struct sqlca_tECPGget_sqlca (void)
bool ECPGstatus (int lineno, const char *connection_name)
PGTransactionStatusType ECPGtransactionStatus (const char *connection_name)
bool ECPGtrans (int lineno, const char *connection_name, const char *transaction)
void ECPGdebug (int n, FILE *dbgs)
void ecpg_log (const char *format,...)
void ECPGset_noind_null (enum ECPGttype type, void *ptr)
static bool _check (unsigned char *ptr, int length)
bool ECPGis_noind_null (enum ECPGttype type, void *ptr)
void ECPGset_var (int number, void *pointer, int lineno)
void * ECPGget_var (int number)

Variables

bool ecpg_internal_regression_mode = false
static struct sqlca_t sqlca_init
static struct sqlca_t sqlca
static int simple_debug = 0
static FILE * debugstream = NULL
struct var_listivlist = NULL

Define Documentation

#define POSTGRES_ECPG_INTERNAL

Definition at line 3 of file misc.c.


Function Documentation

static bool _check ( unsigned char *  ptr,
int  length 
) [static]

Definition at line 361 of file misc.c.

Referenced by ECPGis_noind_null().

{
    for (length--; length >= 0; length--)
        if (ptr[length] != 0xff)
            return false;

    return true;
}

bool ecpg_init ( const struct connection con,
const char *  connection_name,
const int  lineno 
)

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,
  ... 
)

Definition at line 252 of file misc.c.

References debugstream, ecpg_gettext, ecpg_internal_regression_mode, ECPGget_sqlca(), free, malloc, NULL, pthread_mutex_lock(), pthread_mutex_unlock(), simple_debug, snprintf(), sqlca_t::sqlcode, and sqlca_t::sqlstate.

{
    va_list     ap;
    struct sqlca_t *sqlca = ECPGget_sqlca();
    const char *intl_format;
    int         bufsize;
    char       *fmt;

    if (!simple_debug)
        return;

    /* internationalize the error message string */
    intl_format = ecpg_gettext(format);

    /*
     * Insert PID into the format, unless ecpg_internal_regression_mode is set
     * (regression tests want unchanging output).
     */
    bufsize = strlen(intl_format) + 100;
    fmt = (char *) malloc(bufsize);
    if (fmt == NULL)
        return;

    if (ecpg_internal_regression_mode)
        snprintf(fmt, bufsize, "[NO_PID]: %s", intl_format);
    else
        snprintf(fmt, bufsize, "[%d]: %s", (int) getpid(), intl_format);

#ifdef ENABLE_THREAD_SAFETY
    pthread_mutex_lock(&debug_mutex);
#endif

    va_start(ap, format);
    vfprintf(debugstream, fmt, ap);
    va_end(ap);

    /* dump out internal sqlca variables */
    if (ecpg_internal_regression_mode)
        fprintf(debugstream, "[NO_PID]: sqlca: code: %ld, state: %s\n",
                sqlca->sqlcode, sqlca->sqlstate);

    fflush(debugstream);

#ifdef ENABLE_THREAD_SAFETY
    pthread_mutex_unlock(&debug_mutex);
#endif

    free(fmt);
}

void ECPGdebug ( int  n,
FILE *  dbgs 
)

Definition at line 228 of file misc.c.

References debugstream, ecpg_internal_regression_mode, ecpg_log(), pthread_mutex_lock(), pthread_mutex_unlock(), and simple_debug.

{
#ifdef ENABLE_THREAD_SAFETY
    pthread_mutex_lock(&debug_init_mutex);
#endif

    if (n > 100)
    {
        ecpg_internal_regression_mode = true;
        simple_debug = n - 100;
    }
    else
        simple_debug = n;

    debugstream = dbgs;

    ecpg_log("ECPGdebug: set to %d\n", simple_debug);

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

struct sqlca_t* ECPGget_sqlca ( void   )  [read]

Definition at line 135 of file misc.c.

References ecpg_init_sqlca(), malloc, NULL, pthread_getspecific(), and pthread_setspecific().

Referenced by ecpg_execute(), ecpg_get_data(), ECPG_informix_reset_sqlca(), ecpg_init(), ecpg_log(), ecpg_raise(), ecpg_raise_backend(), ECPGallocate_desc(), ECPGconnect(), ECPGdeallocate_desc(), ECPGdisconnect(), ECPGget_desc(), ECPGget_desc_header(), ECPGnoticeReceiver(), ECPGset_var(), and sqlprint().

{
#ifdef ENABLE_THREAD_SAFETY
    struct sqlca_t *sqlca;

    pthread_once(&sqlca_key_once, ecpg_sqlca_key_init);

    sqlca = pthread_getspecific(sqlca_key);
    if (sqlca == NULL)
    {
        sqlca = malloc(sizeof(struct sqlca_t));
        ecpg_init_sqlca(sqlca);
        pthread_setspecific(sqlca_key, sqlca);
    }
    return (sqlca);
#else
    return (&sqlca);
#endif
}

void* ECPGget_var ( int  number  ) 

Definition at line 544 of file misc.c.

References var_list::next, NULL, var_list::number, and var_list::pointer.

Referenced by ECPG_informix_get_var(), get_record1(), open_cur1(), and openit().

{
    struct var_list *ptr;

    for (ptr = ivlist; ptr != NULL && ptr->number != number; ptr = ptr->next);
    return (ptr) ? ptr->pointer : NULL;
}

bool ECPGis_noind_null ( enum ECPGttype  type,
void *  ptr 
)

Definition at line 371 of file misc.c.

References _check(), ECPGgeneric_varchar::arr, ECPGt_char, ECPGt_date, ECPGt_decimal, ECPGt_double, ECPGt_float, ECPGt_int, ECPGt_interval, ECPGt_long, ECPGt_long_long, 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, NUMERIC_NULL, and sign.

Referenced by ecpg_store_input(), and risnull().

{
    switch (type)
    {
        case ECPGt_char:
        case ECPGt_unsigned_char:
        case ECPGt_string:
            if (*((char *) ptr) == '\0')
                return true;
            break;
        case ECPGt_short:
        case ECPGt_unsigned_short:
            if (*((short int *) ptr) == SHRT_MIN)
                return true;
            break;
        case ECPGt_int:
        case ECPGt_unsigned_int:
            if (*((int *) ptr) == INT_MIN)
                return true;
            break;
        case ECPGt_long:
        case ECPGt_unsigned_long:
        case ECPGt_date:
            if (*((long *) ptr) == LONG_MIN)
                return true;
            break;
#ifdef HAVE_LONG_LONG_INT
        case ECPGt_long_long:
        case ECPGt_unsigned_long_long:
            if (*((long long *) ptr) == LONG_LONG_MIN)
                return true;
            break;
#endif   /* HAVE_LONG_LONG_INT */
        case ECPGt_float:
            return (_check(ptr, sizeof(float)));
            break;
        case ECPGt_double:
            return (_check(ptr, sizeof(double)));
            break;
        case ECPGt_varchar:
            if (*(((struct ECPGgeneric_varchar *) ptr)->arr) == 0x00)
                return true;
            break;
        case ECPGt_decimal:
            if (((decimal *) ptr)->sign == NUMERIC_NULL)
                return true;
            break;
        case ECPGt_numeric:
            if (((numeric *) ptr)->sign == NUMERIC_NULL)
                return true;
            break;
        case ECPGt_interval:
            return (_check(ptr, sizeof(interval)));
            break;
        case ECPGt_timestamp:
            return (_check(ptr, sizeof(timestamp)));
            break;
        default:
            break;
    }

    return false;
}

void ECPGset_noind_null ( enum ECPGttype  type,
void *  ptr 
)

Definition at line 303 of file misc.c.

References ECPGt_char, ECPGt_date, ECPGt_decimal, ECPGt_double, ECPGt_float, ECPGt_int, ECPGt_interval, ECPGt_long, ECPGt_long_long, ECPGt_numeric, ECPGt_short, ECPGt_string, ECPGt_timestamp, ECPGt_unsigned_char, ECPGt_unsigned_int, ECPGt_unsigned_long, ECPGt_unsigned_long_long, ECPGt_unsigned_short, and ECPGt_varchar.

Referenced by ecpg_get_data(), ecpg_set_compat_sqlda(), ecpg_set_native_sqlda(), and rsetnull().

{
    switch (type)
    {
        case ECPGt_char:
        case ECPGt_unsigned_char:
        case ECPGt_string:
            *((char *) ptr) = '\0';
            break;
        case ECPGt_short:
        case ECPGt_unsigned_short:
            *((short int *) ptr) = SHRT_MIN;
            break;
        case ECPGt_int:
        case ECPGt_unsigned_int:
            *((int *) ptr) = INT_MIN;
            break;
        case ECPGt_long:
        case ECPGt_unsigned_long:
        case ECPGt_date:
            *((long *) ptr) = LONG_MIN;
            break;
#ifdef HAVE_LONG_LONG_INT
        case ECPGt_long_long:
        case ECPGt_unsigned_long_long:
            *((long long *) ptr) = LONG_LONG_MIN;
            break;
#endif   /* HAVE_LONG_LONG_INT */
        case ECPGt_float:
            memset((char *) ptr, 0xff, sizeof(float));
            break;
        case ECPGt_double:
            memset((char *) ptr, 0xff, sizeof(double));
            break;
        case ECPGt_varchar:
            *(((struct ECPGgeneric_varchar *) ptr)->arr) = 0x00;
            ((struct ECPGgeneric_varchar *) ptr)->len = 0;
            break;
        case ECPGt_decimal:
            memset((char *) ptr, 0, sizeof(decimal));
            ((decimal *) ptr)->sign = NUMERIC_NULL;
            break;
        case ECPGt_numeric:
            memset((char *) ptr, 0, sizeof(numeric));
            ((numeric *) ptr)->sign = NUMERIC_NULL;
            break;
        case ECPGt_interval:
            memset((char *) ptr, 0xff, sizeof(interval));
            break;
        case ECPGt_timestamp:
            memset((char *) ptr, 0xff, sizeof(timestamp));
            break;
        default:
            break;
    }
}

void ECPGset_var ( int  number,
void *  pointer,
int  lineno 
)

Definition at line 507 of file misc.c.

References calloc, ECPGfree_auto_mem(), ECPGget_sqlca(), var_list::next, var_list::number, var_list::pointer, snprintf(), sqlca_t::sqlcode, sqlca_t::sqlerrm, sqlca_t::sqlerrmc, sqlca_t::sqlerrml, and sqlca_t::sqlstate.

Referenced by ECPG_informix_set_var(), get_var1(), and main().

{
    struct var_list *ptr;

    for (ptr = ivlist; ptr != NULL; ptr = ptr->next)
    {
        if (ptr->number == number)
        {
            /* already known => just change pointer value */
            ptr->pointer = pointer;
            return;
        }
    }

    /* a new one has to be added */
    ptr = (struct var_list *) calloc(1L, sizeof(struct var_list));
    if (!ptr)
    {
        struct sqlca_t *sqlca = ECPGget_sqlca();

        sqlca->sqlcode = ECPG_OUT_OF_MEMORY;
        strncpy(sqlca->sqlstate, "YE001", sizeof(sqlca->sqlstate));
        snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), "out of memory on line %d", lineno);
        sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc);
        /* free all memory we have allocated for the user */
        ECPGfree_auto_mem();
    }
    else
    {
        ptr->number = number;
        ptr->pointer = pointer;
        ptr->next = ivlist;
        ivlist = ptr;
    }
}

bool ECPGstatus ( int  lineno,
const char *  connection_name 
)

Definition at line 156 of file misc.c.

References connection::connection, ecpg_get_connection(), ecpg_init(), ECPG_NOT_CONN, ecpg_raise(), ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, connection::name, and NULL.

{
    struct connection *con = ecpg_get_connection(connection_name);

    if (!ecpg_init(con, connection_name, lineno))
        return (false);

    /* are we connected? */
    if (con->connection == NULL)
    {
        ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, con->name);
        return false;
    }

    return (true);
}

bool ECPGtrans ( int  lineno,
const char *  connection_name,
const char *  transaction 
)

Definition at line 190 of file misc.c.

References connection::autocommit, connection::connection, ecpg_check_PQresult(), ECPG_COMPAT_PGSQL, ecpg_get_connection(), ecpg_init(), ecpg_log(), connection::name, PQclear(), PQexec(), PQTRANS_IDLE, and PQtransactionStatus().

Referenced by main(), and sql_check().

{
    PGresult   *res;
    struct connection *con = ecpg_get_connection(connection_name);

    if (!ecpg_init(con, connection_name, lineno))
        return (false);

    ecpg_log("ECPGtrans on line %d: action \"%s\"; connection \"%s\"\n", lineno, transaction, con ? con->name : "null");

    /* if we have no connection we just simulate the command */
    if (con && con->connection)
    {
        /*
         * If we got a transaction command but have no open transaction, we
         * have to start one, unless we are in autocommit, where the
         * developers have to take care themselves. However, if the command is
         * a begin statement, we just execute it once.
         */
        if (PQtransactionStatus(con->connection) == PQTRANS_IDLE && !con->autocommit && strncmp(transaction, "begin", 5) != 0 && strncmp(transaction, "start", 5) != 0)
        {
            res = PQexec(con->connection, "begin transaction");
            if (!ecpg_check_PQresult(res, lineno, con->connection, ECPG_COMPAT_PGSQL))
                return FALSE;
            PQclear(res);
        }

        res = PQexec(con->connection, transaction);
        if (!ecpg_check_PQresult(res, lineno, con->connection, ECPG_COMPAT_PGSQL))
            return FALSE;
        PQclear(res);
    }

    return true;
}

PGTransactionStatusType ECPGtransactionStatus ( const char *  connection_name  ) 

Definition at line 174 of file misc.c.

References connection::connection, ecpg_get_connection(), NULL, and PQtransactionStatus().

{
    const struct connection *con;

    con = ecpg_get_connection(connection_name);
    if (con == NULL)
    {
        /* transaction status is unknown */
        return PQTRANS_UNKNOWN;
    }

    return PQtransactionStatus(con->connection);

}


Variable Documentation

FILE* debugstream = NULL [static]

Definition at line 96 of file misc.c.

Referenced by ecpg_log(), and ECPGdebug().

Definition at line 30 of file misc.c.

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

struct var_list* ivlist = NULL

Definition at line 504 of file misc.c.

Referenced by ecpg_finish().

int simple_debug = 0 [static]

Definition at line 95 of file misc.c.

Referenced by ecpg_log(), and ECPGdebug().

struct sqlca_t sqlca [static]
Initial value:
{
    {
        'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
    },
    sizeof(struct sqlca_t),
    0,
    {
        0,
        {
            0
        }
    },
    {
        'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
    },
    {
        0, 0, 0, 0, 0, 0
    },
    {
        0, 0, 0, 0, 0, 0, 0, 0
    },
    {
        '0', '0', '0', '0', '0'
    }
}

Definition at line 63 of file misc.c.

struct sqlca_t sqlca_init [static]
Initial value:
{
    {
        'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
    },
    sizeof(struct sqlca_t),
    0,
    {
        0,
        {
            0
        }
    },
    {
        'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
    },
    {
        0, 0, 0, 0, 0, 0
    },
    {
        0, 0, 0, 0, 0, 0, 0, 0
    },
    {
        '0', '0', '0', '0', '0'
    }
}

Definition at line 32 of file misc.c.