Header And Logo

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

Defines | Functions

data.c File Reference

#include "postgres_fe.h"
#include <stdlib.h>
#include <string.h>
#include <float.h>
#include <math.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 dependency graph for data.c:

Go to the source code of this file.

Defines

#define POSTGRES_ECPG_INTERNAL

Functions

static bool array_delimiter (enum ARRAY_TYPE isarray, char c)
static bool array_boundary (enum ARRAY_TYPE isarray, char c)
static bool garbage_left (enum ARRAY_TYPE isarray, char *scan_length, enum COMPAT_MODE compat)
static double get_float8_infinity (void)
static double get_float8_nan (void)
static bool check_special_value (char *ptr, double *retval, char **endptr)
bool ecpg_get_data (const PGresult *results, int act_tuple, int act_field, int lineno, enum ECPGttype type, enum ECPGttype ind_type, char *var, char *ind, long varcharsize, long offset, long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)

Define Documentation

#define POSTGRES_ECPG_INTERNAL

Definition at line 3 of file data.c.


Function Documentation

static bool array_boundary ( enum ARRAY_TYPE  isarray,
char  c 
) [static]

Definition at line 36 of file data.c.

References ECPG_ARRAY_ARRAY, and ECPG_ARRAY_VECTOR.

Referenced by ecpg_get_data(), and garbage_left().

{
    if (isarray == ECPG_ARRAY_ARRAY && c == '}')
        return true;

    if (isarray == ECPG_ARRAY_VECTOR && c == '\0')
        return true;

    return false;
}

static bool array_delimiter ( enum ARRAY_TYPE  isarray,
char  c 
) [static]

Definition at line 23 of file data.c.

References ECPG_ARRAY_ARRAY, and ECPG_ARRAY_VECTOR.

Referenced by ecpg_get_data(), and garbage_left().

{
    if (isarray == ECPG_ARRAY_ARRAY && c == ',')
        return true;

    if (isarray == ECPG_ARRAY_VECTOR && c == ' ')
        return true;

    return false;
}

static bool check_special_value ( char *  ptr,
double *  retval,
char **  endptr 
) [static]

Definition at line 98 of file data.c.

References get_float8_infinity(), get_float8_nan(), and pg_strncasecmp().

Referenced by ecpg_get_data().

{
    if (pg_strncasecmp(ptr, "NaN", 3) == 0)
    {
        *retval = get_float8_nan();
        *endptr = ptr + 3;
        return true;
    }
    else if (pg_strncasecmp(ptr, "Infinity", 8) == 0)
    {
        *retval = get_float8_infinity();
        *endptr = ptr + 8;
        return true;
    }
    else if (pg_strncasecmp(ptr, "-Infinity", 9) == 0)
    {
        *retval = -get_float8_infinity();
        *endptr = ptr + 9;
        return true;
    }

    return false;
}

bool ecpg_get_data ( const PGresult results,
int  act_tuple,
int  act_field,
int  lineno,
enum ECPGttype  type,
enum ECPGttype  ind_type,
char *  var,
char *  ind,
long  varcharsize,
long  offset,
long  ind_offset,
enum ARRAY_TYPE  isarray,
enum COMPAT_MODE  compat,
bool  force_indicator 
)

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

static bool garbage_left ( enum ARRAY_TYPE  isarray,
char *  scan_length,
enum COMPAT_MODE  compat 
) [static]

Definition at line 49 of file data.c.

References array_boundary(), array_delimiter(), ECPG_ARRAY_NONE, ECPG_IS_ARRAY, and INFORMIX_MODE.

Referenced by ecpg_get_data().

{
    /*
     * INFORMIX allows for selecting a numeric into an int, the result is
     * truncated
     */
    if (isarray == ECPG_ARRAY_NONE)
    {
        if (INFORMIX_MODE(compat) && *scan_length == '.')
            return false;

        if (*scan_length != ' ' && *scan_length != '\0')
            return true;
    }
    else if (ECPG_IS_ARRAY(isarray) && !array_delimiter(isarray, *scan_length) && !array_boundary(isarray, *scan_length))
        return true;

    return false;
}

static double get_float8_infinity ( void   )  [static]

Definition at line 77 of file data.c.

{
#ifdef INFINITY
    return (double) INFINITY;
#else
    return (double) (HUGE_VAL * HUGE_VAL);
#endif
}

static double get_float8_nan ( void   )  [static]

Definition at line 87 of file data.c.

{
    /* (double) NAN doesn't work on some NetBSD/MIPS releases */
#if defined(NAN) && !(defined(__NetBSD__) && defined(__mips__))
    return (double) NAN;
#else
    return (double) (0.0 / 0.0);
#endif
}