Header And Logo

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

Defines | Functions

ecpglib.h File Reference

#include "libpq-fe.h"
#include "ecpgtype.h"
#include "sqlca.h"
#include <string.h>
Include dependency graph for ecpglib.h:

Go to the source code of this file.

Defines

#define ecpg_gettext(x)   (x)
#define bool   char
#define true   ((bool) 1)
#define false   ((bool) 0)
#define TRUE   1
#define FALSE   0
#define SQLCODE   sqlca.sqlcode
#define SQLSTATE   sqlca.sqlstate

Functions

void ECPGdebug (int, FILE *)
bool ECPGstatus (int, const char *)
bool ECPGsetcommit (int, const char *, const char *)
bool ECPGsetconn (int, const char *)
bool ECPGconnect (int, int, const char *, const char *, const char *, const char *, int)
bool ECPGdo (const int, const int, const int, const char *, const bool, const int, const char *,...)
bool ECPGtrans (int, const char *, const char *)
bool ECPGdisconnect (int, const char *)
bool ECPGprepare (int, const char *, const bool, const char *, const char *)
bool ECPGdeallocate (int, int, const char *, const char *)
bool ECPGdeallocate_all (int, int, const char *)
char * ECPGprepared_statement (const char *, const char *, int)
PGconnECPGget_PGconn (const char *)
PGTransactionStatusType ECPGtransactionStatus (const char *)
char * ECPGerrmsg (void)
void sqlprint (void)
bool ECPGdo_descriptor (int, const char *, const char *, const char *)
bool ECPGdeallocate_desc (int, const char *)
bool ECPGallocate_desc (int, const char *)
bool ECPGget_desc_header (int, const char *, int *)
bool ECPGget_desc (int, const char *, int,...)
bool ECPGset_desc_header (int, const char *, int)
bool ECPGset_desc (int, const char *, int,...)
void ECPGset_noind_null (enum ECPGttype, void *)
bool ECPGis_noind_null (enum ECPGttype, void *)
bool ECPGdescribe (int, int, bool, const char *, const char *,...)
void ECPGset_var (int, void *, int)
void * ECPGget_var (int number)
void ECPGfree_auto_mem (void)

Define Documentation

#define bool   char

Definition at line 25 of file ecpglib.h.

#define ecpg_gettext (   x  )     (x)
#define false   ((bool) 0)

Definition at line 32 of file ecpglib.h.

#define FALSE   0

Definition at line 41 of file ecpglib.h.

#define SQLCODE   sqlca.sqlcode

Definition at line 71 of file ecpglib.h.

Referenced by sql_check().

#define SQLSTATE   sqlca.sqlstate

Definition at line 72 of file ecpglib.h.

#define true   ((bool) 1)

Definition at line 29 of file ecpglib.h.

#define TRUE   1

Definition at line 37 of file ecpglib.h.


Function Documentation

bool ECPGallocate_desc ( int  ,
const char *   
)

Definition at line 740 of file descriptor.c.

References ecpg_alloc(), ecpg_free(), ecpg_init_sqlca(), ECPG_OUT_OF_MEMORY, ecpg_raise(), ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, ECPGget_sqlca(), get_descriptors, NULL, PQmakeEmptyPGresult(), set_descriptors, and sqlca.

Referenced by fn(), and main().

{
    struct descriptor *new;
    struct sqlca_t *sqlca = ECPGget_sqlca();

    ecpg_init_sqlca(sqlca);
    new = (struct descriptor *) ecpg_alloc(sizeof(struct descriptor), line);
    if (!new)
        return false;
    new->next = get_descriptors();
    new->name = ecpg_alloc(strlen(name) + 1, line);
    if (!new->name)
    {
        ecpg_free(new);
        return false;
    }
    new->count = -1;
    new->items = NULL;
    new->result = PQmakeEmptyPGresult(NULL, 0);
    if (!new->result)
    {
        ecpg_free(new->name);
        ecpg_free(new);
        ecpg_raise(line, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
        return false;
    }
    strcpy(new->name, name);
    set_descriptors(new);
    return true;
}

bool ECPGconnect ( int  ,
int  ,
const char *  ,
const char *  ,
const char *  ,
const char *  ,
int   
)

Definition at line 265 of file connect.c.

References connection::cache_head, compat, CONNECTION_BAD, ecpg_alloc(), ecpg_clear_auto_mem(), ECPG_CONNECT, ecpg_finish(), ecpg_free(), ecpg_get_connection(), ecpg_gettext, ecpg_init_sqlca(), ecpg_internal_regression_mode, ecpg_log(), ecpg_raise(), ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, ecpg_strdup(), ECPGget_sqlca(), ECPGnoticeReceiver(), errmsg(), free, i, INFORMIX_MODE, last_dir_separator(), next(), NULL, port, PQconnectdbParams(), PQerrorMessage(), PQsetNoticeReceiver(), PQstatus(), connection::prep_stmts, pthread_mutex_lock(), pthread_mutex_unlock(), pthread_setspecific(), and sqlca.

Referenced by main(), and test().

{
    struct sqlca_t *sqlca = ECPGget_sqlca();
    enum COMPAT_MODE compat = c;
    struct connection *this;
    int         i,
                connect_params = 0;
    char       *dbname = name ? ecpg_strdup(name, lineno) : NULL,
               *host = NULL,
               *tmp,
               *port = NULL,
               *realname = NULL,
               *options = NULL;
    const char **conn_keywords;
    const char **conn_values;

    ecpg_init_sqlca(sqlca);

    /*
     * clear auto_mem structure because some error handling functions might
     * access it
     */
    ecpg_clear_auto_mem();

    if (INFORMIX_MODE(compat))
    {
        char       *envname;

        /*
         * Informix uses an environment variable DBPATH that overrides the
         * connection parameters given here. We do the same with PG_DBPATH as
         * the syntax is different.
         */
        envname = getenv("PG_DBPATH");
        if (envname)
        {
            ecpg_free(dbname);
            dbname = ecpg_strdup(envname, lineno);
        }

    }

    if (dbname == NULL && connection_name == NULL)
        connection_name = "DEFAULT";

#if ENABLE_THREAD_SAFETY
    ecpg_pthreads_init();
#endif

    /* check if the identifier is unique */
    if (ecpg_get_connection(connection_name))
    {
        ecpg_free(dbname);
        ecpg_log("ECPGconnect: connection identifier %s is already in use\n",
                 connection_name);
        return false;
    }

    if ((this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno)) == NULL)
        return false;

    if (dbname != NULL)
    {
        /* get the detail information out of dbname */
        if (strncmp(dbname, "tcp:", 4) == 0 || strncmp(dbname, "unix:", 5) == 0)
        {
            int         offset = 0;

            /*
             * only allow protocols tcp and unix
             */
            if (strncmp(dbname, "tcp:", 4) == 0)
                offset = 4;
            else if (strncmp(dbname, "unix:", 5) == 0)
                offset = 5;

            if (strncmp(dbname + offset, "postgresql://", strlen("postgresql://")) == 0)
            {

                /*------
                 * new style:
                 *  <tcp|unix>:postgresql://server[:port|:/unixsocket/path:]
                 *  [/db name][?options]
                 *------
                 */
                offset += strlen("postgresql://");

                tmp = strrchr(dbname + offset, '?');
                if (tmp != NULL)    /* options given */
                {
                    options = ecpg_strdup(tmp + 1, lineno);
                    *tmp = '\0';
                }

                tmp = last_dir_separator(dbname + offset);
                if (tmp != NULL)    /* database name given */
                {
                    if (tmp[1] != '\0') /* non-empty database name */
                    {
                        realname = ecpg_strdup(tmp + 1, lineno);
                        connect_params++;
                    }
                    *tmp = '\0';
                }

                tmp = strrchr(dbname + offset, ':');
                if (tmp != NULL)    /* port number or Unix socket path given */
                {
                    char       *tmp2;

                    *tmp = '\0';
                    if ((tmp2 = strchr(tmp + 1, ':')) != NULL)
                    {
                        *tmp2 = '\0';
                        host = ecpg_strdup(tmp + 1, lineno);
                        connect_params++;
                        if (strncmp(dbname, "unix:", 5) != 0)
                        {
                            ecpg_log("ECPGconnect: socketname %s given for TCP connection on line %d\n", host, lineno);
                            ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : ecpg_gettext("<DEFAULT>"));
                            if (host)
                                ecpg_free(host);

                            /*
                             * port not set yet if (port) ecpg_free(port);
                             */
                            if (options)
                                ecpg_free(options);
                            if (realname)
                                ecpg_free(realname);
                            if (dbname)
                                ecpg_free(dbname);
                            free(this);
                            return false;
                        }
                    }
                    else
                    {
                        port = ecpg_strdup(tmp + 1, lineno);
                        connect_params++;
                    }
                }

                if (strncmp(dbname, "unix:", 5) == 0)
                {
                    if (strcmp(dbname + offset, "localhost") != 0 && strcmp(dbname + offset, "127.0.0.1") != 0)
                    {
                        ecpg_log("ECPGconnect: non-localhost access via sockets on line %d\n", lineno);
                        ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, realname ? realname : ecpg_gettext("<DEFAULT>"));
                        if (host)
                            ecpg_free(host);
                        if (port)
                            ecpg_free(port);
                        if (options)
                            ecpg_free(options);
                        if (realname)
                            ecpg_free(realname);
                        if (dbname)
                            ecpg_free(dbname);
                        free(this);
                        return false;
                    }
                }
                else
                {
                    host = ecpg_strdup(dbname + offset, lineno);
                    connect_params++;
                }

            }
        }
        else
        {
            /* old style: dbname[@server][:port] */
            tmp = strrchr(dbname, ':');
            if (tmp != NULL)    /* port number given */
            {
                port = ecpg_strdup(tmp + 1, lineno);
                connect_params++;
                *tmp = '\0';
            }

            tmp = strrchr(dbname, '@');
            if (tmp != NULL)    /* host name given */
            {
                host = ecpg_strdup(tmp + 1, lineno);
                connect_params++;
                *tmp = '\0';
            }

            if (strlen(dbname) > 0)
            {
                realname = ecpg_strdup(dbname, lineno);
                connect_params++;
            }
            else
                realname = NULL;
        }
    }
    else
        realname = NULL;

    /* add connection to our list */
#ifdef ENABLE_THREAD_SAFETY
    pthread_mutex_lock(&connections_mutex);
#endif
    if (connection_name != NULL)
        this->name = ecpg_strdup(connection_name, lineno);
    else
        this->name = ecpg_strdup(realname, lineno);

    this->cache_head = NULL;
    this->prep_stmts = NULL;

    if (all_connections == NULL)
        this->next = NULL;
    else
        this->next = all_connections;

    all_connections = this;
#ifdef ENABLE_THREAD_SAFETY
    pthread_setspecific(actual_connection_key, all_connections);
#endif
    actual_connection = all_connections;

    ecpg_log("ECPGconnect: opening database %s on %s port %s %s%s %s%s\n",
             realname ? realname : "<DEFAULT>",
             host ? host : "<DEFAULT>",
             port ? (ecpg_internal_regression_mode ? "<REGRESSION_PORT>" : port) : "<DEFAULT>",
             options ? "with options " : "", options ? options : "",
             (user && strlen(user) > 0) ? "for user " : "", user ? user : "");

    if (options)
        for (i = 0; options[i]; i++)
            /* count options */
            if (options[i] == '=')
                connect_params++;

    if (user && strlen(user) > 0)
        connect_params++;
    if (passwd && strlen(passwd) > 0)
        connect_params++;

    /* allocate enough space for all connection parameters */
    conn_keywords = (const char **) ecpg_alloc((connect_params + 1) * sizeof(char *), lineno);
    conn_values = (const char **) ecpg_alloc(connect_params * sizeof(char *), lineno);
    if (conn_keywords == NULL || conn_values == NULL)
    {
        if (host)
            ecpg_free(host);
        if (port)
            ecpg_free(port);
        if (options)
            ecpg_free(options);
        if (realname)
            ecpg_free(realname);
        if (dbname)
            ecpg_free(dbname);
        if (conn_keywords)
            ecpg_free(conn_keywords);
        if (conn_values)
            ecpg_free(conn_values);
        free(this);
        return false;
    }

    i = 0;
    if (realname)
    {
        conn_keywords[i] = "dbname";
        conn_values[i] = realname;
        i++;
    }
    if (host)
    {
        conn_keywords[i] = "host";
        conn_values[i] = host;
        i++;
    }
    if (port)
    {
        conn_keywords[i] = "port";
        conn_values[i] = port;
        i++;
    }
    if (user && strlen(user) > 0)
    {
        conn_keywords[i] = "user";
        conn_values[i] = user;
        i++;
    }
    if (passwd && strlen(passwd) > 0)
    {
        conn_keywords[i] = "password";
        conn_values[i] = passwd;
        i++;
    }
    if (options)
    {
        char       *str;

        /* options look like this "option1 = value1 option2 = value2 ... */
        /* we have to break up the string into single options */
        for (str = options; *str;)
        {
            int         e,
                        a;
            char       *token1,
                       *token2;

            for (token1 = str; *token1 && *token1 == ' '; token1++);
            for (e = 0; token1[e] && token1[e] != '='; e++);
            if (token1[e])      /* found "=" */
            {
                token1[e] = '\0';
                for (token2 = token1 + e + 1; *token2 && *token2 == ' '; token2++);
                for (a = 0; token2[a] && token2[a] != '&'; a++);
                if (token2[a])  /* found "&" => another option follows */
                {
                    token2[a] = '\0';
                    str = token2 + a + 1;
                }
                else
                    str = token2 + a;

                conn_keywords[i] = token1;
                conn_values[i] = token2;
                i++;
            }
            else
                /* the parser should not be able to create this invalid option */
                str = token1 + e;
        }

    }
    conn_keywords[i] = NULL;    /* terminator */

    this->connection = PQconnectdbParams(conn_keywords, conn_values, 0);

    if (host)
        ecpg_free(host);
    if (port)
        ecpg_free(port);
    if (options)
        ecpg_free(options);
    if (dbname)
        ecpg_free(dbname);
    ecpg_free(conn_values);
    ecpg_free(conn_keywords);

    if (PQstatus(this->connection) == CONNECTION_BAD)
    {
        const char *errmsg = PQerrorMessage(this->connection);
        const char *db = realname ? realname : ecpg_gettext("<DEFAULT>");

        ecpg_log("ECPGconnect: could not open database: %s\n", errmsg);

        ecpg_finish(this);
#ifdef ENABLE_THREAD_SAFETY
        pthread_mutex_unlock(&connections_mutex);
#endif

        ecpg_raise(lineno, ECPG_CONNECT, ECPG_SQLSTATE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION, db);
        if (realname)
            ecpg_free(realname);

        return false;
    }

    if (realname)
        ecpg_free(realname);

#ifdef ENABLE_THREAD_SAFETY
    pthread_mutex_unlock(&connections_mutex);
#endif

    this->autocommit = autocommit;

    PQsetNoticeReceiver(this->connection, &ECPGnoticeReceiver, (void *) this);

    return true;
}

bool ECPGdeallocate ( int  ,
int  ,
const char *  ,
const char *   
)

Definition at line 253 of file prepare.c.

References deallocate_one(), ecpg_find_prepared_statement(), ecpg_get_connection(), ecpg_init(), ECPG_INVALID_STMT, ecpg_raise(), ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, and INFORMIX_MODE.

Referenced by main().

{
    struct connection *con;
    struct prepared_statement *this,
               *prev;

    con = ecpg_get_connection(connection_name);

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

    this = ecpg_find_prepared_statement(name, con, &prev);
    if (this)
        return deallocate_one(lineno, c, con, prev, this);

    /* prepared statement is not found */
    if (INFORMIX_MODE(c))
        return true;
    ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, name);
    return false;
}

bool ECPGdeallocate_all ( int  ,
int  ,
const char *   
)

Definition at line 289 of file prepare.c.

References ecpg_deallocate_all_conn(), and ecpg_get_connection().

Referenced by main().

{
    return ecpg_deallocate_all_conn(lineno, compat, ecpg_get_connection(connection_name));
}

bool ECPGdeallocate_desc ( int  ,
const char *   
)

Definition at line 700 of file descriptor.c.

References descriptor_free(), ecpg_init_sqlca(), ecpg_raise(), ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, ECPG_UNKNOWN_DESCRIPTOR, ECPGget_sqlca(), get_descriptors, descriptor::next, NULL, set_descriptors, and sqlca.

Referenced by fn(), and main().

{
    struct descriptor *desc;
    struct descriptor *prev;
    struct sqlca_t *sqlca = ECPGget_sqlca();

    ecpg_init_sqlca(sqlca);
    for (desc = get_descriptors(), prev = NULL; desc; prev = desc, desc = desc->next)
    {
        if (strcmp(name, desc->name) == 0)
        {
            if (prev)
                prev->next = desc->next;
            else
                set_descriptors(desc->next);
            descriptor_free(desc);
            return true;
        }
    }
    ecpg_raise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, name);
    return false;
}

void ECPGdebug ( int  ,
FILE *   
)

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
}

bool ECPGdescribe ( int  ,
int  ,
bool  ,
const char *  ,
const char *  ,
  ... 
)

Definition at line 788 of file descriptor.c.

References connection::connection, sqlda_struct::desc_next, sqlda_compat::desc_next, ecpg_build_compat_sqlda(), ecpg_build_native_sqlda(), ecpg_check_PQresult(), ecpg_find_desc(), ecpg_find_prepared_statement(), ecpg_get_connection(), ecpg_gettext, ECPG_INVALID_STMT, ECPG_NO_CONN, ecpg_raise(), ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, ECPG_UNSUPPORTED, ECPGt_descriptor, ECPGt_EORT, ECPGt_sqlda, free, INFORMIX_MODE, name, NULL, PQclear(), PQdescribePrepared(), and descriptor::result.

Referenced by main().

{
    bool        ret = false;
    struct connection *con;
    struct prepared_statement *prep;
    PGresult   *res;
    va_list     args;

    /* DESCRIBE INPUT is not yet supported */
    if (input)
    {
        ecpg_raise(line, ECPG_UNSUPPORTED, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, "DESCRIBE INPUT");
        return ret;
    }

    con = ecpg_get_connection(connection_name);
    if (!con)
    {
        ecpg_raise(line, ECPG_NO_CONN, ECPG_SQLSTATE_CONNECTION_DOES_NOT_EXIST,
                   connection_name ? connection_name : ecpg_gettext("NULL"));
        return ret;
    }
    prep = ecpg_find_prepared_statement(stmt_name, con, NULL);
    if (!prep)
    {
        ecpg_raise(line, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt_name);
        return ret;
    }

    va_start(args, stmt_name);

    for (;;)
    {
        enum ECPGttype type;
        void       *ptr;

        /* variable type */
        type = va_arg(args, enum ECPGttype);

        if (type == ECPGt_EORT)
            break;

        /* rest of variable parameters */
        ptr = va_arg(args, void *);
        (void) va_arg(args, long);      /* skip args */
        (void) va_arg(args, long);
        (void) va_arg(args, long);

        /* variable indicator */
        (void) va_arg(args, enum ECPGttype);
        (void) va_arg(args, void *);    /* skip args */
        (void) va_arg(args, long);
        (void) va_arg(args, long);
        (void) va_arg(args, long);

        switch (type)
        {
            case ECPGt_descriptor:
                {
                    char       *name = ptr;
                    struct descriptor *desc = ecpg_find_desc(line, name);

                    if (desc == NULL)
                        break;

                    res = PQdescribePrepared(con->connection, stmt_name);
                    if (!ecpg_check_PQresult(res, line, con->connection, compat))
                        break;

                    if (desc->result != NULL)
                        PQclear(desc->result);

                    desc->result = res;
                    ret = true;
                    break;
                }
            case ECPGt_sqlda:
                {
                    if (INFORMIX_MODE(compat))
                    {
                        struct sqlda_compat **_sqlda = ptr;
                        struct sqlda_compat *sqlda;

                        res = PQdescribePrepared(con->connection, stmt_name);
                        if (!ecpg_check_PQresult(res, line, con->connection, compat))
                            break;

                        sqlda = ecpg_build_compat_sqlda(line, res, -1, compat);
                        if (sqlda)
                        {
                            struct sqlda_compat *sqlda_old = *_sqlda;
                            struct sqlda_compat *sqlda_old1;

                            while (sqlda_old)
                            {
                                sqlda_old1 = sqlda_old->desc_next;
                                free(sqlda_old);
                                sqlda_old = sqlda_old1;
                            }

                            *_sqlda = sqlda;
                            ret = true;
                        }

                        PQclear(res);
                    }
                    else
                    {
                        struct sqlda_struct **_sqlda = ptr;
                        struct sqlda_struct *sqlda;

                        res = PQdescribePrepared(con->connection, stmt_name);
                        if (!ecpg_check_PQresult(res, line, con->connection, compat))
                            break;

                        sqlda = ecpg_build_native_sqlda(line, res, -1, compat);
                        if (sqlda)
                        {
                            struct sqlda_struct *sqlda_old = *_sqlda;
                            struct sqlda_struct *sqlda_old1;

                            while (sqlda_old)
                            {
                                sqlda_old1 = sqlda_old->desc_next;
                                free(sqlda_old);
                                sqlda_old = sqlda_old1;
                            }

                            *_sqlda = sqlda;
                            ret = true;
                        }

                        PQclear(res);
                    }
                    break;
                }
            default:
                /* nothing else may come */
                ;
        }
    }

    va_end(args);

    return ret;
}

bool ECPGdisconnect ( int  ,
const char *   
)

Definition at line 649 of file connect.c.

References ecpg_finish(), ecpg_get_connection_nr(), ecpg_init(), ecpg_init_sqlca(), ECPGget_sqlca(), connection::next, pthread_mutex_lock(), pthread_mutex_unlock(), and sqlca.

Referenced by main(), and test().

{
    struct sqlca_t *sqlca = ECPGget_sqlca();
    struct connection *con;

#ifdef ENABLE_THREAD_SAFETY
    pthread_mutex_lock(&connections_mutex);
#endif

    if (strcmp(connection_name, "ALL") == 0)
    {
        ecpg_init_sqlca(sqlca);
        for (con = all_connections; con;)
        {
            struct connection *f = con;

            con = con->next;
            ecpg_finish(f);
        }
    }
    else
    {
        con = ecpg_get_connection_nr(connection_name);

        if (!ecpg_init(con, connection_name, lineno))
        {
#ifdef ENABLE_THREAD_SAFETY
            pthread_mutex_unlock(&connections_mutex);
#endif
            return (false);
        }
        else
            ecpg_finish(con);
    }

#ifdef ENABLE_THREAD_SAFETY
    pthread_mutex_unlock(&connections_mutex);
#endif

    return true;
}

bool ECPGdo ( const   int,
const   int,
const   int,
const char *  ,
const   bool,
const   int,
const char *  ,
  ... 
)

Definition at line 1710 of file execute.c.

References variable::arrsize, statement::command, statement::compat, connection::connection, statement::connection, ecpg_alloc(), ecpg_auto_prepare(), ecpg_clear_auto_mem(), ECPG_EMPTY, ecpg_execute(), ecpg_free(), ecpg_get_connection(), ecpg_gettext, ecpg_init(), ECPG_INVALID_STMT, ECPG_NOT_CONN, ecpg_prepared(), ecpg_raise(), ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, ecpg_strdup(), ECPGst_execute, ECPGst_prepnormal, ECPGt_EOIT, ECPGt_EORT, ECPGt_NO_INDICATOR, statement::force_indicator, free_statement(), variable::ind_arrsize, variable::ind_offset, variable::ind_pointer, variable::ind_type, variable::ind_value, variable::ind_varcharsize, statement::inlist, statement::lineno, sort-test::list, connection::name, statement::name, variable::next, NULL, variable::offset, statement::outlist, variable::pointer, statement::questionmarks, statement::statement_type, variable::type, variable::value, and variable::varcharsize.

Referenced by close_cur1(), ECPGdo_descriptor(), get_record1(), main(), open_cur1(), openit(), and test().

