Re: [INTERFACES] Postgres odbc driver bug - Mailing list pgsql-odbc
| From | Bruce Momjian |
|---|---|
| Subject | Re: [INTERFACES] Postgres odbc driver bug |
| Date | |
| Msg-id | 200105081655.f48GtkL12980@candle.pha.pa.us Whole thread Raw |
| List | pgsql-odbc |
OK, I have created a context diff of your changes, which is attached.
Can someone comment on this? The patch appears to deal with
STMT_PREMATURE differently than our current code.
In fact, it seems to disable this code:
/*
* If the statement is premature, it means we already executed it from
* an SQLPrepare/SQLDescribeCol type of scenario. So just return
* success.
*/
if (stmt->prepare && stmt->status == STMT_PREMATURE)
> We have found a reproducible problem with the Postgres ODBC driver. It has
> to do with the parameter replacement feature in the driver. Below is a
> piece of test code that shows the problem. We were able to fix the problem
> by making a change to execute.c in the ODBC driver code (attached).
>
> odbc driver version : Found in both 6.50 and 7.01.0004.
> postgresql database version : Found with both 7.0.2 and 7.0.3 versions of
> Postgres.
> Server Operating System: Windows2000
> Client Operation System: Windows2000
>
> Explanation of the odbc driver bug:
>
>
> /*****************************************
> * ERROR HAPPENS HERE:
> * If we set the buffer that we binded to column "text1" now, it will
> FAIL.
> * The SQLExecute in doQuery() will succeed (finding 0 rows), and the
> * SQLFetchScroll call will return SQL_NO_DATA_FOUND.
> *
> * This is because of a bug in the odbc driver. The call to
> SQLNumResultCols
> * will execute the query in the driver, but the buffer that is binded is
>
> * empty, so no rows will be found. This of course assumes that the
> table
> * doesn't contain any empty records for the "text1" column, which is
> correct
> * for our test. Then when we call SQLExcute, the driver will realize it
> has
> * already done the query work and will not do it again, even though our
> * buffer for parameter substitution has changed (next line of code below
>
> * this comment).
> *****************************************/
>
> Zip file is attached. The code is currently set up to fail, but I describe
> in my comments that you can uncomment the code that sets the buffer before
> SQLNumResultCols to make things will work.
>
> Thanks for your attention,
> Keith Millard
>
>
> _____
>
> <http://www.swifttouch.com/SwiftCardJump.asp?SwiftLink=95NN9NB1Q1FWA> Alex
> Shore..
> Senior Software Engineer..
> Pumatech..
> tel 603-888-0666 x1017..
> ..
> ashore@pumatech.com..
> www.pumatech.com..
>
>
[ Attachment, skipping... ]
[ Attachment, skipping... ]
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
> subscribe-nomail command to majordomo@postgresql.org so that your
> message can get through to the mailing list cleanly
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
*** e2 Tue May 8 12:49:51 2001
--- execute.c Tue May 8 12:47:48 2001
***************
*** 204,209 ****
--- 204,210 ----
it from an SQLPrepare/SQLDescribeCol type of scenario. So
just return success.
*/
+ #if 0 //chuck
if ( stmt->prepare && stmt->status == STMT_PREMATURE) {
stmt->status = STMT_FINISHED;
if (stmt->errormsg == NULL) {
***************
*** 216,221 ****
--- 217,223 ----
return SQL_ERROR;
}
}
+ #endif
mylog("%s: clear errors...\n", func);
***************
*** 248,255 ****
}
/* Check if the statement is in the correct state */
! if ((stmt->prepare && stmt->status != STMT_READY) ||
! (stmt->status != STMT_ALLOCATED && stmt->status != STMT_READY)) {
stmt->errornumber = STMT_STATUS_ERROR;
stmt->errormsg = "The handle does not point to a statement that is ready to be executed";
--- 250,259 ----
}
/* Check if the statement is in the correct state */
! //chuck if ((stmt->prepare && stmt->status != STMT_READY) ||
! //chuck (stmt->status != STMT_ALLOCATED && stmt->status != STMT_READY)) {
! if ((stmt->prepare && (stmt->status != STMT_READY && stmt->status != STMT_PREMATURE)) || //chuck
! (stmt->status != STMT_ALLOCATED && stmt->status != STMT_READY && stmt->status != STMT_PREMATURE)) { //chuck
stmt->errornumber = STMT_STATUS_ERROR;
stmt->errormsg = "The handle does not point to a statement that is ready to be executed";
***************
*** 262,270 ****
--- 266,277 ----
/* The bound parameters could have possibly changed since the last execute
of this statement? Therefore check for params and re-copy.
*/
+ mylog("%s: Check for data at execution parameters\n", func);
+ mylog("%s: stmt->parameters_allocated = %d\n", func,stmt->parameters_allocated);
stmt->data_at_exec = -1;
for (i = 0; i < stmt->parameters_allocated; i++) {
/* Check for data at execution parameters */
+ mylog("%s: stmt->parameters[%d].data_at_exec = %d\n", func,i,stmt->parameters[i].data_at_exec);
if ( stmt->parameters[i].data_at_exec == TRUE) {
if (stmt->data_at_exec < 0)
stmt->data_at_exec = 1;
pgsql-odbc by date: