1) Avoid password leak in the log.
authorHiroshi Inoue <inoue@tpf.co.jp>
Wed, 23 Apr 2003 09:49:47 +0000 (09:49 +0000)
committerHiroshi Inoue <inoue@tpf.co.jp>
Wed, 23 Apr 2003 09:49:47 +0000 (09:49 +0000)
2) Reduce time() calls for the performance.
3) Improve the handling of per Driver resource.
4) #define HAVE_STRTOLL
  etc.

22 files changed:
configure.ac
connection.c
convert.c
convert.h
dlg_specific.c
dlg_specific.h
dlg_wingui.c
drvconn.c
execute.c
info.c
misc.c
misc.h
multibyte.c
parse.c
pgtypes.c
psqlodbc.h
qresult.c
results.c
setup.c
statement.c
statement.h
version.h

index c7fc5fb2221b245ae89bac216d4b984171c7d4af..16b004158f397df7af1cea76b8ab1d0ee37f7889 100644 (file)
@@ -24,9 +24,21 @@ if test "$with_unixodbc" = yes && test "$with_iodbc" = yes; then
   AC_MSG_ERROR([ODBC driver cannot be built for both unixODBC and iODBC])
 fi
 
+#
+# Default odbc version number (--with-odbcver), default 0x0250
+#
+AC_MSG_CHECKING([for ODBC version number])
+PGAC_ARG_REQ(with, odbcver, [  --with-odbcver=VERSION  change default ODBC version number
+ [0x0250]],
+             [AC_DEFINE_UNQUOTED(ODBCVER, ${withval},
+           [Define to ODBC version (--with-odbcver)])])
+AC_MSG_RESULT([$with_odbcver])
+
 AM_CONDITIONAL(with_unixodbc, [test $with_unixodbc = yes])
 AM_CONDITIONAL(with_iodbc, [test $with_iodbc = yes])
 
+AC_CHECK_FUNCS(strtoll)
+
 # to implement the thread-safe driver
 PGAC_ARG_BOOL(enable, pthreads, no,
     [  --enable-pthreads         build pthread implementation if possible],
@@ -37,7 +49,7 @@ PGAC_ARG_BOOL(enable, pthreads, no,
      AC_CHECK_LIB(c_r, gethostbyname)
      AC_CHECK_LIB(nsl, gethostbyname_r, [],
    [AC_CHECK_FUNCS(getipnodebyname gethostbyname_r, break)])
-     if test "$ac_cv_func_gethostbyname_r" = yes || test "$ac_cv_lib_nsl_gethostbyname_r" = yes; then
+     if test x"$ac_cv_func_gethostbyname_r" = xyes || test x"$ac_cv_lib_nsl_gethostbyname_r" = xyes; then
    AC_TRY_COMPILE([#include <netdb.h>],
    [ gethostbyname_r((char *) 0, (struct hostent *) 0, (char *) 0, 0, (int *) 0);],
         [AC_DEFINE(PGS_REENTRANT_API_1, 1, [Define if you have 5 parameter gethostbyname_r])],
index e36b8efa592962dfb384af01d8133bdc4523f5ea..456637a37e2a40d17d9e41faae4e75a23b806cb5 100644 (file)
@@ -126,7 +126,7 @@ PGAPI_Connect(
    /* fill in any defaults */
    getDSNdefaults(ci);
 
-   qlog("conn = %u, %s(DSN='%s', UID='%s', PWD='%s')\n", conn, func, ci->dsn, ci->username, ci->password);
+   qlog("conn = %u, %s(DSN='%s', UID='%s', PWD='%s')\n", conn, func, ci->dsn, ci->username, ci->password ? "xxxxx" : "");
 
    if (CC_connect(conn, AUTH_REQ_OK, NULL) <= 0)
    {
@@ -675,7 +675,7 @@ CC_connect(ConnectionClass *self, char password_req, char *salt_para)
            return 0;
        }
 
-       mylog("CC_connect(): DSN = '%s', server = '%s', port = '%s', database = '%s', username = '%s', password='%s'\n", ci->dsn, ci->server, ci->port, ci->database, ci->username, ci->password);
+       mylog("CC_connect(): DSN = '%s', server = '%s', port = '%s', database = '%s', username = '%s', password='%s'\n", ci->dsn, ci->server, ci->port, ci->database, ci->username, ci->password ? "xxxxx" : "");
 
 another_version_retry:
 
index fd44b31cbf5912bda72740b5c6f42a355918c756..5cf25f62d7054f1e8ab90a67c62d4d5380ee531f 100644 (file)
--- a/convert.c
+++ b/convert.c
@@ -136,7 +136,6 @@ static unsigned int conv_from_octal(const unsigned char *s);
 static unsigned int conv_from_hex(const unsigned char *s);
 static char *conv_to_octal(unsigned char val, char *octal);
 static int pg_bin2hex(UCHAR *src, UCHAR *dst, int length);
-static int pg_hex2bin(UCHAR *src, UCHAR *dst, int length);
 
 /*---------
  *         A Guide for date/time/timestamp conversions
@@ -166,11 +165,12 @@ static int pg_hex2bin(UCHAR *src, UCHAR *dst, int length);
 #define    ATOI64U _atoi64
 #define    FORMATI64   "%I64d"
 #define    FORMATI64U  "%I64u"
-#else
+#elif  defined(HAVE_STRTOLL)
 #define    ATOI64(val) strtoll(val, NULL, 10)
 #define    ATOI64U(val)    strtoull(val, NULL, 10)
 #define    FORMATI64   "%lld"
 #define    FORMATI64U  "%llu"
+#else /* HAVE_STRTOLL */
 #endif /* WIN32 */
 #endif /* ODBCINT64 */
 
@@ -369,8 +369,8 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
    ARDFields   *opts = SC_get_ARD(stmt);
    Int4        len = 0,
                copy_len = 0;
-   SIMPLE_TIME st;
-   time_t      t = time(NULL);
+   SIMPLE_TIME std_time;
+   time_t      stmt_t = SC_get_time(stmt);
    struct tm  *tim;
 #ifdef HAVE_LOCALTIME_R
    struct tm  tm;
@@ -433,17 +433,17 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
 
    }
 
-   memset(&st, 0, sizeof(SIMPLE_TIME));
+   memset(&std_time, 0, sizeof(SIMPLE_TIME));
 
    /* Initialize current date */
 #ifdef HAVE_LOCALTIME_R
-   tim = localtime_r(&t, &tm);
+   tim = localtime_r(&stmt_t, &tm);
 #else
-   tim = localtime(&t);
+   tim = localtime(&stmt_t);
 #endif /* HAVE_LOCALTIME_R */
-   st.m = tim->tm_mon + 1;
-   st.d = tim->tm_mday;
-   st.y = tim->tm_year + 1900;
+   std_time.m = tim->tm_mon + 1;
+   std_time.d = tim->tm_mday;
+   std_time.y = tim->tm_year + 1900;
 
    mylog("copy_and_convert: field_type = %d, fctype = %d, value = '%s', cbValueMax=%d\n", field_type, fCType, (value == NULL) ? "<NULL>" : value, cbValueMax);
 
@@ -490,38 +490,38 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
             * PG_TYPE_CHAR,VARCHAR $$$
             */
        case PG_TYPE_DATE:
-           sscanf(value, "%4d-%2d-%2d", &st.y, &st.m, &st.d);
+           sscanf(value, "%4d-%2d-%2d", &std_time.y, &std_time.m, &std_time.d);
            break;
 
        case PG_TYPE_TIME:
-           sscanf(value, "%2d:%2d:%2d", &st.hh, &st.mm, &st.ss);
+           sscanf(value, "%2d:%2d:%2d", &std_time.hh, &std_time.mm, &std_time.ss);
            break;
 
        case PG_TYPE_ABSTIME:
        case PG_TYPE_DATETIME:
        case PG_TYPE_TIMESTAMP_NO_TMZONE:
        case PG_TYPE_TIMESTAMP:
-           st.fr = 0;
-           st.infinity = 0;
+           std_time.fr = 0;
+           std_time.infinity = 0;
            if (strnicmp(value, "infinity", 8) == 0)
            {
-               st.infinity = 1;
-               st.m = 12;
-               st.d = 31;
-               st.y = 9999;
-               st.hh = 23;
-               st.mm = 59;
-               st.ss = 59;
+               std_time.infinity = 1;
+               std_time.m = 12;
+               std_time.d = 31;
+               std_time.y = 9999;
+               std_time.hh = 23;
+               std_time.mm = 59;
+               std_time.ss = 59;
            }
            if (strnicmp(value, "-infinity", 9) == 0)
            {
-               st.infinity = -1;
-               st.m = 0;
-               st.d = 0;
-               st.y = 0;
-               st.hh = 0;
-               st.mm = 0;
-               st.ss = 0;
+               std_time.infinity = -1;
+               std_time.m = 0;
+               std_time.d = 0;
+               std_time.y = 0;
+               std_time.hh = 0;
+               std_time.mm = 0;
+               std_time.ss = 0;
            }
            if (strnicmp(value, "invalid", 7) != 0)
            {
@@ -529,11 +529,12 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
                int         zone;
 
                /*
-                * sscanf(value, "%4d-%2d-%2d %2d:%2d:%2d", &st.y, &st.m,
-                * &st.d, &st.hh, &st.mm, &st.ss);
+                * sscanf(value, "%4d-%2d-%2d %2d:%2d:%2d", &std_time.y, &std_time.m,
+                * &std_time.d, &std_time.hh, &std_time.mm, &std_time.ss);
                 */
                bZone = FALSE;  /* time zone stuff is unreliable */
-               timestamp2stime(value, &st, &bZone, &zone);
+               timestamp2stime(value, &std_time, &bZone, &zone);
+inolog("2stime fr=%d\n", std_time.fr);
            }
            else
            {
@@ -541,18 +542,18 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
                 * The timestamp is invalid so set something conspicuous,
                 * like the epoch
                 */
-               t = 0;
+               time_t  t = 0;
 #ifdef HAVE_LOCALTIME_R
                tim = localtime_r(&t, &tm);
 #else
                tim = localtime(&t);
 #endif /* HAVE_LOCALTIME_R */
-               st.m = tim->tm_mon + 1;
-               st.d = tim->tm_mday;
-               st.y = tim->tm_year + 1900;
-               st.hh = tim->tm_hour;
-               st.mm = tim->tm_min;
-               st.ss = tim->tm_sec;
+               std_time.m = tim->tm_mon + 1;
+               std_time.d = tim->tm_mday;
+               std_time.y = tim->tm_year + 1900;
+               std_time.hh = tim->tm_hour;
+               std_time.mm = tim->tm_min;
+               std_time.ss = tim->tm_sec;
            }
            break;
 
@@ -680,13 +681,13 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
            case PG_TYPE_DATE:
                len = 10;
                if (cbValueMax > len)
-                   sprintf(rgbValueBindRow, "%.4d-%.2d-%.2d", st.y, st.m, st.d);
+                   sprintf(rgbValueBindRow, "%.4d-%.2d-%.2d", std_time.y, std_time.m, std_time.d);
                break;
 
            case PG_TYPE_TIME:
                len = 8;
                if (cbValueMax > len)
-                   sprintf(rgbValueBindRow, "%.2d:%.2d:%.2d", st.hh, st.mm, st.ss);
+                   sprintf(rgbValueBindRow, "%.2d:%.2d:%.2d", std_time.hh, std_time.mm, std_time.ss);
                break;
 
            case PG_TYPE_ABSTIME:
@@ -696,7 +697,7 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
                len = 19;
                if (cbValueMax > len)
                    sprintf(rgbValueBindRow, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
-                           st.y, st.m, st.d, st.hh, st.mm, st.ss);
+                           std_time.y, std_time.m, std_time.d, std_time.hh, std_time.mm, std_time.ss);
                break;
 
            case PG_TYPE_BOOL:
@@ -956,9 +957,9 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
                        ds = (DATE_STRUCT *) ((char *) rgbValue + (bind_row * bind_size));
                    else
                        ds = (DATE_STRUCT *) rgbValue + bind_row;
-                   ds->year = st.y;
-                   ds->month = st.m;
-                   ds->day = st.d;
+                   ds->year = std_time.y;
+                   ds->month = std_time.m;
+                   ds->day = std_time.d;
                }
                break;
 
@@ -974,9 +975,9 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
                        ts = (TIME_STRUCT *) ((char *) rgbValue + (bind_row * bind_size));
                    else
                        ts = (TIME_STRUCT *) rgbValue + bind_row;
-                   ts->hour = st.hh;
-                   ts->minute = st.mm;
-                   ts->second = st.ss;
+                   ts->hour = std_time.hh;
+                   ts->minute = std_time.mm;
+                   ts->second = std_time.ss;
                }
                break;
 
@@ -992,13 +993,13 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
                        ts = (TIMESTAMP_STRUCT *) ((char *) rgbValue + (bind_row * bind_size));
                    else
                        ts = (TIMESTAMP_STRUCT *) rgbValue + bind_row;
-                   ts->year = st.y;
-                   ts->month = st.m;
-                   ts->day = st.d;
-                   ts->hour = st.hh;
-                   ts->minute = st.mm;
-                   ts->second = st.ss;
-                   ts->fraction = st.fr;
+                   ts->year = std_time.y;
+                   ts->month = std_time.m;
+                   ts->day = std_time.d;
+                   ts->hour = std_time.hh;
+                   ts->minute = std_time.mm;
+                   ts->second = std_time.ss;
+                   ts->fraction = std_time.fr;
                }
                break;
 
@@ -1202,7 +1203,13 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
 #endif /* ODBCINT64 */
            case SQL_C_BINARY:
 
-               if (PG_TYPE_BYTEA != field_type)
+               if (PG_TYPE_UNKNOWN == field_type)
+               {
+                   if (pcbValue)
+                       *(SDWORD *) ((char *) pcbValue + pcbValueOffset) = SQL_NULL_DATA;
+                   return COPY_OK;
+               }
+               else if (PG_TYPE_BYTEA != field_type)
                {
                    mylog("couldn't convert the type %d to SQL_C_BINARY\n", field_type);
                    return COPY_UNSUPPORTED_TYPE;
@@ -2513,7 +2520,7 @@ ResolveOneParam(QueryBuild *qb)
    param_string[0] = '\0';
    cbuf[0] = '\0';
    memset(&st, 0, sizeof(st));
-   t = time(NULL);
+   t = SC_get_time(qb->stmt);
 #ifdef HAVE_LOCALTIME_R
    tim = localtime_r(&t, &tm);
 #else
@@ -3709,12 +3716,12 @@ pg_bin2hex(UCHAR *src, UCHAR *dst, int length)
    return length;
 }
 
-static int
-pg_hex2bin(UCHAR *src, UCHAR *dst, int length)
+int
+pg_hex2bin(const UCHAR *src, UCHAR *dst, int length)
 {
-   UCHAR       chr,
-              *src_wk,
-              *dst_wk;
+   UCHAR       chr;
+   const UCHAR *src_wk;
+   UCHAR       *dst_wk;
    int     i, val;
    BOOL        HByte = TRUE;
 
index 157fdcae1650b1eba1577e83427f6b544670e133..9e6b4f77011215e00e99e7d142e45e0b183286ac 100644 (file)
--- a/convert.h
+++ b/convert.h
@@ -48,6 +48,7 @@ int           convert_special_chars(const char *si, char *dst, int used, BOOL convlf,int
 int            convert_pgbinary_to_char(const char *value, char *rgbValue, int cbValueMax);
 int            convert_from_pgbinary(const unsigned char *value, unsigned char *rgbValue, int cbValueMax);
 int            convert_to_pgbinary(const unsigned char *in, char *out, int len);
+int        pg_hex2bin(const UCHAR *in, UCHAR *out, int len);
 void       encode(const char *in, char *out);
 void       decode(const char *in, char *out);
 int convert_lo(StatementClass *stmt, const void *value, Int2 fCType, PTR rgbValue,
index d89d96a9656d623fa6dd9b52deed1ed8f30951b0..f01dd3ba922055fe5252cb78447f47d4213befa0 100644 (file)
@@ -319,7 +319,7 @@ copyAttributes(ConnInfo *ci, const char *attribute, const char *value)
    else if (stricmp(attribute, "CX") == 0)
        unfoldCXAttribute(ci, value);
 
-   mylog("copyAttributes: DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s',conn_settings='%s',disallow_premature=%d)\n", ci->dsn, ci->server, ci->database, ci->username, ci->password, ci->port, ci->onlyread, ci->protocol, ci->conn_settings, ci->disallow_premature);
+   mylog("copyAttributes: DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s',conn_settings='%s',disallow_premature=%d)\n", ci->dsn, ci->server, ci->database, ci->username, ci->password ? "xxxxx" : "", ci->port, ci->onlyread, ci->protocol, ci->conn_settings, ci->disallow_premature);
 }
 
 void
@@ -449,6 +449,13 @@ getDSNinfo(ConnInfo *ci, char overwrite)
    while (*(DSN + strlen(DSN) - 1) == ' ')
        *(DSN + strlen(DSN) - 1) = '\0';
 
+   if (ci->driver[0] == '\0' || overwrite)
+   {
+       SQLGetPrivateProfileString(ODBC_DATASOURCES, DSN, "", ci->driver, sizeof(ci->driver), ODBC_INI);
+       if (ci->driver[0] && stricmp(ci->driver, DBMS_NAME))
+           getCommonDefaults(ci->driver, ODBCINST_INI, ci);
+   }
+
    /* Proceed with getting info for the given DSN. */
 
    if (ci->desc[0] == '\0' || overwrite)
@@ -557,7 +564,7 @@ getDSNinfo(ConnInfo *ci, char overwrite)
         ci->port,
         ci->database,
         ci->username,
-        ci->password);
+        ci->password ? "xxxxx" : "");
    qlog("          onlyread='%s',protocol='%s',showoid='%s',fakeoidindex='%s',showsystable='%s'\n",
         ci->onlyread,
         ci->protocol,
@@ -579,33 +586,14 @@ getDSNinfo(ConnInfo *ci, char overwrite)
  * to the ODBCINST.INI portion of the registry
  */
 void
-writeDriverCommoninfo(const ConnInfo *ci)
+writeDriverCommoninfo(const char *fileName, const char *sectionName,
+            const GLOBAL_VALUES *comval)
 {
-   const char *sectionName;
-   const char *fileName;
-   const GLOBAL_VALUES *comval;
    char        tmp[128];
 
-   if (ci)
-       if (ci->dsn && ci->dsn[0])
-       {
-           mylog("DSN=%s updating\n", ci->dsn);
-           comval = &(ci->drivers);
-           sectionName = ci->dsn;
-           fileName = ODBC_INI;
-       }
-       else
-       {
-           mylog("ci but dsn==NULL\n");
-           return;
-       }
-   else
-   {
-       mylog("drivers updating\n");
-       comval = &globals;
+   if (ODBCINST_INI == fileName && NULL == sectionName)
        sectionName = DBMS_NAME;
-       fileName = ODBCINST_INI;
-   }
    sprintf(tmp, "%d", comval->fetch_max);
    SQLWritePrivateProfileString(sectionName,
                                 INI_FETCH, tmp, fileName);
@@ -631,7 +619,7 @@ writeDriverCommoninfo(const ConnInfo *ci)
    /*
     * Never update the onlyread from this module.
     */
-   if (!ci)
+   if (ODBCINST_INI == fileName)
    {
        sprintf(tmp, "%d", comval->onlyread);
        SQLWritePrivateProfileString(sectionName, INI_READONLY, tmp,
index 2066660c69c1d1778c6bfb7e40987e5b8141d9d4..4cef795d470c3f19d3ea514b8786944e0171f20d 100644 (file)
@@ -31,6 +31,7 @@
 #define ODBCINST_INI                   "ODBCINST.INI"
 #endif
 
+#define    ODBC_DATASOURCES    "ODBC Data Sources"
 
 #if (ODBCVER >= 0x0300)
 #ifdef  UNICODE_SUPPORT
@@ -202,7 +203,8 @@ int CALLBACK ds_options2Proc(HWND hdlg,
 #endif   /* WIN32 */
 
 void       updateGlobals(void);
-void       writeDriverCommoninfo(const ConnInfo *ci);
+void       writeDriverCommoninfo(const char *fileName, const char *sectionName,
+       const GLOBAL_VALUES *);
 void       writeDSNinfo(const ConnInfo *ci);
 void       getDSNdefaults(ConnInfo *ci);
 void       getDSNinfo(ConnInfo *ci, char overwrite);
index 39d0666fca7d0e03ec3926ef7ce31a4fd3327ca9..7e58fc4b047c5c3b34d58e0736a2143ef47c1762 100644 (file)
@@ -39,7 +39,7 @@ extern GLOBAL_VALUES globals;
 
 extern HINSTANCE NEAR s_hModule;
 static int driver_optionsDraw(HWND, const ConnInfo *, int src, BOOL enable);
-static int driver_options_update(HWND hdlg, ConnInfo *ci, BOOL);
+static int driver_options_update(HWND hdlg, ConnInfo *ci, const char *);
 
 void
 SetDlgStuff(HWND hdlg, const ConnInfo *ci)
@@ -48,11 +48,11 @@ SetDlgStuff(HWND hdlg, const ConnInfo *ci)
     * If driver attribute NOT present, then set the datasource name and
     * description
     */
-   if (ci->driver[0] == '\0')
-   {
+   /**if (ci->driver[0] == '\0')
+   {**/
        SetDlgItemText(hdlg, IDC_DSNAME, ci->dsn);
        SetDlgItemText(hdlg, IDC_DESC, ci->desc);
-   }
+   /**}**/
 
    SetDlgItemText(hdlg, IDC_DATABASE, ci->database);
    SetDlgItemText(hdlg, IDC_SERVER, ci->server);
@@ -170,7 +170,7 @@ driver_optionsDraw(HWND hdlg, const ConnInfo *ci, int src, BOOL enable)
 }
 
 static int
-driver_options_update(HWND hdlg, ConnInfo *ci, BOOL updateProfile)
+driver_options_update(HWND hdlg, ConnInfo *ci, const char *updateDriver)
 {
    GLOBAL_VALUES *comval;
 
@@ -218,8 +218,8 @@ driver_options_update(HWND hdlg, ConnInfo *ci, BOOL updateProfile)
    if (!ci)
        GetDlgItemText(hdlg, DRV_CONNSETTINGS, comval->conn_settings, sizeof(comval->conn_settings));
 
-   if (updateProfile)
-       writeDriverCommoninfo(ci);
+   if (updateDriver)
+       writeDriverCommoninfo(ODBCINST_INI, updateDriver, comval);
 
    /* fall through */
    return 0;
@@ -250,7 +250,7 @@ driver_optionsProc(HWND hdlg,
                case IDOK:
                    ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
                    driver_options_update(hdlg, NULL,
-                                         ci && ci->dsn && ci->dsn[0]);
+                       ci ? ci->driver : NULL);
 
                case IDCANCEL:
                    EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
@@ -291,7 +291,7 @@ global_optionsProc(HWND hdlg,
                case IDOK:
                    globals.commlog = IsDlgButtonChecked(hdlg, DRV_COMMLOG);
                    globals.debug = IsDlgButtonChecked(hdlg, DRV_DEBUG);
-                   writeDriverCommoninfo(NULL);
+                   writeDriverCommoninfo(ODBCINST_INI, NULL, &globals);
 
                case IDCANCEL:
                    EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
@@ -330,14 +330,14 @@ ds_options1Proc(HWND hdlg,
            switch (GET_WM_COMMAND_ID(wParam, lParam))
            {
                case IDOK:
-                   driver_options_update(hdlg, ci, FALSE);
+                   driver_options_update(hdlg, ci, NULL);
 
                case IDCANCEL:
                    EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
                    return TRUE;
 
                case IDAPPLY:
-                   driver_options_update(hdlg, ci, FALSE);
+                   driver_options_update(hdlg, ci, NULL);
                    SendMessage(GetWindow(hdlg, GW_OWNER), WM_COMMAND, wParam, lParam);
                    break;
 
@@ -346,7 +346,7 @@ ds_options1Proc(HWND hdlg,
                    break;
 
                case IDNEXTPAGE:
-                   driver_options_update(hdlg, ci, FALSE);
+                   driver_options_update(hdlg, ci, NULL);
 
                    EndDialog(hdlg, FALSE);
                    DialogBoxParam(s_hModule,
index ae754113767411feedcca121f70c3025631c86cb..81156477ca6eb96b3a27d1da327b98530660f970 100644 (file)
--- a/drvconn.c
+++ b/drvconn.c
 
 #include "dlg_specific.h"
 
+static char * hide_password(const char *str)
+{
+   char *outstr, *pwdp;
+
+   outstr = strdup(str);
+   if (pwdp = strstr(outstr, "PWD="), !pwdp)
+       pwdp = strstr(outstr, "pwd=");
+   if (pwdp)
+   {
+       char    *p;
+
+       for (p=pwdp + 4; *p && *p != ';'; p++)
+           *p = 'x';
+   }
+   return outstr;
+}
+
 /* prototypes */
 void       dconn_get_connect_attributes(const UCHAR FAR * connect_string, ConnInfo *ci);
 static void dconn_get_common_attributes(const UCHAR FAR * connect_string, ConnInfo *ci);
@@ -94,8 +111,19 @@ PGAPI_DriverConnect(
 
    make_string(szConnStrIn, cbConnStrIn, connStrIn);
 
+#ifdef FORCE_PASSWORD_DISPLAY
    mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn);
    qlog("conn=%u, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, connStrIn, fDriverCompletion);
+#else
+   if (get_qlog() || get_mylog())
+   {
+       char    *hide_str = hide_password(connStrIn);
+
+       mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, hide_str);
+       qlog("conn=%u, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, hide_str, fDriverCompletion);
+       free(hide_str);
+   }
+#endif /* FORCE_PASSWORD_DISPLAY */
 
    ci = &(conn->connInfo);
 
@@ -239,8 +267,19 @@ dialog:
    if (pcbConnStrOut)
        *pcbConnStrOut = len;
 
+#ifdef FORCE_PASSWORD_DISPLAY
    mylog("szConnStrOut = '%s' len=%d,%d\n", szConnStrOut, len, cbConnStrOutMax);
    qlog("conn=%u, PGAPI_DriverConnect(out)='%s'\n", conn, szConnStrOut);
+#else
+   if (get_qlog() || get_mylog())
+   {
+       char    *hide_str = hide_password(szConnStrOut);
+
+       mylog("szConnStrOut = '%s' len=%d,%d\n", hide_str, len, cbConnStrOutMax);
+       qlog("conn=%u, PGAPI_DriverConnect(out)='%s'\n", conn, hide_str);
+       free(hide_str);
+   }
+#endif /* FORCE_PASSWORD_DISPLAY */
 
 
    mylog("PGAPI_DriverConnect: returning %d\n", result);
@@ -361,7 +400,17 @@ dconn_get_connect_attributes(const UCHAR FAR * connect_string, ConnInfo *ci)
    our_connect_string = strdup(connect_string);
    strtok_arg = our_connect_string;
 
+#ifdef FORCE_PASSWORD_DISPLAY
    mylog("our_connect_string = '%s'\n", our_connect_string);
+#else
+   if (get_mylog())
+   {
+       char    *hide_str = hide_password(our_connect_string);
+
+       mylog("our_connect_string = '%s'\n", hide_str);
+       free(hide_str);
+   }
+#endif /* FORCE_PASSWORD_DISPLAY */
 
    while (1)
    {
@@ -383,7 +432,13 @@ dconn_get_connect_attributes(const UCHAR FAR * connect_string, ConnInfo *ci)
        attribute = pair;       /* ex. DSN */
        value = equals + 1;     /* ex. 'CEO co1' */
 
-       mylog("attribute = '%s', value = '%s'\n", attribute, value);
+#ifndef    FORCE_PASSWORD_DISPLAY
+       if (stricmp(attribute, INI_PASSWORD) == 0 ||
+           stricmp(attribute, "pwd") == 0)
+           mylog("attribute = '%s', value = 'xxxxx'\n", attribute);
+       else
+#endif /* FORCE_PASSWORD_DISPLAY */
+           mylog("attribute = '%s', value = '%s'\n", attribute, value);
 
        if (!attribute || !value)
            continue;
@@ -412,7 +467,17 @@ dconn_get_common_attributes(const UCHAR FAR * connect_string, ConnInfo *ci)
    our_connect_string = strdup(connect_string);
    strtok_arg = our_connect_string;
 
+#ifdef FORCE_PASSWORD_DISPLAY
    mylog("our_connect_string = '%s'\n", our_connect_string);
+#else
+   if (get_mylog())
+   {
+       char    *hide_str = hide_password(our_connect_string);
+
+       mylog("our_connect_string = '%s'\n", hide_str);
+       free(hide_str);
+   }
+#endif /* FORCE_PASSWORD_DISPLAY */
 
    while (1)
    {
@@ -434,7 +499,13 @@ dconn_get_common_attributes(const UCHAR FAR * connect_string, ConnInfo *ci)
        attribute = pair;       /* ex. DSN */
        value = equals + 1;     /* ex. 'CEO co1' */
 
-       mylog("attribute = '%s', value = '%s'\n", attribute, value);
+#ifndef    FORCE_PASSWORD_DISPLAY
+       if (stricmp(attribute, INI_PASSWORD) == 0 ||
+           stricmp(attribute, "pwd") == 0)
+           mylog("attribute = '%s', value = 'xxxxx'\n", attribute);
+       else
+#endif /* FORCE_PASSWORD_DISPLAY */
+           mylog("attribute = '%s', value = '%s'\n", attribute, value);
 
        if (!attribute || !value)
            continue;
index d4060f355c26e481c65ef0c9fc6eaa6337690a6a..6b987540095b446bf1145ed31e9076cdb608e1a1 100644 (file)
--- a/execute.c
+++ b/execute.c
@@ -930,7 +930,10 @@ PGAPI_PutData(
                retval;
    ParameterInfoClass *current_param;
    ParameterImplClass *current_iparam;
-   char       *buffer;
+   char       *buffer, *putbuf, *allocbuf = NULL;
+   Int2        ctype;
+   SDWORD      putlen;
+   BOOL        lenset = FALSE;
 
    mylog("%s: entering...\n", func);
 
@@ -951,8 +954,53 @@ PGAPI_PutData(
    current_param = &(apdopts->parameters[stmt->current_exec_param]);
    ipdopts = SC_get_IPD(stmt);
    current_iparam = &(ipdopts->parameters[stmt->current_exec_param]);
+   ctype = current_param->CType;
 
    conn = SC_get_conn(stmt);
+   if (ctype == SQL_C_DEFAULT)
+       ctype = sqltype_to_default_ctype(conn, current_iparam->SQLType);
+   if (SQL_NTS == cbValue)
+   {
+#ifdef UNICODE_SUPPORT
+       if (SQL_C_WCHAR == ctype)
+       {
+           putlen = 2 * ucs2strlen((SQLWCHAR *) rgbValue);
+           lenset = TRUE;
+       }
+       else
+#endif /* UNICODE_SUPPORT */
+       if (SQL_C_CHAR == ctype)
+       {
+           putlen = strlen(rgbValue);
+           lenset = TRUE;
+       }
+   }
+   if (!lenset)
+   {
+       if (cbValue < 0)
+           putlen = cbValue;
+       else
+#ifdef UNICODE_SUPPORT
+       if (ctype == SQL_C_CHAR || ctype == SQL_C_BINARY || ctype == SQL_C_WCHAR)
+#else
+       if (ctype == SQL_C_CHAR || ctype == SQL_C_BINARY)
+#endif /* UNICODE_SUPPORT */
+           putlen = cbValue;
+       else
+           putlen = ctype_length(ctype);
+   }
+   putbuf = rgbValue;
+   if (current_iparam->PGType == conn->lobj_type && SQL_C_CHAR == ctype)
+   {
+       allocbuf = malloc(putlen / 2 + 1);
+       if (allocbuf)
+       {
+           pg_hex2bin(rgbValue, allocbuf, putlen);
+           putbuf = allocbuf;
+           putlen /= 2;
+       }
+   }
+
    if (!stmt->put_data)
    {                           /* first call */
        mylog("PGAPI_PutData: (1) cbValue = %d\n", cbValue);
@@ -967,7 +1015,7 @@ PGAPI_PutData(
            return SQL_ERROR;
        }
 
-       *current_param->EXEC_used = cbValue;
+       *current_param->EXEC_used = putlen;
 
        if (cbValue == SQL_NULL_DATA)
            return SQL_SUCCESS;
@@ -1011,62 +1059,20 @@ PGAPI_PutData(
                return SQL_ERROR;
            }
 
-           retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue);
-           mylog("lo_write: cbValue=%d, wrote %d bytes\n", cbValue, retval);
+           retval = lo_write(stmt->hdbc, stmt->lobj_fd, putbuf, putlen);
+           mylog("lo_write: cbValue=%d, wrote %d bytes\n", putlen, retval);
        }
        else
        {
-           Int2        ctype = current_param->CType;
-           if (ctype == SQL_C_DEFAULT)
-               ctype = sqltype_to_default_ctype(conn, current_iparam->SQLType);
-
-#ifdef UNICODE_SUPPORT
-           if (SQL_NTS == cbValue && SQL_C_WCHAR == ctype)
-               cbValue = 2 * ucs2strlen((SQLWCHAR *) rgbValue);
-#endif /* UNICODE_SUPPORT */
-           /* for handling fields */
-           if (cbValue == SQL_NTS)
-           {
-               current_param->EXEC_buffer = strdup(rgbValue);
-               if (!current_param->EXEC_buffer)
-               {
-                   SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Out of memory in PGAPI_PutData (2)");
-                   SC_log_error(func, "", stmt);
-                   return SQL_ERROR;
-               }
-           }
-           else
+           current_param->EXEC_buffer = malloc(putlen + 1);
+           if (!current_param->EXEC_buffer)
            {
-#ifdef UNICODE_SUPPORT
-               if (ctype == SQL_C_CHAR || ctype == SQL_C_BINARY || ctype == SQL_C_WCHAR)
-#else
-               if (ctype == SQL_C_CHAR || ctype == SQL_C_BINARY)
-#endif /* UNICODE_SUPPORT */
-               {
-                   current_param->EXEC_buffer = malloc(cbValue + 1);
-                   if (!current_param->EXEC_buffer)
-                   {
-                       SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Out of memory in PGAPI_PutData (2)");
-                       SC_log_error(func, "", stmt);
-                       return SQL_ERROR;
-                   }
-                   memcpy(current_param->EXEC_buffer, rgbValue, cbValue);
-                   current_param->EXEC_buffer[cbValue] = '\0';
-               }
-               else
-               {
-                   Int4        used = ctype_length(ctype);
-
-                   current_param->EXEC_buffer = malloc(used);
-                   if (!current_param->EXEC_buffer)
-                   {
-                       SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Out of memory in PGAPI_PutData (2)");
-                       SC_log_error(func, "", stmt);
-                       return SQL_ERROR;
-                   }
-                   memcpy(current_param->EXEC_buffer, rgbValue, used);
-               }
+               SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Out of memory in PGAPI_PutData (2)");
+               SC_log_error(func, "", stmt);
+               return SQL_ERROR;
            }
+           memcpy(current_param->EXEC_buffer, putbuf, putlen);
+           current_param->EXEC_buffer[putlen] = '\0';
        }
    }
    else
@@ -1078,41 +1084,20 @@ PGAPI_PutData(
        if (current_iparam->PGType == conn->lobj_type)
        {
            /* the large object fd is in EXEC_buffer */
-           retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue);
-           mylog("lo_write(2): cbValue = %d, wrote %d bytes\n", cbValue, retval);
+           retval = lo_write(stmt->hdbc, stmt->lobj_fd, putbuf, putlen);
+           mylog("lo_write(2): cbValue = %d, wrote %d bytes\n", putlen, retval);
 
-           *current_param->EXEC_used += cbValue;
+           *current_param->EXEC_used += putlen;
        }
        else
        {
-           Int2    ctype = current_param->CType;
-
-           if (ctype == SQL_C_DEFAULT)
-               ctype = sqltype_to_default_ctype(conn, current_iparam->SQLType);
            buffer = current_param->EXEC_buffer;
-           if (old_pos = *current_param->EXEC_used, SQL_NTS == old_pos)
-           {
-#ifdef UNICODE_SUPPORT
-               if (SQL_C_WCHAR == ctype)
-                   old_pos = 2 * ucs2strlen((SQLWCHAR *) buffer);
-               else
-#endif /* UNICODE_SUPPORT */
-               old_pos = strlen(buffer);
-           }
-           if (SQL_NTS == cbValue)
-           {
-#ifdef UNICODE_SUPPORT
-               if (SQL_C_WCHAR == ctype)
-                   cbValue = 2 * ucs2strlen((SQLWCHAR *) rgbValue);
-               else
-#endif /* UNICODE_SUPPORT */
-               cbValue = strlen(rgbValue);
-           }
-           if (cbValue > 0)
+           old_pos = *current_param->EXEC_used;
+           if (putlen > 0)
            {
-               *current_param->EXEC_used += cbValue;
+               *current_param->EXEC_used += putlen;
 
-               mylog("        cbValue = %d, old_pos = %d, *used = %d\n", cbValue, old_pos, *current_param->EXEC_used);
+               mylog("        cbValue = %d, old_pos = %d, *used = %d\n", putlen, old_pos, *current_param->EXEC_used);
 
                /* dont lose the old pointer in case out of memory */
                buffer = realloc(current_param->EXEC_buffer, *current_param->EXEC_used + 1);
@@ -1123,7 +1108,7 @@ PGAPI_PutData(
                    return SQL_ERROR;
                }
 
-               memcpy(&buffer[old_pos], rgbValue, cbValue);
+               memcpy(&buffer[old_pos], putbuf, putlen);
                buffer[*current_param->EXEC_used] = '\0';
 
                /* reassign buffer incase realloc moved it */
@@ -1136,6 +1121,8 @@ PGAPI_PutData(
            }
        }
    }
+   if (allocbuf)
+       free(allocbuf);
 
    return SQL_SUCCESS;
 }
diff --git a/info.c b/info.c
index 85decca2923a3bcfddd986c02c5a2925411a00c6..0959dbcac0f8e3c51e446b613999331b594a6320 100644 (file)
--- a/info.c
+++ b/info.c
@@ -852,12 +852,28 @@ PGAPI_GetTypeInfo(
 
        if (fSqlType == SQL_ALL_TYPES || fSqlType == sqlType)
        {
+           int pgtcount = 1, cnt;
+
+           if (SQL_INTEGER == sqlType && PG_VERSION_GE(SC_get_conn(stmt), 6.4))
+               pgtcount = 2;
+           for (cnt = 0; cnt < pgtcount; cnt ++)
+           {
+
            row = (TupleNode *) malloc(sizeof(TupleNode) + (result_cols - 1) * sizeof(TupleField));
 
            /* These values can't be NULL */
-           set_tuplefield_string(&row->tuple[0], pgtype_to_name(stmt, pgType));
+           if (1 == cnt)
+           {
+               set_tuplefield_string(&row->tuple[0], "serial");
+               set_tuplefield_int2(&row->tuple[6], SQL_NO_NULLS);
+inolog("serial in\n");
+           }
+           else
+           {
+               set_tuplefield_string(&row->tuple[0], pgtype_to_name(stmt, pgType));
+               set_tuplefield_int2(&row->tuple[6], pgtype_nullable(stmt, pgType));
+           }
            set_tuplefield_int2(&row->tuple[1], (Int2) sqlType);
-           set_tuplefield_int2(&row->tuple[6], pgtype_nullable(stmt, pgType));
            set_tuplefield_int2(&row->tuple[7], pgtype_case_sensitive(stmt, pgType));
            set_tuplefield_int2(&row->tuple[8], pgtype_searchable(stmt, pgType));
            set_tuplefield_int2(&row->tuple[10], pgtype_money(stmt, pgType));
@@ -873,8 +889,16 @@ PGAPI_GetTypeInfo(
            set_nullfield_string(&row->tuple[3], pgtype_literal_prefix(stmt, pgType));
            set_nullfield_string(&row->tuple[4], pgtype_literal_suffix(stmt, pgType));
            set_nullfield_string(&row->tuple[5], pgtype_create_params(stmt, pgType));
-           set_nullfield_int2(&row->tuple[9], pgtype_unsigned(stmt, pgType));
-           set_nullfield_int2(&row->tuple[11], pgtype_auto_increment(stmt, pgType));
+           if (1 == cnt)
+           {
+               set_nullfield_int2(&row->tuple[9], TRUE);
+               set_nullfield_int2(&row->tuple[11], TRUE);
+           }
+           else
+           {
+               set_nullfield_int2(&row->tuple[9], pgtype_unsigned(stmt, pgType));
+               set_nullfield_int2(&row->tuple[11], pgtype_auto_increment(stmt, pgType));
+           }
            set_nullfield_int2(&row->tuple[13], pgtype_scale(stmt, pgType, PG_STATIC));
            set_nullfield_int2(&row->tuple[14], pgtype_scale(stmt, pgType, PG_STATIC));
 #if (ODBCVER >=0x0300)
@@ -885,6 +909,8 @@ PGAPI_GetTypeInfo(
 #endif /* ODBCVER */
 
            QR_add_tuple(res, row);
+
+           }
        }
    }
 
diff --git a/misc.c b/misc.c
index 7fc591e259decbfb9f1ecbf6ae6c40878b5780a5..493a3d49e597a778617574051e673e9e38ea7cc0 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -64,6 +64,16 @@ pthread_mutex_t  qlog_cs, mylog_cs;
 #endif /* WIN_MULTITHREAD_SUPPORT */
 static int mylog_on = 0,
            qlog_on = 0;
+
+int    get_mylog(void)
+{
+   return mylog_on;
+}
+int    get_qlog(void)
+{
+   return qlog_on;
+}
+
 void
 logs_on_off(int cnopen, int mylog_onoff, int qlog_onoff)
 {
diff --git a/misc.h b/misc.h
index b0a663b6c298684a40922e880ec522d25ee0b5ea..7ae9e09ee551bd8aebb5869c1ea5f2cc5cbbcf59 100644 (file)
--- a/misc.h
+++ b/misc.h
@@ -94,6 +94,8 @@ extern void qlog(char *fmt,...);
 #endif
 #endif
 #define    inoqlog qlog
+int    get_qlog(void);
+int    get_mylog(void);
 
 #ifndef WIN32
 #define DIRSEPARATOR       "/"
index d880b993cd63a8bf1d75b8631944b81b6d61852a..f661d74f4a65a620d17e473ee2c9912c7189b0d7 100644 (file)
@@ -398,7 +398,7 @@ CC_lookup_characterset(ConnectionClass *self)
                wenc = "BIG5";
                break;
        }
-       if (wenc && stricmp(encstr, wenc))
+       if (wenc && (!encstr || stricmp(encstr, wenc)))
        {
            QResultClass    *res;
            char        query[64];
diff --git a/parse.c b/parse.c
index 07f971f12f32eb32ddb872e32b1c094d5ca1746d..f3cfdcd31f5112d6718273e4ac4bcd8b62f719b4 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -293,6 +293,29 @@ searchColInfo(COL_INFO *col_info, FIELD_INFO *fi)
    return FALSE;
 }
 
+/*
+ * lower the unquoted name
+ */
+static
+void lower_the_name(char *name, ConnectionClass *conn, BOOL dquote)
+{
+   if (!dquote)
+   {
+       char        *ptr;
+       encoded_str encstr;
+       make_encoded_str(&encstr, conn, name);
+
+       /* lower case table name */
+       for (ptr = name; *ptr; ptr++)
+       {
+           encoded_nextchar(&encstr);
+           if (ENCODE_STATUS(encstr) != 0)
+               ptr++;
+           else
+               *ptr = tolower((unsigned char) *ptr);
+       }
+   }
+}
 
 char
 parse_statement(StatementClass *stmt)
@@ -661,7 +684,12 @@ parse_statement(StatementClass *stmt)
            }
            if (out_table && !in_table) /* new table */
            {
-
+               if (!dquote)
+               {
+                   if (token[0] == '(' ||
+                       token[0] == ')')
+                       continue;
+               }
                if (!(stmt->ntab % TAB_INCR))
                {
                    ti = (TABLE_INFO **) realloc(ti, (stmt->ntab + TAB_INCR) * sizeof(TABLE_INFO *));
@@ -684,22 +712,7 @@ parse_statement(StatementClass *stmt)
                ti[stmt->ntab]->updatable = 1;
 
                strcpy(ti[stmt->ntab]->name, token);
-               if (!dquote)
-               {
-                   char       *ptr;
-                   encoded_str encstr;
-                   make_encoded_str(&encstr, conn, ti[stmt->ntab]->name);
-
-                   /* lower case table name */
-                   for (ptr = ti[stmt->ntab]->name; *ptr; ptr++)
-                   {
-                       encoded_nextchar(&encstr);
-                       if (ENCODE_STATUS(encstr) != 0)
-                           ptr++;
-                       else
-                           *ptr = tolower((unsigned char) *ptr);
-                   }
-               }
+               lower_the_name(ti[stmt->ntab]->name, conn, dquote);
                mylog("got table = '%s'\n", ti[stmt->ntab]->name);
 
                if (delim == ',')
@@ -729,6 +742,7 @@ parse_statement(StatementClass *stmt)
                {
                    strcpy(ti[stmt->ntab - 1]->schema, ti[stmt->ntab - 1]->name);
                    strcpy(ti[stmt->ntab - 1]->name, token);
+                   lower_the_name(ti[stmt->ntab - 1]->name, conn, dquote);
                    in_dot = FALSE;
                    continue;
                }
index fde18269275d35692a9a302a85ed6980b8770384..38a0837bb84c4c1f717c355ab3365e883bf48e3f 100644 (file)
--- a/pgtypes.c
+++ b/pgtypes.c
@@ -79,9 +79,8 @@ Int2      sqlTypes[] = {
    SQL_CHAR,
 #if (ODBCVER >= 0x0300)
    SQL_TYPE_DATE,
-#else
-   SQL_DATE,
 #endif /* ODBCVER */
+   SQL_DATE,
    SQL_DECIMAL,
    SQL_DOUBLE,
    SQL_FLOAT,
@@ -94,10 +93,9 @@ Int2     sqlTypes[] = {
 #if (ODBCVER >= 0x0300)
    SQL_TYPE_TIME,
    SQL_TYPE_TIMESTAMP,
-#else
+#endif /* ODBCVER */
    SQL_TIME,
    SQL_TIMESTAMP,
-#endif /* ODBCVER */
    SQL_TINYINT,
    SQL_VARBINARY,
    SQL_VARCHAR,
@@ -109,9 +107,9 @@ Int2        sqlTypes[] = {
    0
 };
 
-#if (ODBCVER >= 0x0300) && defined(OBDCINT64)
-/* #define ALLOWED_C_BIGINT    SQL_C_SBIGINT */
-#define    ALLOWED_C_BIGINT    SQL_C_CHAR /* Delphi should be either ? */
+#if (ODBCVER >= 0x0300) && defined(ODBCINT64)
+#define    ALLOWED_C_BIGINT    SQL_C_SBIGINT
+/* #define ALLOWED_C_BIGINT    SQL_C_CHAR */ /* Delphi should be either ? */
 #else
 #define    ALLOWED_C_BIGINT    SQL_C_CHAR
 #endif
@@ -143,9 +141,10 @@ sqltype_to_pgtype(StatementClass *stmt, SWORD fSqlType)
            pgType = ci->drivers.bools_as_char ? PG_TYPE_CHAR : PG_TYPE_BOOL;
            break;
 
-       case SQL_DATE:
 #if (ODBCVER >= 0x0300)
        case SQL_TYPE_DATE:
+#else
+       case SQL_DATE:
 #endif /* ODBCVER */
            pgType = PG_TYPE_DATE;
            break;
@@ -304,8 +303,8 @@ pgtype_to_concise_type(StatementClass *stmt, Int4 type)
        case PG_TYPE_INT8:
            if (ci->int8_as != 0) 
                return ci->int8_as;
-           if (conn->ms_jet) 
-               return SQL_NUMERIC; /* maybe a little better than SQL_VARCHAR */
+           /***if (conn->ms_jet) 
+               return SQL_NUMERIC; ***/ /* maybe a little better than SQL_VARCHAR */
 #if (ODBCVER >= 0x0300)
            return SQL_BIGINT;
 #else
index 2eaae42524c2bff1aa6fbc2a839b01aae20db111..a00e220504a1dfa726395714f5e1c254411be417 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Comments:       See "notice.txt" for copyright and license information.
  *
- * $Id: psqlodbc.h,v 1.75 2003/01/03 16:08:14 hinoue Exp $
+ * $Id: psqlodbc.h,v 1.76 2003/04/23 09:49:47 hinoue Exp $
  *
  */
 
index 583407a3b23aabe9ee09e50e116f91ebbe57ab23..b64f6de59ab642bcafd0786a7aa9a744fc53d211 100644 (file)
--- a/qresult.c
+++ b/qresult.c
@@ -708,11 +708,10 @@ inolog("clear obsolete %d tuples\n", num_backend_rows);
                mylog("end of tuple list -- setting inUse to false: this = %u\n", self);
 
                self->inTuples = FALSE;
-               if (self->num_total_rows > 0)
+               qlog("    [ fetched %d rows ]\n", self->num_total_rows);
+               mylog("_next_tuple: 'C' fetch_total = %d & this_fetch = %d\n", self->num_total_rows, self->num_backend_rows);
+               if (self->num_backend_rows > 0)
                {
-                   qlog("    [ fetched %d rows ]\n", self->num_total_rows);
-                   mylog("_next_tuple: 'C' fetch_max && fcount = %d\n", self->num_total_rows);
-
                    /* set to first row */
                    self->tupleField = self->backend_tuples + (offset * self->num_fields);
                    return TRUE;
@@ -720,7 +719,6 @@ inolog("clear obsolete %d tuples\n", num_backend_rows);
                else
                {
                    /* We are surely done here (we read 0 tuples) */
-                   qlog("    [ fetched 0 rows ]\n");
                    mylog("_next_tuple: 'C': DONE (fcount == 0)\n");
                    return -1;  /* end of tuples */
                }
index b269eb7bab98933142bb26091740b03d4e75e18e..d2fea06519b3bc3bad0f14877377ce392c4445f3 100644 (file)
--- a/results.c
+++ b/results.c
@@ -1392,6 +1392,7 @@ PGAPI_ExtendedFetch(
            break;
 
        default:
+           SC_set_error(stmt, STMT_FETCH_OUT_OF_RANGE, "Unsupported PGAPI_ExtendedFetch Direction");
            SC_log_error(func, "Unsupported PGAPI_ExtendedFetch Direction", stmt);
            return SQL_ERROR;
    }
@@ -1839,17 +1840,24 @@ SC_pos_reload(StatementClass *stmt, UDWORD global_ridx, UWORD *count, BOOL logCh
    if (count)
        *count = 0;
    if (!(res = SC_get_Curres(stmt)))
+   {
+       SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Null statement result in SC_pos_reload.");
        return SQL_ERROR;
+   }
    if (!stmt->ti)
        parse_statement(stmt);  /* not preferable */
    if (!stmt->updatable)
    {
        stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
+       SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only");
        return SQL_ERROR;
    }
    res_ridx = global_ridx - stmt->rowset_start + res->base;
    if (!(oid = getOid(res, global_ridx)))
+   {
+       SC_set_error(stmt, STMT_ROW_VERSION_CHANGED, "the row was already deleted ?");
        return SQL_SUCCESS_WITH_INFO;
+   }
    getTid(res, global_ridx, &blocknum, &offset);
    sprintf(tidval, "(%u, %u)", blocknum, offset);
    res_cols = getNumResultCols(res);
@@ -1921,12 +1929,16 @@ SC_pos_reload_needed(StatementClass *stmt, UDWORD flag)
 
    mylog("SC_pos_reload_needed\n");
    if (!(res = SC_get_Curres(stmt)))
+   {
+       SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Null statement result in SC_pos_reload_needed.");
        return SQL_ERROR;
+   }
    if (!stmt->ti)
        parse_statement(stmt);  /* not preferable */
    if (!stmt->updatable)
    {
        stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
+       SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only");
        return SQL_ERROR;
    }
    limitrow = stmt->rowset_start + res->rowset_size;
@@ -2069,12 +2081,16 @@ SC_pos_newload(StatementClass *stmt, UInt4 oid, BOOL tidRef)
 
    mylog("positioned new ti=%x\n", stmt->ti);
    if (!(res = SC_get_Curres(stmt)))
+   {
+       SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Null statement result in SC_pos_newload.");
        return SQL_ERROR;
+   }
    if (!stmt->ti)
        parse_statement(stmt);  /* not preferable */
    if (!stmt->updatable)
    {
        stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
+       SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only");
        return SQL_ERROR;
    }
    if (qres = positioned_load(stmt, tidRef ? USE_INSERTED_TID : 0, oid, NULL), qres)
@@ -2203,19 +2219,23 @@ SC_pos_update(StatementClass *stmt,
    UInt2   pgoffset;
    Int4    *used, bind_size = opts->bind_size;
 
-   mylog("POS UPDATE %d+%d fi=%x ti=%x\n", irow, SC_get_Curres(stmt)->base,fi, stmt->ti);
    if (!(res = SC_get_Curres(stmt)))
+   {
+       SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Null statement result in SC_pos_update.");
        return SQL_ERROR;
+   }
+   mylog("POS UPDATE %d+%d fi=%x ti=%x\n", irow, res->base, fi, stmt->ti);
    if (!stmt->ti)
        parse_statement(stmt);  /* not preferable */
    if (!stmt->updatable)
    {
        stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
+       SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only");
        return SQL_ERROR;
    }
    if (!(oid = getOid(res, global_ridx)))
    {
-       SC_set_errormsg(stmt, "The row is already deleted");
+       SC_set_error(stmt, STMT_INVALID_CURSOR_POSITION, "The row is already deleted ?");
        return SQL_ERROR;
    }
    getTid(res, global_ridx, &blocknum, &pgoffset);
@@ -2264,7 +2284,10 @@ SC_pos_update(StatementClass *stmt,
                blocknum, pgoffset, oid);
        mylog("updstr=%s\n", updstr);
        if (PGAPI_AllocStmt(conn, &hstmt) != SQL_SUCCESS)
+       {
+           SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "internal AllocStmt error");
            return SQL_ERROR;
+       }
        qstmt = (StatementClass *) hstmt;
        apdopts = SC_get_APD(qstmt);
        apdopts->param_bind_type = opts->bind_size;
@@ -2311,7 +2334,7 @@ SC_pos_update(StatementClass *stmt,
    else
    {
        ret = SQL_SUCCESS_WITH_INFO;
-       SC_set_errormsg(stmt, "update list null");
+       SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "update list null");
    }
    if (SQL_SUCCESS == ret && res->keyset)
    {
@@ -2354,17 +2377,21 @@ SC_pos_delete(StatementClass *stmt,
 
    mylog("POS DELETE ti=%x\n", stmt->ti);
    if (!(res = SC_get_Curres(stmt)))
+   {
+       SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Null statement result in SC_pos_delete.");
        return SQL_ERROR;
+   }
    if (!stmt->ti)
        parse_statement(stmt);  /* not preferable */
    if (!stmt->updatable)
    {
        stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
+       SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only");
        return SQL_ERROR;
    }
    if (!(oid = getOid(res, global_ridx)))
    {
-       SC_set_errormsg(stmt, "The row is already deleted");
+       SC_set_error(stmt, STMT_INVALID_CURSOR_POSITION, "The row is already deleted ?");
        return SQL_ERROR;
    }
    getTid(res, global_ridx, &blocknum, &offset);
@@ -2516,12 +2543,16 @@ SC_pos_add(StatementClass *stmt,
 
    mylog("POS ADD fi=%x ti=%x\n", fi, stmt->ti);
    if (!(res = SC_get_Curres(stmt)))
+   {
+       SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Null statement result in SC_pos_add.");
        return SQL_ERROR;
+   }
    if (!stmt->ti)
        parse_statement(stmt);  /* not preferable */
    if (!stmt->updatable)
    {
        stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY;
+       SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only");
        return SQL_ERROR;
    }
    num_cols = irdflds->nfields;
@@ -2531,7 +2562,10 @@ SC_pos_add(StatementClass *stmt,
    else
        sprintf(addstr, "insert into \"%s\" (", stmt->ti[0]->name);
    if (PGAPI_AllocStmt(conn, &hstmt) != SQL_SUCCESS)
+   {
+       SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "internal AllocStmt error");
        return SQL_ERROR;
+   }
    if (opts->row_offset_ptr)
        offset = *opts->row_offset_ptr;
    else
@@ -2605,7 +2639,7 @@ SC_pos_add(StatementClass *stmt,
    else
    {
        ret = SQL_SUCCESS_WITH_INFO;
-       SC_set_errormsg(stmt, "insert list null");
+       SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "insert list null");
    }
    PGAPI_FreeStmt(hstmt, SQL_DROP);
    if (SQL_SUCCESS == ret && res->keyset)
@@ -2732,7 +2766,7 @@ PGAPI_SetPos(
 
    if (!(res = SC_get_Curres(stmt)))
    {
-       SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Null statement result in PGAPI_SetPos.");
+       SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Null statement result in PGAPI_SetPos.");
        SC_log_error(func, "", stmt);
        return SQL_ERROR;
    }
@@ -2750,7 +2784,7 @@ PGAPI_SetPos(
    }
    else
    {
-       if (irow > stmt->last_fetch_count)
+       if (SQL_ADD != fOption && irow > stmt->last_fetch_count)
        {
            SC_set_error(stmt, STMT_ROW_OUT_OF_RANGE, "Row value out of range");
            SC_log_error(func, "", stmt);
@@ -2842,7 +2876,6 @@ PGAPI_SetPos(
    else if (SC_get_IRD(stmt)->rowsFetched)
        *(SC_get_IRD(stmt)->rowsFetched) = processed;
    res->recent_processed_row_count = stmt->diag_row_count = processed;
-inolog("rowset=%d processed=%d ret=%d\n", opts->rowset_size, processed, ret);
    return ret; 
 }
 
diff --git a/setup.c b/setup.c
index 9fad9dba46ed9102d01bc488987cdcae330db647..a1cfa1bfba0c43aaa3bc22b9a45a37916146a745 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -395,7 +395,7 @@ SetDSNAttributes(HWND hwndParent, LPSETUPDLG lpsetupdlg)
    }
 
    /* Update ODBC.INI */
-   writeDriverCommoninfo(&lpsetupdlg->ci);
+   writeDriverCommoninfo(ODBC_INI, lpsetupdlg->ci.dsn, &(lpsetupdlg->ci.drivers));
    writeDSNinfo(&lpsetupdlg->ci);
 
    /* If the data source name has changed, remove the old name */
index ccdc82379d92836c5d5622a3bea06e9a8ccaa5e8..c9d681621a10f20d880852d14e86594c6414f6dd 100644 (file)
@@ -304,6 +304,7 @@ SC_Constructor(void)
        rv->updatable = FALSE;
        rv->error_recsize = -1;
        rv->diag_row_count = 0;
+       rv->stmt_time = 0;
        INIT_STMT_CS(rv);
    }
    return rv;
@@ -812,6 +813,15 @@ SC_get_error(StatementClass *self, int *number, char **message)
 }
 
 
+time_t
+SC_get_time(StatementClass *stmt)
+{
+   if (!stmt)
+       return time(NULL);
+   if (!stmt->stmt_time)
+       stmt->stmt_time = time(NULL);
+   return stmt->stmt_time;
+}
 /*
  * Currently, the driver offers very simple bookmark support -- it is
  * just the current row number.  But it could be more sophisticated
index c1ccc70151aa8aa96874d7a59171d657c698bf7c..85bf16e405d4e68fd10e922e7633a87649965f28 100644 (file)
@@ -10,6 +10,7 @@
 #define __STATEMENT_H__
 
 #include "psqlodbc.h"
+#include <time.h>
 
 #include "bind.h"
 #include "descriptor.h"
@@ -204,6 +205,7 @@ struct StatementClass_
    Int4        from_pos;   
    Int4        where_pos;
    Int4        last_fetch_count_include_ommitted;
+   time_t      stmt_time;
 #if defined(WIN_MULTITHREAD_SUPPORT)
    CRITICAL_SECTION    cs;
 #elif defined(POSIX_MULTITHREAD_SUPPORT)
@@ -281,6 +283,7 @@ RETCODE     SC_execute(StatementClass *self);
 RETCODE        SC_fetch(StatementClass *self);
 void       SC_free_params(StatementClass *self, char option);
 void       SC_log_error(const char *func, const char *desc, const StatementClass *self);
+time_t     SC_get_time(StatementClass *self);
 unsigned long SC_get_bookmark(StatementClass *self);
 RETCODE        SC_pos_update(StatementClass *self, UWORD irow, UDWORD index);
 RETCODE        SC_pos_delete(StatementClass *self, UWORD irow, UDWORD index);
index 6105b2a8b8f7eb39ec00c83bf5241cb9aa001fc4..097deb9dac65ae33a305a8b6ceb5206fd826f315 100644 (file)
--- a/version.h
+++ b/version.h
@@ -9,8 +9,8 @@
 #ifndef __VERSION_H__
 #define __VERSION_H__
 
-#define POSTGRESDRIVERVERSION      "07.02.0005"
-#define POSTGRES_RESOURCE_VERSION  "07.02.0005\0"
-#define PG_DRVFILE_VERSION     7,2,0,05
+#define POSTGRESDRIVERVERSION      "07.03.0001"
+#define POSTGRES_RESOURCE_VERSION  "07.03.0001\0"
+#define PG_DRVFILE_VERSION     7,3,0,01
 
 #endif