{
    va_list     args;
    struct statement *stmt;
    struct connection *con;
    bool        status;
    char       *oldlocale;
    enum ECPGttype type;
    struct variable **list;
    enum ECPG_statement_type statement_type = (enum ECPG_statement_type) st;
    char       *prepname;

    if (!query)
    {
        ecpg_raise(lineno, ECPG_EMPTY, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, NULL);
        return (false);
    }

    /* Make sure we do NOT honor the locale for numeric input/output */
    /* since the database wants the standard decimal point */
    oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
    setlocale(LC_NUMERIC, "C");

#ifdef ENABLE_THREAD_SAFETY
    ecpg_pthreads_init();
#endif

    con = ecpg_get_connection(connection_name);

    if (!ecpg_init(con, connection_name, lineno))
    {
        setlocale(LC_NUMERIC, oldlocale);
        ecpg_free(oldlocale);
        return (false);
    }

    /* construct statement in our own structure */
    va_start(args, query);

    /*
     * create a list of variables The variables are listed with input
     * variables preceding outputvariables The end of each group is marked by
     * an end marker. per variable we list: type - as defined in ecpgtype.h
     * value - where to store the data varcharsize - length of string in case
     * we have a stringvariable, else 0 arraysize - 0 for pointer (we don't
     * know the size of the array), 1 for simple variable, size for arrays
     * offset - offset between ith and (i+1)th entry in an array, normally
     * that means sizeof(type) ind_type - type of indicator variable ind_value
     * - pointer to indicator variable ind_varcharsize - empty ind_arraysize -
     * arraysize of indicator array ind_offset - indicator offset
     */
    if (!(stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
    {
        setlocale(LC_NUMERIC, oldlocale);
        ecpg_free(oldlocale);
        va_end(args);
        return false;
    }

    /*
     * If statement type is ECPGst_prepnormal we are supposed to prepare the
     * statement before executing them
     */
    if (statement_type == ECPGst_prepnormal)
    {
        if (!ecpg_auto_prepare(lineno, connection_name, compat, &prepname, query))
        {
            setlocale(LC_NUMERIC, oldlocale);
            ecpg_free(oldlocale);
            free_statement(stmt);
            va_end(args);
            return (false);
        }

        /*
         * statement is now prepared, so instead of the query we have to
         * execute the name
         */
        stmt->command = prepname;
        statement_type = ECPGst_execute;
    }
    else
        stmt->command = ecpg_strdup(query, lineno);

    stmt->name = NULL;

    if (statement_type == ECPGst_execute)
    {
        /* if we have an EXECUTE command, only the name is send */
        char       *command = ecpg_prepared(stmt->command, con);

        if (command)
        {
            stmt->name = stmt->command;
            stmt->command = ecpg_strdup(command, lineno);
        }
        else
        {
            ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, stmt->command);
            setlocale(LC_NUMERIC, oldlocale);
            ecpg_free(oldlocale);
            free_statement(stmt);
            va_end(args);
            return (false);
        }
    }

    stmt->connection = con;
    stmt->lineno = lineno;
    stmt->compat = compat;
    stmt->force_indicator = force_indicator;
    stmt->questionmarks = questionmarks;
    stmt->statement_type = statement_type;

    list = &(stmt->inlist);

    type = va_arg(args, enum ECPGttype);

    while (type != ECPGt_EORT)
    {
        if (type == ECPGt_EOIT)
            list = &(stmt->outlist);
        else
        {
            struct variable *var,
                       *ptr;

            if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
            {
                setlocale(LC_NUMERIC, oldlocale);
                ecpg_free(oldlocale);
                free_statement(stmt);
                va_end(args);
                return false;
            }

            var->type = type;
            var->pointer = va_arg(args, char *);

            var->varcharsize = va_arg(args, long);
            var->arrsize = va_arg(args, long);
            var->offset = va_arg(args, long);

            if (var->arrsize == 0 || var->varcharsize == 0)
                var->value = *((char **) (var->pointer));
            else
                var->value = var->pointer;

            /*
             * negative values are used to indicate an array without given
             * bounds
             */
            /* reset to zero for us */
            if (var->arrsize < 0)
                var->arrsize = 0;
            if (var->varcharsize < 0)
                var->varcharsize = 0;

            var->next = NULL;

            var->ind_type = va_arg(args, enum ECPGttype);
            var->ind_pointer = va_arg(args, char *);
            var->ind_varcharsize = va_arg(args, long);
            var->ind_arrsize = va_arg(args, long);
            var->ind_offset = va_arg(args, long);

            if (var->ind_type != ECPGt_NO_INDICATOR
                && (var->ind_arrsize == 0 || var->ind_varcharsize == 0))
                var->ind_value = *((char **) (var->ind_pointer));
            else
                var->ind_value = var->ind_pointer;

            /*
             * negative values are used to indicate an array without given
             * bounds
             */
            /* reset to zero for us */
            if (var->ind_arrsize < 0)
                var->ind_arrsize = 0;
            if (var->ind_varcharsize < 0)
                var->ind_varcharsize = 0;

            /* if variable is NULL, the statement hasn't been prepared */
            if (var->pointer == NULL)
            {
                ecpg_raise(lineno, ECPG_INVALID_STMT, ECPG_SQLSTATE_INVALID_SQL_STATEMENT_NAME, NULL);
                ecpg_free(var);
                setlocale(LC_NUMERIC, oldlocale);
                ecpg_free(oldlocale);
                free_statement(stmt);
                va_end(args);
                return false;
            }

            for (ptr = *list; ptr && ptr->next; ptr = ptr->next);

            if (ptr == NULL)
                *list = var;
            else
                ptr->next = var;
        }

        type = va_arg(args, enum ECPGttype);
    }

    va_end(args);

    /* are we connected? */
    if (con == NULL || con->connection == NULL)
    {
        free_statement(stmt);
        ecpg_raise(lineno, ECPG_NOT_CONN, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
        setlocale(LC_NUMERIC, oldlocale);
        ecpg_free(oldlocale);
        return false;
    }

    /* initialize auto_mem struct */
    ecpg_clear_auto_mem();

    status = ecpg_execute(stmt);
    free_statement(stmt);

    /* and reset locale value so our application is not affected */
    setlocale(LC_NUMERIC, oldlocale);
    ecpg_free(oldlocale);

    return (status);
}

bool ECPGdo_descriptor ( int  ,
const char *  ,
const char *  ,
const char *   
)

Definition at line 1942 of file execute.c.

References ECPG_COMPAT_PGSQL, ECPGdo(), ECPGt_descriptor, ECPGt_EOIT, ECPGt_EORT, ECPGt_NO_INDICATOR, and NULL.

{
    return ECPGdo(line, ECPG_COMPAT_PGSQL, true, connection, '\0', 0, query, ECPGt_EOIT,
                  ECPGt_descriptor, descriptor, 0L, 0L, 0L,
                  ECPGt_NO_INDICATOR, NULL, 0L, 0L, 0L, ECPGt_EORT);
}

char* ECPGerrmsg ( void   ) 
void ECPGfree_auto_mem ( void   ) 

Definition at line 118 of file memory.c.

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

Referenced by ecpg_raise(), ecpg_raise_backend(), ECPGset_var(), and main().

{
    struct auto_mem *am = get_auto_allocs();

    /* free all memory we have allocated for the user */
    if (am)
    {
        do
        {
            struct auto_mem *act = am;

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

bool ECPGget_desc ( int  ,
const char *  ,
int  ,
  ... 
)

Definition at line 238 of file descriptor.c.

References variable::arrsize, statement::connection, ecpg_add_mem(), ecpg_alloc(), ecpg_dynamic_type(), ecpg_dynamic_type_DDT(), ecpg_free(), ecpg_get_connection(), ecpg_init_sqlca(), ECPG_INVALID_DESCRIPTOR_INDEX, ecpg_log(), ecpg_raise(), ecpg_result_by_descriptor(), ECPG_SQLSTATE_CARDINALITY_VIOLATION, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ECPG_SQLSTATE_INVALID_DESCRIPTOR_INDEX, ecpg_store_result(), ecpg_strdup(), ECPG_TOO_MANY_MATCHES, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPGd_cardinality, ECPGd_data, ECPGd_di_code, ECPGd_EODT, ECPGd_indicator, ECPGd_key_member, ECPGd_length, ECPGd_name, ECPGd_nullable, ECPGd_octet, ECPGd_precision, ECPGd_ret_length, ECPGd_ret_octet, ECPGd_scale, ECPGd_type, ECPGget_sqlca(), ECPGt_EORT, ECPGt_NO_INDICATOR, get_char_item(), get_int_item(), variable::ind_arrsize, variable::ind_offset, variable::ind_pointer, variable::ind_type, variable::ind_value, variable::ind_varcharsize, statement::lineno, NULL, variable::offset, variable::pointer, PQfmod(), PQfname(), PQfsize(), PQftype(), PQgetisnull(), PQgetlength(), PQnfields(), PQntuples(), snprintf(), sqlca, sqlca_t::sqlerrd, variable::type, variable::value, variable::varcharsize, and VARHDRSZ.

Referenced by main().

{
    va_list     args;
    PGresult   *ECPGresult;
    enum ECPGdtype type;
    int         ntuples,
                act_tuple;
    struct variable data_var;
    struct sqlca_t *sqlca = ECPGget_sqlca();

    va_start(args, index);
    ecpg_init_sqlca(sqlca);
    ECPGresult = ecpg_result_by_descriptor(lineno, desc_name);
    if (!ECPGresult)
    {
        va_end(args);
        return (false);
    }

    ntuples = PQntuples(ECPGresult);

    if (index < 1 || index > PQnfields(ECPGresult))
    {
        ecpg_raise(lineno, ECPG_INVALID_DESCRIPTOR_INDEX, ECPG_SQLSTATE_INVALID_DESCRIPTOR_INDEX, NULL);
        va_end(args);
        return (false);
    }

    ecpg_log("ECPGget_desc: reading items for tuple %d\n", index);
    --index;

    type = va_arg(args, enum ECPGdtype);

    memset(&data_var, 0, sizeof data_var);
    data_var.type = ECPGt_EORT;
    data_var.ind_type = ECPGt_NO_INDICATOR;

    while (type != ECPGd_EODT)
    {
        char        type_str[20];
        long        varcharsize;
        long        offset;
        long        arrsize;
        enum ECPGttype vartype;
        void       *var;

        vartype = va_arg(args, enum ECPGttype);
        var = va_arg(args, void *);
        varcharsize = va_arg(args, long);
        arrsize = va_arg(args, long);
        offset = va_arg(args, long);

        switch (type)
        {
            case (ECPGd_indicator):
                RETURN_IF_NO_DATA;
                data_var.ind_type = vartype;
                data_var.ind_pointer = var;
                data_var.ind_varcharsize = varcharsize;
                data_var.ind_arrsize = arrsize;
                data_var.ind_offset = offset;
                if (data_var.ind_arrsize == 0 || data_var.ind_varcharsize == 0)
                    data_var.ind_value = *((void **) (data_var.ind_pointer));
                else
                    data_var.ind_value = data_var.ind_pointer;
                break;

            case ECPGd_data:
                RETURN_IF_NO_DATA;
                data_var.type = vartype;
                data_var.pointer = var;
                data_var.varcharsize = varcharsize;
                data_var.arrsize = arrsize;
                data_var.offset = offset;
                if (data_var.arrsize == 0 || data_var.varcharsize == 0)
                    data_var.value = *((void **) (data_var.pointer));
                else
                    data_var.value = data_var.pointer;
                break;

            case ECPGd_name:
                if (!get_char_item(lineno, var, vartype, PQfname(ECPGresult, index), varcharsize))
                {
                    va_end(args);
                    return (false);
                }

                ecpg_log("ECPGget_desc: NAME = %s\n", PQfname(ECPGresult, index));
                break;

            case ECPGd_nullable:
                if (!get_int_item(lineno, var, vartype, 1))
                {
                    va_end(args);
                    return (false);
                }

                break;

            case ECPGd_key_member:
                if (!get_int_item(lineno, var, vartype, 0))
                {
                    va_end(args);
                    return (false);
                }

                break;

            case ECPGd_scale:
                if (!get_int_item(lineno, var, vartype, (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff))
                {
                    va_end(args);
                    return (false);
                }

                ecpg_log("ECPGget_desc: SCALE = %d\n", (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff);
                break;

            case ECPGd_precision:
                if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) >> 16))
                {
                    va_end(args);
                    return (false);
                }

                ecpg_log("ECPGget_desc: PRECISION = %d\n", PQfmod(ECPGresult, index) >> 16);
                break;

            case ECPGd_octet:
                if (!get_int_item(lineno, var, vartype, PQfsize(ECPGresult, index)))
                {
                    va_end(args);
                    return (false);
                }

                ecpg_log("ECPGget_desc: OCTET_LENGTH = %d\n", PQfsize(ECPGresult, index));
                break;

            case ECPGd_length:
                if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) - VARHDRSZ))
                {
                    va_end(args);
                    return (false);
                }

                ecpg_log("ECPGget_desc: LENGTH = %d\n", PQfmod(ECPGresult, index) - VARHDRSZ);
                break;

            case ECPGd_type:
                if (!get_int_item(lineno, var, vartype, ecpg_dynamic_type(PQftype(ECPGresult, index))))
                {
                    va_end(args);
                    return (false);
                }

                ecpg_log("ECPGget_desc: TYPE = %d\n", ecpg_dynamic_type(PQftype(ECPGresult, index)));
                break;

            case ECPGd_di_code:
                if (!get_int_item(lineno, var, vartype, ecpg_dynamic_type_DDT(PQftype(ECPGresult, index))))
                {
                    va_end(args);
                    return (false);
                }

                ecpg_log("ECPGget_desc: TYPE = %d\n", ecpg_dynamic_type_DDT(PQftype(ECPGresult, index)));
                break;

            case ECPGd_cardinality:
                if (!get_int_item(lineno, var, vartype, PQntuples(ECPGresult)))
                {
                    va_end(args);
                    return (false);
                }

                ecpg_log("ECPGget_desc: CARDINALITY = %d\n", PQntuples(ECPGresult));
                break;

            case ECPGd_ret_length:
            case ECPGd_ret_octet:

                RETURN_IF_NO_DATA;

                /*
                 * this is like ECPGstore_result
                 */
                if (arrsize > 0 && ntuples > arrsize)
                {
                    ecpg_log("ECPGget_desc on line %d: incorrect number of matches; %d don't fit into array of %ld\n",
                             lineno, ntuples, arrsize);
                    ecpg_raise(lineno, ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);
                    va_end(args);
                    return false;
                }
                /* allocate storage if needed */
                if (arrsize == 0 && *(void **) var == NULL)
                {
                    void       *mem = (void *) ecpg_alloc(offset * ntuples, lineno);

                    if (!mem)
                    {
                        va_end(args);
                        return false;
                    }
                    *(void **) var = mem;
                    ecpg_add_mem(mem, lineno);
                    var = mem;
                }

                for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
                {
                    if (!get_int_item(lineno, var, vartype, PQgetlength(ECPGresult, act_tuple, index)))
                    {
                        va_end(args);
                        return (false);
                    }
                    var = (char *) var + offset;
                    ecpg_log("ECPGget_desc: RETURNED[%d] = %d\n", act_tuple, PQgetlength(ECPGresult, act_tuple, index));
                }
                break;

            default:
                snprintf(type_str, sizeof(type_str), "%d", type);
                ecpg_raise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str);
                va_end(args);
                return (false);
        }

        type = va_arg(args, enum ECPGdtype);
    }

    if (data_var.type != ECPGt_EORT)
    {
        struct statement stmt;
        char       *oldlocale;

        /* Make sure we do NOT honor the locale for numeric input */
        /* since the database gives the standard decimal point */
        oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno);
        setlocale(LC_NUMERIC, "C");

        memset(&stmt, 0, sizeof stmt);
        stmt.lineno = lineno;

        /* desperate try to guess something sensible */
        stmt.connection = ecpg_get_connection(NULL);
        ecpg_store_result(ECPGresult, index, &stmt, &data_var);

        setlocale(LC_NUMERIC, oldlocale);
        ecpg_free(oldlocale);
    }
    else if (data_var.ind_type != ECPGt_NO_INDICATOR && data_var.ind_pointer != NULL)

        /*
         * ind_type != NO_INDICATOR should always have ind_pointer != NULL but
         * since this might be changed manually in the .c file let's play it
         * safe
         */
    {
        /*
         * this is like ECPGstore_result but since we don't have a data
         * variable at hand, we can't call it
         */
        if (data_var.ind_arrsize > 0 && ntuples > data_var.ind_arrsize)
        {
            ecpg_log("ECPGget_desc on line %d: incorrect number of matches (indicator); %d don't fit into array of %ld\n",
                     lineno, ntuples, data_var.ind_arrsize);
            ecpg_raise(lineno, ECPG_TOO_MANY_MATCHES, ECPG_SQLSTATE_CARDINALITY_VIOLATION, NULL);
            va_end(args);
            return false;
        }

        /* allocate storage if needed */
        if (data_var.ind_arrsize == 0 && data_var.ind_value == NULL)
        {
            void       *mem = (void *) ecpg_alloc(data_var.ind_offset * ntuples, lineno);

            if (!mem)
            {
                va_end(args);
                return false;
            }
            *(void **) data_var.ind_pointer = mem;
            ecpg_add_mem(mem, lineno);
            data_var.ind_value = mem;
        }

        for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
        {
            if (!get_int_item(lineno, data_var.ind_value, data_var.ind_type, -PQgetisnull(ECPGresult, act_tuple, index)))
            {
                va_end(args);
                return (false);
            }
            data_var.ind_value = (char *) data_var.ind_value + data_var.ind_offset;
            ecpg_log("ECPGget_desc: INDICATOR[%d] = %d\n", act_tuple, -PQgetisnull(ECPGresult, act_tuple, index));
        }
    }
    sqlca->sqlerrd[2] = ntuples;
    va_end(args);
    return (true);
}

bool ECPGget_desc_header ( int  ,
const char *  ,
int *   
)

Definition at line 91 of file descriptor.c.

References ecpg_init_sqlca(), ecpg_log(), ecpg_result_by_descriptor(), ECPGget_sqlca(), PQnfields(), sqlca, and sqlca_t::sqlerrd.

Referenced by main().

{
    PGresult   *ECPGresult;
    struct sqlca_t *sqlca = ECPGget_sqlca();

    ecpg_init_sqlca(sqlca);
    ECPGresult = ecpg_result_by_descriptor(lineno, desc_name);
    if (!ECPGresult)
        return false;

    *count = PQnfields(ECPGresult);
    sqlca->sqlerrd[2] = 1;
    ecpg_log("ECPGget_desc_header: found %d attributes\n", *count);
    return true;
}

PGconn* ECPGget_PGconn ( const char *   ) 

Definition at line 692 of file connect.c.

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

{
    struct connection *con;

    con = ecpg_get_connection(connection_name);
    if (con == NULL)
        return NULL;

    return con->connection;
}

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,
void *   
)

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

bool ECPGprepare ( int  ,
const char *  ,
const   bool,
const char *  ,
const char *   
)

Definition at line 161 of file prepare.c.

References deallocate_one(), ECPG_COMPAT_PGSQL, ecpg_find_prepared_statement(), ecpg_get_connection(), ecpg_init(), and prepare_common().

