Re: Postgres odbc driver bug - Mailing list pgsql-interfaces
From | Bruce Momjian |
---|---|
Subject | Re: Postgres odbc driver bug |
Date | |
Msg-id | 200105090157.f491vBb18158@candle.pha.pa.us Whole thread Raw |
In response to | Postgres odbc driver bug (Keith Millard <Kmillard@pumatech.com>) |
List | pgsql-interfaces |
Keith, forget my earlier request about reviewing the patch. One of our ODBC guys (Hiroshi) says your patch fixes a different problem. If no one objects, I will be applying yours in a day or two. Can you make sure my version of your patch is correct? I will change the #if 0 and just remove that code, and remove your //chuck comments. Thanks. > 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-interfaces by date: