Fix the bug with datatype lo and server side cursor reported by Roel Claessen.
authorHiroshi Inoue <inoue@tpf.co.jp>
Sun, 25 Oct 2009 13:01:43 +0000 (13:01 +0000)
committerHiroshi Inoue <inoue@tpf.co.jp>
Sun, 25 Oct 2009 13:01:43 +0000 (13:01 +0000)
bind.c
bind.h
results.c
version.h

diff --git a/bind.c b/bind.c
index f8c270439b308a2495453a26f265e63392802f09..32a9170294cad8c0de6bf9a480f3a3722a08f925 100644 (file)
--- a/bind.c
+++ b/bind.c
@@ -83,8 +83,6 @@ PGAPI_BindParameter(
    ipdopts->parameters[ipar].decimal_digits = ibScale;
    ipdopts->parameters[ipar].precision = 0;
    ipdopts->parameters[ipar].scale = 0;
-   if (0 == ipdopts->parameters[ipar].PGType)
-       ipdopts->parameters[ipar].PGType = sqltype_to_pgtype(stmt, fSqlType);
 #if (ODBCVER >= 0x0300)
    switch (fCType)
    {
@@ -135,7 +133,7 @@ PGAPI_BindParameter(
        SC_recycle_statement(stmt);
 
    mylog("%s: ipar=%d, paramType=%d, fCType=%d, fSqlType=%d, cbColDef=%d, ibScale=%d,", func, ipar, fParamType, fCType, fSqlType, cbColDef, ibScale);
-   mylog("rgbValue=%p, pcbValue=%p\n", rgbValue, pcbValue);
+   mylog("rgbValue=%p(%d), pcbValue=%p\n", rgbValue, cbValueMax, pcbValue);
 
    return SQL_SUCCESS;
 }
@@ -309,6 +307,7 @@ PGAPI_DescribeParam(
    IPDFields   *ipdopts;
    RETCODE     ret = SQL_SUCCESS;
    int     num_params;
+   OID     pgtype;
 
    mylog("%s: entering...%d\n", func, ipar);
 
@@ -355,6 +354,7 @@ inolog("howTo=%d\n", SC_get_prepare_method(stmt));
    }
 
    ipar--;
+   pgtype = PIC_get_pgtype(ipdopts->parameters[ipar]);
    /*
     * This implementation is not very good, since it is supposed to
     * describe
@@ -362,12 +362,11 @@ inolog("howTo=%d\n", SC_get_prepare_method(stmt));
    /* parameter markers, not bound parameters.  */
    if (pfSqlType)
    {
-inolog("[%d].SQLType=%d .PGType=%d\n", ipar, ipdopts->parameters[ipar].SQLType,
-ipdopts->parameters[ipar].PGType);
+inolog("[%d].SQLType=%d .PGType=%d\n", ipar, ipdopts->parameters[ipar].SQLType, pgtype);
        if (ipdopts->parameters[ipar].SQLType)
            *pfSqlType = ipdopts->parameters[ipar].SQLType;
-       else if (ipdopts->parameters[ipar].PGType)
-           *pfSqlType = pgtype_to_concise_type(stmt, ipdopts->parameters[ipar].PGType, PG_STATIC);
+       else if (pgtype)
+           *pfSqlType = pgtype_to_concise_type(stmt, pgtype, PG_STATIC);
        else
        {
            ret = SQL_ERROR;
@@ -381,8 +380,8 @@ ipdopts->parameters[ipar].PGType);
        *pcbParamDef = 0;
        if (ipdopts->parameters[ipar].SQLType)
            *pcbParamDef = ipdopts->parameters[ipar].column_size;
-       if (0 == *pcbParamDef && ipdopts->parameters[ipar].PGType)
-           *pcbParamDef = pgtype_column_size(stmt, ipdopts->parameters[ipar].PGType, PG_STATIC, PG_STATIC);
+       if (0 == *pcbParamDef && pgtype)
+           *pcbParamDef = pgtype_column_size(stmt, pgtype, PG_STATIC, PG_STATIC);
    }
 
    if (pibScale)
@@ -390,8 +389,8 @@ ipdopts->parameters[ipar].PGType);
        *pibScale = 0;
        if (ipdopts->parameters[ipar].SQLType)
            *pibScale = ipdopts->parameters[ipar].decimal_digits;
-       else if (ipdopts->parameters[ipar].PGType)
-           *pibScale = pgtype_scale(stmt, ipdopts->parameters[ipar].PGType, -1);
+       else if (pgtype)
+           *pibScale = pgtype_scale(stmt, pgtype, -1);
    }
 
    if (pfNullable)
@@ -614,7 +613,7 @@ reset_a_iparameter_binding(IPDFields *self, int ipar)
    self->parameters[ipar].decimal_digits = 0;
    self->parameters[ipar].precision = 0;
    self->parameters[ipar].scale = 0;
-   self->parameters[ipar].PGType = 0;
+   PIC_set_pgtype(self->parameters[ipar], 0);
 }
 
 int
diff --git a/bind.h b/bind.h
index 0060d03cc7c42f65a74b8943882ed6fdafbd795a..e36ef292e27aa025fd1fd3184383aedff49a2723 100644 (file)
--- a/bind.h
+++ b/bind.h
@@ -89,6 +89,11 @@ typedef struct
    PutDataClass    *pdata;
 }  PutDataInfo;
 
+/* Macros to handle pgtype of parameters */
+#define    PIC_get_pgtype(pari) ((pari).PGType)
+#define    PIC_set_pgtype(pari, type) ((pari).PGType = (type))
+#define    PIC_dsp_pgtype(stmt, pari) ((pari).PGType ? (pari).PGType : sqltype_to_pgtype(stmt, (pari).SQLType))
+
 void   extend_column_bindings(ARDFields *opts, int num_columns);
 void   reset_a_column_binding(ARDFields *opts, int icol);
 void   extend_parameter_bindings(APDFields *opts, int num_params);
index 485970693d6eccf7390c24b7d9b547068130a07f..2b725853b9dd962f7760d8485e5b164db08306b4 100644 (file)
--- a/results.c
+++ b/results.c
@@ -33,6 +33,8 @@
 
 #include "pgapifunc.h"
 
+/* Helper macro */
+#define getEffectiveOid(conn, fi) pg_true_type((conn), (fi)->columntype, FI_type(fi))
 
 
 RETCODE        SQL_API
@@ -339,7 +341,7 @@ inolog("answering bookmark info\n");
    }
    if (FI_is_applicable(fi))
    {
-       fieldtype = pg_true_type(conn, fi->columntype, FI_type(fi));
+       fieldtype = getEffectiveOid(conn, fi);
        if (NAME_IS_VALID(fi->column_alias))
            col_name = GET_NAME(fi->column_alias);
        else
@@ -477,7 +479,7 @@ PGAPI_ColAttributes(
        return SQL_INVALID_HANDLE;
    }
    stmt_updatable = SC_is_updatable(stmt)
-       /* The folllowing doesn't seem appropriate for client side cursors
+       /* The following doesn't seem appropriate for client side cursors
          && stmt->options.scroll_concurrency != SQL_CONCUR_READ_ONLY
         */
        ;
@@ -561,7 +563,7 @@ inolog("answering bookmark info\n");
    if (col_idx < irdflds->nfields && irdflds->fi)
        fi = irdflds->fi[col_idx];
    if (FI_is_applicable(fi))
-       field_type = pg_true_type(conn, fi->columntype, FI_type(fi));
+       field_type = getEffectiveOid(conn, fi);
    else
    {
        BOOL    build_fi = FALSE;
@@ -624,7 +626,7 @@ inolog("answering bookmark info\n");
    if (FI_is_applicable(fi))
    {
        ti = fi->ti;
-       field_type = pg_true_type(conn, fi->columntype, FI_type(fi));
+       field_type = getEffectiveOid(conn, fi);
    }
 
    mylog("colAttr: col %d field_type=%d fi,ti=%p,%p\n", col_idx, field_type, fi, ti);
@@ -3668,6 +3670,7 @@ SC_pos_update(StatementClass *stmt,
        int         j;
        ConnInfo    *ci = &(conn->connInfo);
        APDFields   *apdopts;
+       IPDFields   *ipdopts;
        OID     fieldtype = 0;
        const char *bestitem = GET_NAME(ti->bestitem);
        const char *bestqual = GET_NAME(ti->bestqual);
@@ -3692,7 +3695,9 @@ SC_pos_update(StatementClass *stmt,
        apdopts = SC_get_APDF(s.qstmt);
        apdopts->param_bind_type = opts->bind_size;
        apdopts->param_offset_ptr = opts->row_offset_ptr;
+       ipdopts = SC_get_IPDF(s.qstmt);
        SC_set_delegate(s.stmt, s.qstmt);
+       extend_iparameter_bindings(ipdopts, num_cols);
        for (i = j = 0; i < num_cols; i++)
        {
            if (used = bindings[i].used, used != NULL)
@@ -3705,7 +3710,9 @@ SC_pos_update(StatementClass *stmt,
                mylog("%d used=%d\n", i, *used);
                if (*used != SQL_IGNORE && fi[i]->updatable)
                {
-                   fieldtype = QR_get_field_type(s.res, i);
+                   /* fieldtype = QR_get_field_type(s.res, i); */
+                   fieldtype = getEffectiveOid(conn, fi[i]);
+                   PIC_set_pgtype(ipdopts->parameters[j], fieldtype);
                    PGAPI_BindParameter(hstmt,
                        (SQLUSMALLINT) ++j,
                        SQL_PARAM_INPUT,
@@ -4036,6 +4043,7 @@ SC_pos_add(StatementClass *stmt,
    ConnInfo    *ci;
    ARDFields   *opts = SC_get_ARDF(stmt);
    APDFields   *apdopts;
+   IPDFields   *ipdopts;
    BindInfoClass *bindings = opts->bindings;
    FIELD_INFO  **fi = SC_get_IRDF(stmt)->fi;
    char        addstr[4096];
@@ -4082,8 +4090,10 @@ SC_pos_add(StatementClass *stmt,
    apdopts = SC_get_APDF(s.qstmt);
    apdopts->param_bind_type = opts->bind_size;
    apdopts->param_offset_ptr = opts->row_offset_ptr;
+   ipdopts = SC_get_IPDF(s.qstmt);
    SC_set_delegate(s.stmt, s.qstmt);
    ci = &(conn->connInfo);
+   extend_iparameter_bindings(ipdopts, num_cols);
    for (i = add_cols = 0; i < num_cols; i++)
    {
        if (used = bindings[i].used, used != NULL)
@@ -4096,11 +4106,13 @@ SC_pos_add(StatementClass *stmt,
            mylog("%d used=%d\n", i, *used);
            if (*used != SQL_IGNORE && fi[i]->updatable)
            {
-               fieldtype = QR_get_field_type(s.res, i);
+               /* fieldtype = QR_get_field_type(s.res, i); */
+               fieldtype = getEffectiveOid(conn, fi[i]);
                if (add_cols)
                    sprintf(addstr, "%s, \"%s\"", addstr, GET_NAME(fi[i]->column_name));
                else
                    sprintf(addstr, "%s\"%s\"", addstr, GET_NAME(fi[i]->column_name));
+               PIC_set_pgtype(ipdopts->parameters[add_cols], fieldtype);
                PGAPI_BindParameter(hstmt,
                    (SQLUSMALLINT) ++add_cols,
                    SQL_PARAM_INPUT,
index 02b550430baa18ef2bdddfe9f87467845eb9ae00..85fe15be8e4b203ff09db68041e7a9f34174fb63 100644 (file)
--- a/version.h
+++ b/version.h
@@ -12,6 +12,6 @@
 #define POSTGRESDRIVERVERSION      "08.04.0101"
 #define POSTGRES_RESOURCE_VERSION  "08.04.0101\0"
 #define PG_DRVFILE_VERSION     8,4,01,01
-#define PG_BUILD_VERSION       "200910250001"
+#define PG_BUILD_VERSION       "200910250002"
 
 #endif