Referenced by ecpg_auto_prepare(), main(), and test().

{
    struct connection *con;
    struct prepared_statement *this,
               *prev;

    (void) questionmarks;       /* quiet the compiler */
    con = ecpg_get_connection(connection_name);

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

    /* check if we already have prepared this statement */
    this = ecpg_find_prepared_statement(name, con, &prev);
    if (this && !deallocate_one(lineno, ECPG_COMPAT_PGSQL, con, prev, this))
        return false;

    return prepare_common(lineno, con, name, variable);
}

char* ECPGprepared_statement ( const char *  ,
const char *  ,
int   
)

Definition at line 306 of file prepare.c.

References ecpg_get_connection(), and ecpg_prepared().

Referenced by main(), and test().

{
    (void) lineno;              /* keep the compiler quiet */
    return ecpg_prepared(name, ecpg_get_connection(connection_name));
}

bool ECPGset_desc ( int  ,
const char *  ,
int  ,
  ... 
)

Definition at line 555 of file descriptor.c.

References variable::arrsize, descriptor::count, descriptor_item::data, ecpg_alloc(), ecpg_find_desc(), ecpg_free(), ecpg_raise(), ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, ecpg_store_input(), ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPGd_data, ECPGd_EODT, ECPGd_indicator, ECPGd_length, ECPGd_precision, ECPGd_scale, ECPGd_type, descriptor_item::indicator, descriptor::items, descriptor_item::length, variable::next, descriptor_item::next, NULL, descriptor_item::num, variable::offset, variable::pointer, descriptor_item::precision, descriptor_item::scale, set_int_item(), snprintf(), descriptor_item::type, variable::type, variable::value, and variable::varcharsize.

