[7.3.0208]
authorHiroshi Inoue <inoue@tpf.co.jp>
Thu, 5 Feb 2004 09:11:44 +0000 (09:11 +0000)
committerHiroshi Inoue <inoue@tpf.co.jp>
Thu, 5 Feb 2004 09:11:44 +0000 (09:11 +0000)
1) Change catalog functions to search 'public' schema if a user
   tries to search the user named schema and finds no record to
   return.
2) Set the statement status to STMT_FINISHED(not STMT_PREPARED)
   if the pre execution causes an error.
3) Adjust null terminator for SQL_C_WCHAR type.
4) Change getCharColumnSize to return max size when the
   statement has no result.
5) Cache the number of parameters for statements.

13 files changed:
bind.c
connection.c
convert.c
info.c
odbcapi.c
odbcapi30w.c
odbcapiw.c
pgapifunc.h
pgtypes.c
results.c
statement.c
statement.h
version.h

diff --git a/bind.c b/bind.c
index fe2168cb693e61f27d8617c185ce6fada7a7ee95..9138daefab5fe42967b5f9f6cdeb70dd76d26cf5 100644 (file)
--- a/bind.c
+++ b/bind.c
@@ -388,7 +388,9 @@ PGAPI_NumParams(
    }
 
 
-   if (!stmt->statement)
+   if (stmt->num_params >= 0)
+       *pcpar = stmt->num_params;
+   else if (!stmt->statement)
    {
        /* no statement has been allocated */
        SC_set_error(stmt, STMT_SEQUENCE_ERROR, "PGAPI_NumParams called with no statement ready.");
@@ -407,8 +409,9 @@ PGAPI_NumParams(
                    in_quote = (in_quote ? FALSE : TRUE);
            }
        }
-       return SQL_SUCCESS;
+       stmt->num_params = *pcpar;
    }
+   return SQL_SUCCESS;
 }
 
 
@@ -553,8 +556,7 @@ APD_free_params(APDFields *apdopts, char option)
 
    if (option == STMT_FREE_PARAMS_ALL)
    {
-       if (apdopts->parameters)
-           free(apdopts->parameters);
+       free(apdopts->parameters);
        apdopts->parameters = NULL;
        apdopts->allocated = 0;
    }
@@ -588,8 +590,7 @@ PDATA_free_params(PutDataInfo *pdata, char option)
 
    if (option == STMT_FREE_PARAMS_ALL)
    {
-       if (pdata->pdata)
-           free(pdata->pdata);
+       free(pdata->pdata);
        pdata->pdata = NULL;
        pdata->allocated = 0;
    }
@@ -605,11 +606,11 @@ IPD_free_params(IPDFields *ipdopts, char option)
 {
    mylog("IPD_free_params:  ENTER, self=%d\n", ipdopts);
 
-   if (ipdopts->parameters &&
-       option == STMT_FREE_PARAMS_ALL)
+   if (!ipdopts->parameters)
+       return;
+   if (option == STMT_FREE_PARAMS_ALL)
    {
-       if (ipdopts->parameters)
-           free(ipdopts->parameters);
+       free(ipdopts->parameters);
        ipdopts->parameters = NULL;
        ipdopts->allocated = 0;
    }
index 324b3d9f5bdccad01b73a570b90d29108d04cbb6..dac2a514539b1e9b34633c3b767020611fd955c4 100644 (file)
@@ -2209,7 +2209,7 @@ CC_get_max_query_len(const ConnectionClass *conn)
 }
 
 /*
- * This deosn't really return the CURRENT SCHEMA
+ * This doesn't really return the CURRENT SCHEMA
  * but there's no alternative.
  */
 const char *
index 106b0af11b914a1b2680ffe3d54ffab85325c85c..da8818bb4bbd443df6aeffd7bd36f084a367299b 100644 (file)
--- a/convert.c
+++ b/convert.c
@@ -779,7 +779,7 @@ inolog("2stime fr=%d\n", std_time.fr);
                    if (fCType == SQL_C_CHAR)
                    {
                        wstrlen = utf8_to_ucs2_lf(neut_str, -1, lf_conv, NULL, 0);
-                       allocbuf = (SQLWCHAR *) malloc(2 * (wstrlen + 1));
+                       allocbuf = (SQLWCHAR *) malloc(WCLEN * (wstrlen + 1));
                        wstrlen = utf8_to_ucs2_lf(neut_str, -1, lf_conv, allocbuf, wstrlen + 1);
                        len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) allocbuf, wstrlen, NULL, 0, NULL, NULL);
                        changed = TRUE;
@@ -868,13 +868,13 @@ inolog("2stime fr=%d\n", std_time.fr);
                    BOOL    already_copied = FALSE;
 
                    copy_len = (len >= cbValueMax) ? cbValueMax - 1 : len;
-#ifdef WIN_UNICODE_SUPPORT
+#ifdef UNICODE_SUPPORT
                    if (fCType == SQL_C_WCHAR)
                    {
-                       copy_len /= 2;
-                       copy_len *= 2;
+                       copy_len /= WCLEN;
+                       copy_len *= WCLEN;
                    }
-#endif /* WIN_UNICODE_SUPPORT */
+#endif /* UNICODE_SUPPORT */
 #ifdef HAVE_LOCALE_H
                    switch (field_type)
                    {
@@ -908,13 +908,14 @@ inolog("2stime fr=%d\n", std_time.fr);
                    {
                        /* Copy the data */
                        memcpy(rgbValueBindRow, ptr, copy_len);
+                       /* Add null terminator */
+#ifdef UNICODE_SUPPORT
+                       if (fCType == SQL_C_WCHAR)
+                           memset(rgbValueBindRow + copy_len, 0, WCLEN);
+                       else
+#endif /* UNICODE_SUPPORT */
                        rgbValueBindRow[copy_len] = '\0';
                    }
-#ifdef WIN_UNICODE_SUPPORT
-                   if (fCType == SQL_C_WCHAR)
-                       rgbValueBindRow[copy_len + 1] = '\0';
-#endif /* WIN_UNICODE_SUPPORT */
-
                    /* Adjust data_left for next time */
                    if (stmt->current_col >= 0)
                        pgdc->data_left -= copy_len;
@@ -942,11 +943,11 @@ inolog("2stime fr=%d\n", std_time.fr);
 #ifdef UNICODE_SUPPORT
        if (SQL_C_WCHAR == fCType && ! wchanged)
        {
-           if (cbValueMax > WCLEN * len)
+           if (cbValueMax > (SDWORD) (WCLEN * len))
            {
                char *str = strdup(rgbValueBindRow);
                UInt4   ucount = utf8_to_ucs2(str, len, (SQLWCHAR *) rgbValueBindRow, cbValueMax / WCLEN);
-               if (cbValueMax < WCLEN * (SDWORD) ucount)
+               if (cbValueMax < (SDWORD) (WCLEN * ucount))
                    result = COPY_RESULT_TRUNCATED;
                len = ucount * WCLEN;
                free(str); 
@@ -2630,7 +2631,7 @@ ResolveOneParam(QueryBuild *qb)
                case SQL_WLONGVARCHAR:
                    if (SQL_NTS == used)
                        used = strlen(buffer);
-                   allocbuf = malloc(2 * (used + 1));
+                   allocbuf = malloc(WCLEN * (used + 1));
                    used = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, buffer,
                        used, (LPWSTR) allocbuf, used + 1);
                    buf = ucs2_to_utf8((SQLWCHAR *) allocbuf, used, &used, FALSE);
diff --git a/info.c b/info.c
index 3917ce1029668b4fb530268eaec64f6a1ccfcb3c..735e5b4fb4eb9883e28299f9f8801b910f95676a 100644 (file)
--- a/info.c
+++ b/info.c
 #define TRIGGER_DELETE 0x01
 #define TRIGGER_UPDATE 0x02
 
+#define    NULL_IF_NULL(a) (a ? a : "(NULL)")
 
 /* extern GLOBAL_VALUES globals; */
 
+CSTR   pubstr = "public";
 
 
 RETCODE        SQL_API
@@ -1316,10 +1318,10 @@ PGAPI_Tables(
                view,
                systable;
    int         i;
-   SWORD           internal_asis_type = SQL_C_CHAR;
-   const char *likeeq = "like";
+   SWORD           internal_asis_type = SQL_C_CHAR, cbSchemaName;
+   const char *likeeq = "like", *szSchemaName;
 
-   mylog("%s: entering...stmt=%u scnm=%x len=%d\n", func, stmt, szTableOwner, cbTableOwner);
+   mylog("%s: entering...stmt=%u scnm=%x len=%d\n", func, stmt, NULL_IF_NULL(szTableOwner), cbTableOwner);
 
    if (result = SC_initialize_and_recycle(stmt), SQL_SUCCESS != result)
        return result;
@@ -1338,7 +1340,10 @@ PGAPI_Tables(
        return SQL_ERROR;
    }
    tbl_stmt = (StatementClass *) htbl_stmt;
+   szSchemaName = szTableOwner;
+   cbSchemaName = cbTableOwner;
 
+retry_public_schema:
    /*
     * Create the query to find out the tables
     */
@@ -1364,11 +1369,11 @@ PGAPI_Tables(
 
    if (conn->schema_support)
    {
-       schema_strcat1(tables_query, " and nspname %s '%.*s'", likeeq, szTableOwner, cbTableOwner, szTableName, cbTableName, conn);
+       schema_strcat1(tables_query, " and nspname %s '%.*s'", likeeq, szSchemaName, cbSchemaName, szTableName, cbTableName, conn);
        strcat(tables_query, " and pg_catalog.pg_table_is_visible(c.oid)");
    }
    else
-       my_strcat1(tables_query, " and usename %s '%.*s'", likeeq, szTableOwner, cbTableOwner);
+       my_strcat1(tables_query, " and usename %s '%.*s'", likeeq, szSchemaName, cbSchemaName);
    my_strcat1(tables_query, " and relname %s '%.*s'", likeeq, szTableName, cbTableName);
 
    /* Parse the extra systable prefix  */
@@ -1472,6 +1477,29 @@ PGAPI_Tables(
        goto cleanup;
    }
 
+   /* If not found */
+   if (conn->schema_support &&
+       (res = SC_get_Result(tbl_stmt)) &&
+       0 == QR_get_num_total_tuples(res))
+   {
+       const char *user = CC_get_username(conn);
+
+       /*
+        * If specified schema name == user_name and
+        * the current schema is 'public',
+        * retry the 'public' schema.
+        */
+       if (szSchemaName &&
+           (cbSchemaName == SQL_NTS ||
+            cbSchemaName == (SWORD) strlen(user)) &&
+           strnicmp(szSchemaName, user, strlen(user)) == 0 &&
+           stricmp(CC_get_current_schema(conn), pubstr) == 0)
+       {
+           szSchemaName = pubstr;
+           cbSchemaName = SQL_NTS;
+           goto retry_public_schema;
+       }
+   }
 #ifdef UNICODE_SUPPORT
    if (conn->unicode)
        internal_asis_type = INTERNAL_ASIS_TYPE;
@@ -1707,7 +1735,7 @@ PGAPI_Columns(
    StatementClass *stmt = (StatementClass *) hstmt;
    QResultClass    *res;
    TupleNode  *row;
-   HSTMT       hcol_stmt;
+   HSTMT       hcol_stmt = NULL;
    StatementClass *col_stmt;
    char        columns_query[INFO_INQUIRY_LEN];
    RETCODE     result;
@@ -1731,10 +1759,10 @@ PGAPI_Columns(
    BOOL        relisaview;
    ConnInfo   *ci;
    ConnectionClass *conn;
-   SWORD       internal_asis_type = SQL_C_CHAR;
-   const char *likeeq = "like";
+   SWORD       internal_asis_type = SQL_C_CHAR, cbSchemaName;
+   const char *likeeq = "like", *szSchemaName;
 
-   mylog("%s: entering...stmt=%u scnm=%x len=%d\n", func, stmt, szTableOwner, cbTableOwner);
+   mylog("%s: entering...stmt=%u scnm=%x len=%d\n", func, stmt, NULL_IF_NULL(szTableOwner), cbTableOwner);
 
    if (result = SC_initialize_and_recycle(stmt), SQL_SUCCESS != result)
        return result;
@@ -1748,7 +1776,10 @@ PGAPI_Columns(
    if (conn->unicode)
        internal_asis_type = INTERNAL_ASIS_TYPE;
 #endif /* UNICODE_SUPPORT */
+   szSchemaName = szTableOwner;
+   cbSchemaName = cbTableOwner;
 
+retry_public_schema:
    /*
     * Create the query to find out the columns (Note: pre 6.3 did not
     * have the atttypmod field)
@@ -1774,9 +1805,9 @@ PGAPI_Columns(
    {
        my_strcat(columns_query, " and c.relname = '%.*s'", szTableName, cbTableName);
        if (conn->schema_support)
-           schema_strcat(columns_query, " and u.nspname = '%.*s'", szTableOwner, cbTableOwner, szTableName, cbTableName, conn);
+           schema_strcat(columns_query, " and u.nspname = '%.*s'", szSchemaName, cbSchemaName, szTableName, cbTableName, conn);
        else
-           my_strcat(columns_query, " and u.usename = '%.*s'", szTableOwner, cbTableOwner);
+           my_strcat(columns_query, " and u.usename = '%.*s'", szSchemaName, cbSchemaName);
        my_strcat(columns_query, " and a.attname = '%.*s'", szColumnName, cbColumnName);
    }
    else
@@ -1787,9 +1818,9 @@ PGAPI_Columns(
        escTbnamelen = reallyEscapeCatalogEscapes(szTableName, cbTableName, esc_table_name, sizeof(esc_table_name), conn->ccsc);
        my_strcat1(columns_query, " and c.relname %s '%.*s'", likeeq, esc_table_name, escTbnamelen);
        if (conn->schema_support)
-           schema_strcat1(columns_query, " and u.nspname %s '%.*s'", likeeq, szTableOwner, cbTableOwner, szTableName, cbTableName, conn);
+           schema_strcat1(columns_query, " and u.nspname %s '%.*s'", likeeq, szSchemaName, cbSchemaName, szTableName, cbTableName, conn);
        else
-           my_strcat1(columns_query, " and u.usename %s '%.*s'", likeeq, szTableOwner, cbTableOwner);
+           my_strcat1(columns_query, " and u.usename %s '%.*s'", likeeq, szSchemaName, cbSchemaName);
        my_strcat1(columns_query, " and a.attname %s '%.*s'", likeeq, szColumnName, cbColumnName);
    }
 
@@ -1824,9 +1855,34 @@ PGAPI_Columns(
    if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
    {
        SC_full_error_copy(stmt, col_stmt);
-       SC_log_error(func, "", stmt);
-       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-       return SQL_ERROR;
+       goto cleanup;
+   }
+
+   /* If not found */
+   if (conn->schema_support &&
+       (flag & PODBC_SEARCH_PUBLIC_SCHEMA) != 0 &&
+       (res = SC_get_Result(col_stmt)) &&
+       0 == QR_get_num_total_tuples(res))
+   {
+       const char *user = CC_get_username(conn);
+
+       /*
+        * If specified schema name == user_name and
+        * the current schema is 'public',
+        * retry the 'public' schema.
+        */
+       if (szSchemaName &&
+           (cbSchemaName == SQL_NTS ||
+            cbSchemaName == (SWORD) strlen(user)) &&
+           strnicmp(szSchemaName, user, strlen(user)) == 0 &&
+           stricmp(CC_get_current_schema(conn), pubstr) == 0)
+       {
+           PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
+           hcol_stmt = NULL;
+           szSchemaName = pubstr;
+           cbSchemaName = SQL_NTS;
+           goto retry_public_schema;
+       }
    }
 
    result = PGAPI_BindCol(hcol_stmt, 1, internal_asis_type,
@@ -1834,9 +1890,7 @@ PGAPI_Columns(
    if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
    {
        SC_error_copy(stmt, col_stmt);
-       SC_log_error(func, "", stmt);
-       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-       return SQL_ERROR;
+       goto cleanup;
    }
 
    result = PGAPI_BindCol(hcol_stmt, 2, internal_asis_type,
@@ -1844,9 +1898,7 @@ PGAPI_Columns(
    if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
    {
        SC_error_copy(stmt, col_stmt);
-       SC_log_error(func, "", stmt);
-       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-       return SQL_ERROR;
+       goto cleanup;
    }
 
    result = PGAPI_BindCol(hcol_stmt, 3, internal_asis_type,
@@ -1854,9 +1906,7 @@ PGAPI_Columns(
    if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
    {
        SC_error_copy(stmt, col_stmt);
-       SC_log_error(func, "", stmt);
-       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-       return SQL_ERROR;
+       goto cleanup;
    }
 
    result = PGAPI_BindCol(hcol_stmt, 4, SQL_C_LONG,
@@ -1864,9 +1914,7 @@ PGAPI_Columns(
    if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
    {
        SC_error_copy(stmt, col_stmt);
-       SC_log_error(func, "", stmt);
-       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-       return SQL_ERROR;
+       goto cleanup;
    }
 
    result = PGAPI_BindCol(hcol_stmt, 5, internal_asis_type,
@@ -1874,9 +1922,7 @@ PGAPI_Columns(
    if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
    {
        SC_error_copy(stmt, col_stmt);
-       SC_log_error(func, "", stmt);
-       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-       return SQL_ERROR;
+       goto cleanup;
    }
 
    result = PGAPI_BindCol(hcol_stmt, 6, SQL_C_SHORT,
@@ -1884,9 +1930,7 @@ PGAPI_Columns(
    if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
    {
        SC_error_copy(stmt, col_stmt);
-       SC_log_error(func, "", stmt);
-       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-       return SQL_ERROR;
+       goto cleanup;
    }
 
    result = PGAPI_BindCol(hcol_stmt, 7, SQL_C_LONG,
@@ -1894,9 +1938,7 @@ PGAPI_Columns(
    if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
    {
        SC_error_copy(stmt, col_stmt);
-       SC_log_error(func, "", stmt);
-       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-       return SQL_ERROR;
+       goto cleanup;
    }
 
    result = PGAPI_BindCol(hcol_stmt, 8, SQL_C_LONG,
@@ -1904,9 +1946,7 @@ PGAPI_Columns(
    if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
    {
        SC_error_copy(stmt, col_stmt);
-       SC_log_error(func, "", stmt);
-       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-       return SQL_ERROR;
+       goto cleanup;
    }
 
    result = PGAPI_BindCol(hcol_stmt, 9, internal_asis_type,
@@ -1914,9 +1954,7 @@ PGAPI_Columns(
    if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
    {
        SC_error_copy(stmt, col_stmt);
-       SC_log_error(func, "", stmt);
-       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-       return SQL_ERROR;
+       goto cleanup;
    }
 
    result = PGAPI_BindCol(hcol_stmt, 10, internal_asis_type,
@@ -1924,9 +1962,7 @@ PGAPI_Columns(
    if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
    {
        SC_error_copy(stmt, col_stmt);
-       SC_log_error(func, "", stmt);
-       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-       return SQL_ERROR;
+       goto cleanup;
    }
 
    result = PGAPI_BindCol(hcol_stmt, 11, internal_asis_type,
@@ -1934,17 +1970,13 @@ PGAPI_Columns(
    if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
    {
        SC_error_copy(stmt, col_stmt);
-       SC_log_error(func, "", stmt);
-       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-       return SQL_ERROR;
+       goto cleanup;
    }
 
    if (res = QR_Constructor(), !res)
    {
        SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for PGAPI_Columns result.");
-       SC_log_error(func, "", stmt);
-       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-       return SQL_ERROR;
+       goto cleanup;
    }
    SC_set_Result(stmt, res);
 
@@ -2193,9 +2225,7 @@ PGAPI_Columns(
    if (result != SQL_NO_DATA_FOUND)
    {
        SC_full_error_copy(stmt, col_stmt);
-       SC_log_error(func, "", stmt);
-       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-       return SQL_ERROR;
+       goto cleanup;
    }
 
    /*
@@ -2240,7 +2270,9 @@ PGAPI_Columns(
        QR_add_tuple(res, row);
        ordinal++;
    }
+   result = SQL_SUCCESS;
 
+cleanup:
    /*
     * also, things need to think that this statement is finished so the
     * results can be retrieved.
@@ -2252,9 +2284,13 @@ PGAPI_Columns(
    stmt->rowset_start = -1;
    SC_set_current_col(stmt, -1);
 
-   PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
+   if (SQL_SUCCESS != result &&
+       SQL_SUCCESS_WITH_INFO != result)
+       SC_log_error(func, "", stmt);
+   if (hcol_stmt)
+       PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
    mylog("%s: EXIT,  stmt=%u\n", func, stmt);
-   return SQL_SUCCESS;
+   return result;
 }
 
 
@@ -2283,9 +2319,10 @@ PGAPI_SpecialColumns(
    RETCODE     result;
    char        relhasrules[MAX_INFO_STRING], relkind[8], relhasoids[8];
    BOOL        relisaview;
-   SWORD       internal_asis_type = SQL_C_CHAR;
+   SWORD       internal_asis_type = SQL_C_CHAR, cbSchemaName;
+   const char  *szSchemaName;
 
-   mylog("%s: entering...stmt=%u scnm=%x len=%d colType=%d\n", func, stmt, szTableOwner, cbTableOwner, fColType);
+   mylog("%s: entering...stmt=%u scnm=%x len=%d colType=%d\n", func, stmt, NULL_IF_NULL(szTableOwner), cbTableOwner, fColType);
 
    if (result = SC_initialize_and_recycle(stmt), SQL_SUCCESS != result)
        return result;
@@ -2297,7 +2334,10 @@ PGAPI_SpecialColumns(
 #endif /* UNICODE_SUPPORT */
 
    stmt->manual_result = TRUE;
+   szSchemaName = szTableOwner;
+   cbSchemaName = cbTableOwner;
 
+retry_public_schema:
    /*
     * Create the query to find out if this is a view or not...
     */
@@ -2316,9 +2356,9 @@ PGAPI_SpecialColumns(
    my_strcat(columns_query, " and c.relname = '%.*s'", szTableName, cbTableName);
    /* SchemaName cannot contain a string search pattern */
    if (conn->schema_support)
-       schema_strcat(columns_query, " and u.nspname = '%.*s'", szTableOwner, cbTableOwner, szTableName, cbTableName, conn);
+       schema_strcat(columns_query, " and u.nspname = '%.*s'", szSchemaName, cbSchemaName, szTableName, cbTableName, conn);
    else
-       my_strcat(columns_query, " and u.usename = '%.*s'", szTableOwner, cbTableOwner);
+       my_strcat(columns_query, " and u.usename = '%.*s'", szSchemaName, cbSchemaName);
 
 
    result = PGAPI_AllocStmt(stmt->hdbc, &hcol_stmt);
@@ -2341,6 +2381,32 @@ PGAPI_SpecialColumns(
        return SQL_ERROR;
    }
 
+   /* If not found */
+   if (conn->schema_support &&
+       (res = SC_get_Result(col_stmt)) &&
+       0 == QR_get_num_total_tuples(res))
+   {
+       const char *user = CC_get_username(conn);
+
+       /*
+        * If specified schema name == user_name and
+        * the current schema is 'public',
+        * retry the 'public' schema.
+        */
+       if (szSchemaName &&
+           (cbSchemaName == SQL_NTS ||
+            cbSchemaName == (SWORD) strlen(user)) &&
+           strnicmp(szSchemaName, user, strlen(user)) == 0 &&
+           stricmp(CC_get_current_schema(conn), pubstr) == 0)
+       {
+           PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
+           hcol_stmt = NULL;
+           szSchemaName = pubstr;
+           cbSchemaName = SQL_NTS;
+           goto retry_public_schema;
+       }
+   }
+
    result = PGAPI_BindCol(hcol_stmt, 1, internal_asis_type,
                    relhasrules, sizeof(relhasrules), NULL);
    if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
@@ -2517,9 +2583,10 @@ PGAPI_Statistics(
    int         total_columns = 0;
    ConnInfo   *ci;
    char        buf[256];
-   SWORD       internal_asis_type = SQL_C_CHAR;
+   SWORD       internal_asis_type = SQL_C_CHAR, cbSchemaName;
+   const char  *szSchemaName;
 
-   mylog("%s: entering...stmt=%u scnm=%x len=%d\n", func, stmt, szTableOwner, cbTableOwner);
+   mylog("%s: entering...stmt=%u scnm=%x len=%d\n", func, stmt, NULL_IF_NULL(szTableOwner), cbTableOwner);
 
    if (result = SC_initialize_and_recycle(stmt), SQL_SUCCESS != result)
        return result;
@@ -2574,12 +2641,14 @@ PGAPI_Statistics(
    if (!table_name)
    {
        SC_set_error(stmt, STMT_INTERNAL_ERROR, "No table name passed to PGAPI_Statistics.");
-       SC_log_error(func, "", stmt);
-       return SQL_ERROR;
+       goto cleanup;
    }
+   szSchemaName = szTableOwner;
+   cbSchemaName = cbTableOwner;
+
    table_qualifier[0] = '\0';
    if (conn->schema_support)
-       schema_strcat(table_qualifier, "%.*s", szTableOwner, cbTableOwner, szTableName, cbTableName, conn);
+       schema_strcat(table_qualifier, "%.*s", szSchemaName, cbSchemaName, szTableName, cbTableName, conn);
 
    /*
     * we need to get a list of the field names first, so we can return
@@ -2603,7 +2672,7 @@ PGAPI_Statistics(
     * table_name parameter cannot contain a string search pattern. 
     */
    result = PGAPI_Columns(hcol_stmt, "", 0, table_qualifier, SQL_NTS,
-                          table_name, SQL_NTS, "", 0, PODBC_NOT_SEARCH_PATTERN);
+                          table_name, SQL_NTS, "", 0, PODBC_NOT_SEARCH_PATTERN | PODBC_SEARCH_PUBLIC_SCHEMA);
    col_stmt->internal = FALSE;
 
    if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
@@ -2623,6 +2692,8 @@ PGAPI_Statistics(
    result = PGAPI_Fetch(hcol_stmt);
    while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO))
    {
+       if (0 == total_columns)
+           PGAPI_GetData(hcol_stmt, 2, internal_asis_type, table_qualifier, sizeof(table_qualifier), NULL);
        total_columns++;
 
        column_names =
@@ -2638,13 +2709,13 @@ PGAPI_Statistics(
        result = PGAPI_Fetch(hcol_stmt);
    }
 
-   PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
-   hcol_stmt = NULL;
    if (result != SQL_NO_DATA_FOUND)
    {
        SC_full_error_copy(stmt, col_stmt);
        goto cleanup;
    }
+   PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
+   hcol_stmt = NULL;
    if (total_columns == 0)
    {
        /* Couldn't get column names in SQLStatistics.; */
@@ -2871,13 +2942,6 @@ PGAPI_Statistics(
        SC_full_error_copy(stmt, indx_stmt);
        goto cleanup;
    }
-
-   /*
-    * also, things need to think that this statement is finished so the
-    * results can be retrieved.
-    */
-   stmt->status = STMT_FINISHED;
-
    ret = SQL_SUCCESS;
 
 cleanup:
@@ -2903,13 +2967,11 @@ cleanup:
        free(column_names);
    }
 
-   if (SQL_SUCCESS == ret)
-   {
-       /* set up the current tuple pointer for SQLFetch */
-       stmt->currTuple = -1;
-       stmt->rowset_start = -1;
-       SC_set_current_col(stmt, -1);
-   }
+   /* set up the current tuple pointer for SQLFetch */
+   stmt->currTuple = -1;
+   stmt->rowset_start = -1;
+   SC_set_current_col(stmt, -1);
+
    mylog("%s: EXIT, stmt=%u, ret=%d\n", func, stmt, ret);
 
    return ret;
@@ -2976,9 +3038,10 @@ PGAPI_PrimaryKeys(
    int         qno,
                qstart,
                qend;
-   SWORD       internal_asis_type = SQL_C_CHAR;
+   SWORD       internal_asis_type = SQL_C_CHAR, cbSchemaName;
+   const char  *szSchemaName;
 
-   mylog("%s: entering...stmt=%u scnm=%x len=%d\n", func, stmt, szTableOwner, cbTableOwner);
+   mylog("%s: entering...stmt=%u scnm=%x len=%d\n", func, stmt, NULL_IF_NULL(szTableOwner), cbTableOwner);
 
    if (result = SC_initialize_and_recycle(stmt), SQL_SUCCESS != result)
        return result;
@@ -3026,6 +3089,7 @@ PGAPI_PrimaryKeys(
    if (conn->unicode)
        internal_asis_type = INTERNAL_ASIS_TYPE;
 #endif /* UNICODE_SUPPORT */
+
    pktab[0] = '\0';
    make_string(szTableName, cbTableName, pktab);
    if (pktab[0] == '\0')
@@ -3033,9 +3097,13 @@ PGAPI_PrimaryKeys(
        SC_set_error(stmt, STMT_INTERNAL_ERROR, "No Table specified to PGAPI_PrimaryKeys.");
        goto cleanup;
    }
+   szSchemaName = szTableOwner;
+   cbSchemaName = cbTableOwner;
+
+retry_public_schema:
    pkscm[0] = '\0';
    if (conn->schema_support)
-       schema_strcat(pkscm, "%.*s", szTableOwner, cbTableOwner, szTableName, cbTableName, conn);
+       schema_strcat(pkscm, "%.*s", szSchemaName, cbSchemaName, szTableName, cbTableName, conn);
 
    result = PGAPI_BindCol(htbl_stmt, 1, internal_asis_type,
                           attname, MAX_INFO_STRING, &attname_len);
@@ -3133,6 +3201,29 @@ PGAPI_PrimaryKeys(
            break;
    }
 
+   /* If not found */
+   if (conn->schema_support &&
+       SQL_NO_DATA_FOUND == result)
+   {
+       const char *user = CC_get_username(conn);
+
+       /*
+        * If specified schema name == user_name and
+        * the current schema is 'public',
+        * retry the 'public' schema.
+        */
+       if (szSchemaName &&
+           (cbSchemaName == SQL_NTS ||
+            cbSchemaName == (SWORD) strlen(user)) &&
+           strnicmp(szSchemaName, user, strlen(user)) == 0 &&
+           stricmp(CC_get_current_schema(conn), pubstr) == 0)
+       {
+           szSchemaName = pubstr;
+           cbSchemaName = SQL_NTS;
+           goto retry_public_schema;
+       }
+   }
+
    while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO))
    {
        row = (TupleNode *) malloc(sizeof(TupleNode) + (result_cols - 1) *sizeof(TupleField));
@@ -4209,6 +4300,7 @@ char      schema_fetched[SCHEMA_NAME_STORAGE_LEN + 1];
        goto cleanup;
    }
    ret = SQL_SUCCESS;
+
 cleanup:
    /*
     * also, things need to think that this statement is finished so the
@@ -4576,9 +4668,10 @@ PGAPI_TablePrivileges(
    char        (*useracl)[ACLMAX], *acl, *user, *delim, *auth;
    char        *reln, *owner, *priv, *schnm = NULL;
    RETCODE     result;
-   const char *likeeq = "like";
+   const char *likeeq = "like", *szSchemaName;
+   SWORD   cbSchemaName;
 
-   mylog("%s: entering... scnm=%x len-%d\n", func, szTableOwner, cbTableOwner);
+   mylog("%s: entering... scnm=%x len-%d\n", func, NULL_IF_NULL(szTableOwner), cbTableOwner);
    if (result = SC_initialize_and_recycle(stmt), SQL_SUCCESS != result)
        return result;
 
@@ -4611,6 +4704,10 @@ PGAPI_TablePrivileges(
    stmt->currTuple = -1;
    stmt->rowset_start = -1;
    SC_set_current_col(stmt, -1);
+   szSchemaName = szTableOwner;
+   cbSchemaName = cbTableOwner;
+
+retry_public_schema:
    if (conn->schema_support)
        strncpy_null(proc_query, "select relname, usename, relacl, nspname"
        " from pg_catalog.pg_namespace, pg_catalog.pg_class ,"
@@ -4622,7 +4719,7 @@ PGAPI_TablePrivileges(
    {
        if (conn->schema_support)
        {
-           schema_strcat(proc_query, " nspname = '%.*s' and", szTableOwner, cbTableOwner, szTableName, cbTableName, conn);
+           schema_strcat(proc_query, " nspname = '%.*s' and", szSchemaName, cbSchemaName, szTableName, cbTableName, conn);
        }
        my_strcat(proc_query, " relname = '%.*s' and", szTableName, cbTableName);
    }
@@ -4633,7 +4730,7 @@ PGAPI_TablePrivileges(
 
        if (conn->schema_support)
        {
-           escTbnamelen = reallyEscapeCatalogEscapes(szTableOwner, cbTableOwner, esc_table_name, sizeof(esc_table_name), conn->ccsc);
+           escTbnamelen = reallyEscapeCatalogEscapes(szSchemaName, cbSchemaName, esc_table_name, sizeof(esc_table_name), conn->ccsc);
            schema_strcat1(proc_query, " nspname %s '%.*s' and", likeeq, esc_table_name, escTbnamelen, szTableName, cbTableName, conn);
        }
        escTbnamelen = reallyEscapeCatalogEscapes(szTableName, cbTableName, esc_table_name, sizeof(esc_table_name), conn->ccsc);
@@ -4654,8 +4751,33 @@ PGAPI_TablePrivileges(
        SC_set_error(stmt, STMT_EXEC_ERROR, "PGAPI_TablePrivileges query error");
        return SQL_ERROR;
    }
-   strncpy_null(proc_query, "select usename, usesysid, usesuper from pg_user", sizeof(proc_query));
    tablecount = QR_get_num_backend_tuples(res);
+   /* If not found */
+   if (conn->schema_support &&
+       (flag & PODBC_SEARCH_PUBLIC_SCHEMA) != 0 &&
+       0 == tablecount)
+   {
+       const char *user = CC_get_username(conn);
+
+       /*
+        * If specified schema name == user_name and
+        * the current schema is 'public',
+        * retry the 'public' schema.
+        */
+       if (szSchemaName &&
+           (cbSchemaName == SQL_NTS ||
+            cbSchemaName == (SWORD) strlen(user)) &&
+           strnicmp(szSchemaName, user, strlen(user)) == 0 &&
+           stricmp(CC_get_current_schema(conn), pubstr) == 0)
+       {
+           QR_Destructor(res);
+           szSchemaName = pubstr;
+           cbSchemaName = SQL_NTS;
+           goto retry_public_schema;
+       }
+   }
+
+   strncpy_null(proc_query, "select usename, usesysid, usesuper from pg_user", sizeof(proc_query));
    if (allures = CC_send_query(conn, proc_query, NULL, CLEAR_RESULT_ON_ABORT), !allures)
    {
        QR_Destructor(res);
index d191b82bef3958205504728e4b0c82663751489a..cfd97ba70d44b5e8b25a520e0d1ba95907d43b39 100644 (file)
--- a/odbcapi.c
+++ b/odbcapi.c
@@ -115,6 +115,7 @@ SQLColumns(HSTMT StatementHandle,
    StatementClass *stmt = (StatementClass *) StatementHandle;
    SQLCHAR *ctName = CatalogName, *scName = SchemaName,
        *tbName = TableName, *clName = ColumnName;
+   UWORD   flag = PODBC_SEARCH_PUBLIC_SCHEMA;
 
    mylog("[%s]", func);
    ENTER_STMT_CS(stmt);
@@ -124,7 +125,7 @@ SQLColumns(HSTMT StatementHandle,
    else
        ret = PGAPI_Columns(StatementHandle, ctName, NameLength1,
                scName, NameLength2, tbName, NameLength3,
-               clName, NameLength4, 0);
+               clName, NameLength4, flag);
    if (SQL_SUCCESS == ret && 0 == QR_get_num_total_tuples(SC_get_Result(stmt))) 
    {
        BOOL    ifallupper = TRUE, reexec = FALSE;
@@ -157,7 +158,7 @@ SQLColumns(HSTMT StatementHandle,
        {
            ret = PGAPI_Columns(StatementHandle, ctName, NameLength1,
                scName, NameLength2, tbName, NameLength3,
-               clName, NameLength4, 0);
+               clName, NameLength4, flag);
            if (newCt)
                free(newCt);
            if (newSc)
@@ -328,13 +329,17 @@ SQLExecDirect(HSTMT StatementHandle,
 RETCODE        SQL_API
 SQLExecute(HSTMT StatementHandle)
 {
+   CSTR func = "SQLExecute";
    RETCODE ret;
    StatementClass *stmt = (StatementClass *) StatementHandle;
 
-   mylog("[SQLExecute]");
+   mylog("[%s]", func);
    ENTER_STMT_CS(stmt);
    SC_clear_error(stmt);
-   ret = PGAPI_Execute(StatementHandle, 0);
+   if (SC_opencheck(stmt, func))
+       ret = SQL_ERROR;
+   else
+       ret = PGAPI_Execute(StatementHandle, 0);
    LEAVE_STMT_CS(stmt);
    return ret;
 }
index 6ac15a9c1652c5c6564098579dbe7c9ec28c8674..79616a30459ebd4dbb62942794bf21674704fcf3 100644 (file)
@@ -229,13 +229,13 @@ RETCODE SQL_API   SQLGetDiagRecW(SWORD fHandleType,
 }
 
 RETCODE SQL_API SQLColAttributeW(
-    HSTMT           hstmt,
-    SQLUSMALLINT       icol,
-    SQLUSMALLINT       fDescType,
-    PTR            rgbDesc,
-    SQLSMALLINT        cbDescMax,
-    SQLSMALLINT      *pcbDesc,
-    SQLINTEGER           *pfDesc)
+   SQLHSTMT        hstmt,
+   SQLUSMALLINT    iCol,
+   SQLUSMALLINT    iField,
+   SQLPOINTER      pCharAttr,
+   SQLSMALLINT     cbCharAttrMax,  
+   SQLSMALLINT  *pcbCharAttr,
+   SQLPOINTER      pNumAttr)
 {
    RETCODE ret;
    BOOL    alloced = FALSE;
@@ -245,7 +245,7 @@ RETCODE SQL_API SQLColAttributeW(
    mylog("[SQLColAttributeW]");
    ENTER_STMT_CS((StatementClass *) hstmt);
    SC_clear_error((StatementClass *) hstmt);
-   switch (fDescType)
+   switch (iField)
    { 
        case SQL_DESC_BASE_COLUMN_NAME:
        case SQL_DESC_BASE_TABLE_NAME:
@@ -260,31 +260,31 @@ RETCODE SQL_API SQLColAttributeW(
        case SQL_DESC_TYPE_NAME:
        case SQL_COLUMN_NAME:
            alloced = TRUE;
-           bMax = cbDescMax * 3 / 2;
+           bMax = cbCharAttrMax * 3 / 2;
            rgbD = malloc(bMax + 1);
            rgbL = &blen;
                    break;
        default:
-           rgbD = rgbDesc;
-           bMax = cbDescMax;
-           rgbL = pcbDesc;
+           rgbD = pCharAttr;
+           bMax = cbCharAttrMax;
+           rgbL = pcbCharAttr;
            break;
    }
 
-   ret = PGAPI_ColAttributes(hstmt, icol, fDescType, rgbD,
-       bMax, rgbL, pfDesc);
+   ret = PGAPI_ColAttributes(hstmt, iCol, iField, rgbD,
+       bMax, rgbL, pNumAttr);
    if (alloced)
    {
-       blen = utf8_to_ucs2(rgbD, blen, (SQLWCHAR *) rgbDesc, cbDescMax / 2);
-       if (SQL_SUCCESS == ret && blen * 2 > cbDescMax)
+       blen = utf8_to_ucs2(rgbD, blen, (SQLWCHAR *) pCharAttr, cbCharAttrMax / 2);
+       if (SQL_SUCCESS == ret && blen * 2 > cbCharAttrMax)
        {
            StatementClass  *stmt = (StatementClass *) hstmt;
 
            ret = SQL_SUCCESS_WITH_INFO;
-           SC_set_error(stmt, STMT_TRUNCATED, "The buffer was too small for the rgbDesc.");
+           SC_set_error(stmt, STMT_TRUNCATED, "The buffer was too small for the pCharAttr.");
        }
-       if (pcbDesc)
-           *pcbDesc = blen * 2;
+       if (pcbCharAttr)
+           *pcbCharAttr = blen * 2;
        free(rgbD);
    }
    LEAVE_STMT_CS((StatementClass *) hstmt);
index 49859f8eca0871edc0c2329342acc0c0c7ad8711..fd62b05db0bf9b2eeab3fb1e60ae8a0942d18658 100644 (file)
@@ -48,7 +48,7 @@ RETCODE  SQL_API SQLColumnsW(HSTMT StatementHandle,
    ENTER_STMT_CS(stmt);
    ret = PGAPI_Columns(StatementHandle, ctName, (SWORD) nmlen1,
                scName, (SWORD) nmlen2, tbName, (SWORD) nmlen3,
-               clName, (SWORD) nmlen4, 0);
+               clName, (SWORD) nmlen4, PODBC_SEARCH_PUBLIC_SCHEMA);
    LEAVE_STMT_CS(stmt);
    if (ctName)
        free(ctName);
index 16ed19603450fb1d2c387f6f9a42fe1e71190b9f..484f6505a4daf19bf056c2f8c77650916c1758a8 100644 (file)
@@ -12,6 +12,7 @@
 
 /* Internal flags for catalog functions */
 #define    PODBC_NOT_SEARCH_PATTERN    1L
+#define    PODBC_SEARCH_PUBLIC_SCHEMA  (1L << 1)
 /* Internal flags for PGAPI_Exec... functions */
 #define    PODBC_WITH_HOLD         1L
 /* Flags for the error handling */
index 773982ccc2aacda7046e10ee32fd5675a73a9bd4..ff37ac9dce14faf017b4c2223f1c7007df8e27f6 100644 (file)
--- a/pgtypes.c
+++ b/pgtypes.c
@@ -704,7 +704,8 @@ getCharColumnSize(StatementClass *stmt, Int4 type, int col, int handle_unknown_s
    if (col < 0)
        return maxsize;
 
-   result = SC_get_Curres(stmt);
+   if (result = SC_get_Curres(stmt), NULL == result)
+       return maxsize;
 
    /*
     * Manual Result Sets -- use assigned column width (i.e., from
index 43616e3a76c0894dbff7385433f713b862e26327..a79c097836aedcecf2e315f148f4a8094491a3f4 100644 (file)
--- a/results.c
+++ b/results.c
@@ -140,7 +140,13 @@ PGAPI_NumResultCols(
        if ((!result) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE)))
        {
            /* no query has been executed on this statement */
-           SC_set_error(stmt, STMT_SEQUENCE_ERROR, "No query has been executed with that handle");
+           SC_set_error(stmt, STMT_EXEC_ERROR, "No query has been executed with that handle");
+           SC_log_error(func, "", stmt);
+           return SQL_ERROR;
+       }
+       else if (!QR_command_maybe_successful(result))
+       {
+           SC_set_errornumber(stmt, STMT_EXEC_ERROR);
            SC_log_error(func, "", stmt);
            return SQL_ERROR;
        }
index ef4e2466ad4684888e74af49c366cfca358eeb64..ebb47dbc0703cd13b5ba1051727ac128d9015314 100644 (file)
@@ -243,6 +243,7 @@ SC_Constructor(void)
        rv->status = STMT_ALLOCATED;
        rv->internal = FALSE;
        rv->transition_status = 0;
+       rv->num_params = -1; /* unknown */
 
        rv->__error_message = NULL;
        rv->__error_number = 0;
@@ -371,8 +372,11 @@ SC_Destructor(StatementClass *self)
 void
 SC_free_params(StatementClass *self, char option)
 {
-   APD_free_params(SC_get_APDF(self), option);
-   IPD_free_params(SC_get_IPDF(self), option);
+   if (option != STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY)
+   {
+       APD_free_params(SC_get_APDF(self), option);
+       IPD_free_params(SC_get_IPDF(self), option);
+   }
    PDATA_free_params(SC_get_PDTI(self), option);
    self->data_at_exec = -1;
    self->current_exec_param = -1;
@@ -469,7 +473,9 @@ SC_initialize_stmts(StatementClass *self, BOOL initializeOriginal)
        }
        self->prepare = FALSE;
        SC_set_prepared(self, FALSE);
-       self->statement_type = STMT_TYPE_UNKNOWN;
+       self->statement_type = STMT_TYPE_UNKNOWN; /* unknown */
+       self->status = STMT_READY;
+       self->num_params = -1; /* unknown */
    }
    if (self->stmt_with_params)
    {
@@ -648,15 +654,18 @@ SC_pre_execute(StatementClass *self)
        if (self->statement_type == STMT_TYPE_SELECT)
        {
            char        old_pre_executing = self->pre_executing;
+           RETCODE     ret;
 
            self->pre_executing = TRUE;
            self->inaccurate_result = FALSE;
 
-           PGAPI_Execute(self, 0);
+           ret = PGAPI_Execute(self, 0);
 
            self->pre_executing = old_pre_executing;
 
-           if (self->status == STMT_FINISHED)
+           if (self->status == STMT_FINISHED &&
+               (SQL_SUCCESS == ret ||
+                SQL_SUCCESS_WITH_INFO == ret))
            {
                mylog("              preprocess: after status = FINISHED, so set PREMATURE\n");
                self->status = STMT_PREMATURE;
index 04588a37eef6681b6957848c6b0f0f4ce9129c12..39b9d9ff9f8aba744a538a2a970ec81db99e337b 100644 (file)
@@ -200,6 +200,7 @@ struct StatementClass_
    char        transition_status;  /* Transition status */
    char        cursor_name[MAX_CURSOR_LEN + 1];
 
+   Int2        num_params;     /* number of parameters */
    char       *stmt_with_params;       /* statement after parameter
                                         * substitution */
    int         stmt_size_limit;
index bfe57ee2378d00c532037619911ad5e432a20c91..b0586a2778fc37e5ba01af7c6d951a87445685d3 100644 (file)
--- a/version.h
+++ b/version.h
@@ -9,8 +9,8 @@
 #ifndef __VERSION_H__
 #define __VERSION_H__
 
-#define POSTGRESDRIVERVERSION      "07.03.0207"
-#define POSTGRES_RESOURCE_VERSION  "07.03.0207\0"
-#define PG_DRVFILE_VERSION     7,3,2,07
+#define POSTGRESDRIVERVERSION      "07.03.0208"
+#define POSTGRES_RESOURCE_VERSION  "07.03.0208\0"
+#define PG_DRVFILE_VERSION     7,3,2,08
 
 #endif