diff -c psqlodbc.orig\connection.c psqlodbc.cancel_abort\connection.c *** psqlodbc.orig\connection.c Sun Dec 04 22:16:28 2005 --- psqlodbc.cancel_abort\connection.c Wed Dec 07 13:05:05 2005 *************** *** 1423,1443 **** CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag) { QResultClass *cmdres = NULL, ! *retres = NULL, ! *res ; BOOL clear_result_on_abort = ((flag & CLEAR_RESULT_ON_ABORT) != 0), ! create_keyset = ((flag & CREATE_KEYSET) != 0), ! issue_begin = ((flag & GO_INTO_TRANSACTION) != 0 && !CC_is_in_trans(self)); ! char *wq; ! int id=0; PGconn *pgconn = self->pgconn; ! int maxlen, ! empty_reqs; ! BOOL ReadyToReturn = FALSE, ! query_completed = FALSE, ! before_64 = PG_VERSION_LT(self, 6.4), ! aborted = FALSE, ! used_passed_result_object = FALSE; int func_cs_count = 0; --- 1423,1436 ---- CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi, UDWORD flag) { QResultClass *cmdres = NULL, ! *retres = NULL, ! *res ; BOOL clear_result_on_abort = ((flag & CLEAR_RESULT_ON_ABORT) != 0), ! create_keyset = ((flag & CREATE_KEYSET) != 0), ! issue_begin = ((flag & GO_INTO_TRANSACTION) != 0 && !CC_is_in_trans(self)); PGconn *pgconn = self->pgconn; ! int maxlen; ! BOOL used_passed_result_object = FALSE; int func_cs_count = 0; *************** *** 1467,1483 **** if (issue_begin) { res = LIBPQ_execute_query(self,"BEGIN"); ! QR_Destructor(res); } res = LIBPQ_execute_query(self,query); ! if((!res) || (res->status == PGRES_EMPTY_QUERY) ) { QR_Destructor(res); res = NULL; goto cleanup; } else if (res->status == PGRES_COMMAND_OK) { mylog("send_query: done sending command\n"); --- 1460,1492 ---- if (issue_begin) { res = LIBPQ_execute_query(self,"BEGIN"); ! if ((!res) || (res->status != PGRES_COMMAND_OK)) ! { ! CC_set_error(self, CONNECTION_COULD_NOT_SEND, "Could not send Query to backend"); ! CC_on_abort(self, NO_TRANS | CONN_DEAD); ! QR_Destructor(res); ! res = NULL; ! goto cleanup; ! } } res = LIBPQ_execute_query(self,query); ! if(!res) ! { ! goto cleanup; ! } ! #ifdef NOT_USED ! else if ((res->status == PGRES_EMPTY_QUERY) || (res->status == PGRES_FATAL_ERROR) || ! (res->status == PGRES_BAD_RESPONSE)) { + mylog("send_query: failed -> abort\n"); + QR_set_aborted(res, TRUE); QR_Destructor(res); res = NULL; goto cleanup; } + #endif /* NOT_USED */ else if (res->status == PGRES_COMMAND_OK) { mylog("send_query: done sending command\n"); *************** *** 1485,1575 **** } else { ! mylog("send_query: done sending query\n"); - empty_reqs = 0; - for (wq = query; isspace((UCHAR) *wq); wq++) - ; - if (*wq == '\0') - empty_reqs = 1; cmdres = qi ? qi->result_in : NULL; if (cmdres) used_passed_result_object = TRUE; if (!used_passed_result_object) { if (create_keyset) QR_set_haskeyset(res->next); if (!QR_fetch_tuples(res, self, qi ? qi->cursor : NULL)) { CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, QR_get_message(res)); - if (PGRES_FATAL_ERROR == QR_get_status(res)) - retres = cmdres; - else - retres = NULL; } } else ! { /* next fetch, so reuse an existing result */ ! /* ! * called from QR_next_tuple and must return ! * immediately. ! */ if (!QR_fetch_tuples(res, NULL, NULL)) { CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, QR_get_message(res)); ! retres = NULL; } - retres = cmdres; } } cleanup: CLEANUP_FUNC_CONN_CS(func_cs_count, self); ! /* ! * Cleanup garbage results before returning. ! */ ! if (cmdres && retres != cmdres && !used_passed_result_object) ! { ! QR_Destructor(cmdres); ! } /* * Cleanup the aborted result if specified */ if (retres) { ! if (aborted) { ! if (clear_result_on_abort) ! { ! if (!used_passed_result_object) ! { ! QR_Destructor(retres); ! retres = NULL; ! } ! } ! if (retres) ! { ! /* ! * discard results other than errors. ! */ ! QResultClass *qres; ! for (qres = retres; qres->next; qres = retres) ! { ! if (QR_get_aborted(qres)) ! break; ! retres = qres->next; ! qres->next = NULL; ! QR_Destructor(qres); ! } ! /* ! * If error message isn't set ! */ ! if (retres && (!CC_get_errormsg(self) || !CC_get_errormsg(self)[0])) ! CC_set_errormsg(self, QR_get_message(retres)); ! } } } - #undef return return res; } --- 1494,1564 ---- } else { ! mylog("send_query: done sending query with status: %i\n",res->status); cmdres = qi ? qi->result_in : NULL; if (cmdres) used_passed_result_object = TRUE; if (!used_passed_result_object) { + if ((res->status == PGRES_EMPTY_QUERY) || (res->status == PGRES_FATAL_ERROR) || + (res->status == PGRES_BAD_RESPONSE)) + { + mylog("send_query: sended query failed -> abort\n"); + QR_set_aborted(res, TRUE); + QR_Destructor(res); + res = NULL; + goto cleanup; + } if (create_keyset) QR_set_haskeyset(res->next); if (!QR_fetch_tuples(res, self, qi ? qi->cursor : NULL)) { CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, QR_get_message(res)); } } else ! { ! /* next fetch, so reuse an existing result */ ! mylog("send_query: next fetch -> reuse result\n"); if (!QR_fetch_tuples(res, NULL, NULL)) { CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, QR_get_message(res)); ! if (PGRES_FATAL_ERROR == QR_get_status(res)) ! { ! QR_set_aborted(res, TRUE); ! retres = cmdres; ! } } } } cleanup: CLEANUP_FUNC_CONN_CS(func_cs_count, self); ! #undef return /* * Cleanup the aborted result if specified */ if (retres) { ! /* ! * discard results other than errors. ! */ ! QResultClass *qres; ! for (qres = retres; qres->next; qres = retres) { ! if (QR_get_aborted(qres)) ! break; ! retres = qres->next; ! qres->next = NULL; ! QR_Destructor(qres); } + /* + * If error message isn't set + */ + if (retres && (!CC_get_errormsg(self) || !CC_get_errormsg(self)[0])) + CC_set_errormsg(self, QR_get_message(retres)); } return res; } *************** *** 1782,1788 **** LIBPQ_execute_query(ConnectionClass *self,char *query) { QResultClass *qres; ! PGresult *pgres; char errbuffer[ERROR_MSG_LENGTH + 1]; int pos=0; --- 1771,1777 ---- LIBPQ_execute_query(ConnectionClass *self,char *query) { QResultClass *qres; ! PGresult *pgres = NULL, *pgresnew = NULL; char errbuffer[ERROR_MSG_LENGTH + 1]; int pos=0; *************** *** 1791,1803 **** if(!qres) { CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, "Could not allocate memory for result set"); QR_Destructor(qres); ! return NULL; } ! PQsetNoticeProcessor(self->pgconn, CC_handle_notice, qres); ! pgres = PQexec(self->pgconn,query); ! PQsetNoticeProcessor(self->pgconn, CC_handle_notice, NULL); mylog("LIBPQ_execute_query: query = %s\n",query); --- 1780,1806 ---- if(!qres) { CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, "Could not allocate memory for result set"); + CC_on_abort(self, CONN_DEAD); QR_Destructor(qres); ! return NULL; } ! PQsetNoticeProcessor(self->pgconn, CC_handle_notice, qres); ! if (!PQsendQuery(self->pgconn,query)) ! { ! CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, "Could not send query to backend"); ! CC_on_abort(self, CONN_DEAD); ! QR_Destructor(qres); ! return NULL; ! } ! while (pgresnew = PQgetResult(self->pgconn)) ! { ! mylog("LIBPQ_execute_query: get next result with status = %i\n",PQresultStatus(pgresnew)); ! if (pgres) ! PQclear(pgres); ! pgres = pgresnew; ! } ! PQsetNoticeProcessor(self->pgconn, CC_handle_notice, NULL); mylog("LIBPQ_execute_query: query = %s\n",query);