Referenced by main().

{
    va_list     args;
    struct descriptor *desc;
    struct descriptor_item *desc_item;
    struct variable *var;

    desc = ecpg_find_desc(lineno, desc_name);
    if (desc == NULL)
        return false;

    for (desc_item = desc->items; desc_item; desc_item = desc_item->next)
    {
        if (desc_item->num == index)
            break;
    }

    if (desc_item == NULL)
    {
        desc_item = (struct descriptor_item *) ecpg_alloc(sizeof(*desc_item), lineno);
        if (!desc_item)
            return false;
        desc_item->num = index;
        if (desc->count < index)
            desc->count = index;
        desc_item->next = desc->items;
        desc->items = desc_item;
    }

    if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
        return false;

    va_start(args, index);

    for (;;)
    {
        enum ECPGdtype itemtype;
        char       *tobeinserted = NULL;

        itemtype = va_arg(args, enum ECPGdtype);

        if (itemtype == ECPGd_EODT)
            break;

        var->type = va_arg(args, enum ECPGttype);
        var->pointer = va_arg(args, char *);

        var->varcharsize = va_arg(args, long);
        var->arrsize = va_arg(args, long);
        var->offset = va_arg(args, long);

        if (var->arrsize == 0 || var->varcharsize == 0)
            var->value = *((char **) (var->pointer));
        else
            var->value = var->pointer;

        /*
         * negative values are used to indicate an array without given bounds
         */
        /* reset to zero for us */
        if (var->arrsize < 0)
            var->arrsize = 0;
        if (var->varcharsize < 0)
            var->varcharsize = 0;

        var->next = NULL;

        switch (itemtype)
        {
            case ECPGd_data:
                {
                    if (!ecpg_store_input(lineno, true, var, &tobeinserted, false))
                    {
                        ecpg_free(var);
                        va_end(args);
                        return false;
                    }

                    ecpg_free(desc_item->data); /* free() takes care of a
                                                 * potential NULL value */
                    desc_item->data = (char *) tobeinserted;
                    tobeinserted = NULL;
                    break;
                }

            case ECPGd_indicator:
                set_int_item(lineno, &desc_item->indicator, var->pointer, var->type);
                break;

            case ECPGd_length:
                set_int_item(lineno, &desc_item->length, var->pointer, var->type);
                break;

            case ECPGd_precision:
                set_int_item(lineno, &desc_item->precision, var->pointer, var->type);
                break;

            case ECPGd_scale:
                set_int_item(lineno, &desc_item->scale, var->pointer, var->type);
                break;

            case ECPGd_type:
                set_int_item(lineno, &desc_item->type, var->pointer, var->type);
                break;

            default:
                {
                    char        type_str[20];

                    snprintf(type_str, sizeof(type_str), "%d", itemtype);
                    ecpg_raise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str);
                    ecpg_free(var);
                    va_end(args);
                    return false;
                }
        }
    }
    ecpg_free(var);
    va_end(args);

    return true;
}

bool ECPGset_desc_header ( int  ,
const char *  ,
int   
)

Definition at line 544 of file descriptor.c.

References descriptor::count, ecpg_find_desc(), and NULL.

Referenced by main().

{
    struct descriptor *desc = ecpg_find_desc(lineno, desc_name);

    if (desc == NULL)
        return false;
    desc->count = count;
    return true;
}

void ECPGset_noind_null ( enum  ECPGttype,
void *   
)

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  ,
void *  ,
int   
)

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 ECPGsetcommit ( int  ,
const char *  ,
const char *   
)

Definition at line 165 of file connect.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().

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

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

    ecpg_log("ECPGsetcommit on line %d: action \"%s\"; connection \"%s\"\n", lineno, mode, con->name);

    if (con->autocommit && strncmp(mode, "off", strlen("off")) == 0)
    {
        if (PQtransactionStatus(con->connection) == PQTRANS_IDLE)
        {
            results = PQexec(con->connection, "begin transaction");
            if (!ecpg_check_PQresult(results, lineno, con->connection, ECPG_COMPAT_PGSQL))
                return false;
            PQclear(results);
        }
        con->autocommit = false;
    }
    else if (!con->autocommit && strncmp(mode, "on", strlen("on")) == 0)
    {
        if (PQtransactionStatus(con->connection) != PQTRANS_IDLE)
        {
            results = PQexec(con->connection, "commit");
            if (!ecpg_check_PQresult(results, lineno, con->connection, ECPG_COMPAT_PGSQL))
                return false;
            PQclear(results);
        }
        con->autocommit = true;
    }

    return true;
}

bool ECPGsetconn ( int  ,
const char *   
)

Definition at line 202 of file connect.c.

References ecpg_get_connection(), ecpg_init(), and pthread_setspecific().

Referenced by main().

{
    struct connection *con = ecpg_get_connection(connection_name);

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

#ifdef ENABLE_THREAD_SAFETY
    pthread_setspecific(actual_connection_key, con);
#else
    actual_connection = con;
#endif
    return true;
}

bool ECPGstatus ( int  ,
const char *   
)

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  ,
const char *  ,
const char *   
)

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 *   ) 

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

}

void sqlprint ( void   ) 

Definition at line 400 of file error.c.

References ecpg_gettext, ECPGget_sqlca(), sqlca, sqlca_t::sqlerrm, sqlca_t::sqlerrmc, and sqlca_t::sqlerrml.

Referenced by fn(), main(), print(), print2(), and test().

{
    struct sqlca_t *sqlca = ECPGget_sqlca();

    sqlca->sqlerrm.sqlerrmc[sqlca->sqlerrm.sqlerrml] = '\0';
    fprintf(stderr, ecpg_gettext("SQL error: %s\n"), sqlca->sqlerrm.sqlerrmc);
}