diff -c psqlodbc.cleanup.orig\info.c psqlodbc.cleanup\info.c *** psqlodbc.cleanup.orig\info.c Wed Nov 30 13:44:22 2005 --- psqlodbc.cleanup\info.c Tue Dec 20 15:21:11 2005 *************** *** 810,816 **** if (result = SC_initialize_and_recycle(stmt), SQL_SUCCESS != result) return result; ! stmt->manual_result = TRUE; if (res = QR_Constructor(), !res) { SC_log_error(func, "Error creating result.", stmt); --- 810,816 ---- if (result = SC_initialize_and_recycle(stmt), SQL_SUCCESS != result) return result; ! stmt->manual_result = (BOOL)2; if (res = QR_Constructor(), !res) { SC_log_error(func, "Error creating result.", stmt); diff -c psqlodbc.cleanup.orig\options.c psqlodbc.cleanup\options.c *** psqlodbc.cleanup.orig\options.c Wed Nov 30 13:44:27 2005 --- psqlodbc.cleanup\options.c Tue Dec 20 14:35:12 2005 *************** *** 672,696 **** } ridx = GIdx2ResultIdx(stmt->currTuple, stmt, res); ! if (stmt->manual_result || !SC_is_fetchcursor(stmt)) { ! /* make sure we're positioned on a valid row */ ! if ((ridx < 0) || ! (ridx >= QR_get_num_backend_tuples(res))) ! { ! SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row."); ! SC_log_error(func, "", stmt); ! return SQL_ERROR; ! } ! } ! else ! { ! if (stmt->currTuple < 0 || !res->tupleField) ! { ! SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row."); ! SC_log_error(func, "", stmt); ! return SQL_ERROR; ! } } if (fOption == SQL_GET_BOOKMARK && stmt->options.use_bookmarks == SQL_UB_OFF) --- 672,684 ---- } ridx = GIdx2ResultIdx(stmt->currTuple, stmt, res); ! /* make sure we're positioned on a valid row */ ! if ((ridx < 0) || ! (ridx >= QR_get_num_backend_tuples(res))) { ! SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row."); ! SC_log_error(func, "", stmt); ! return SQL_ERROR; } if (fOption == SQL_GET_BOOKMARK && stmt->options.use_bookmarks == SQL_UB_OFF) diff -c psqlodbc.cleanup.orig\pgtypes.c psqlodbc.cleanup\pgtypes.c *** psqlodbc.cleanup.orig\pgtypes.c Wed Nov 30 13:44:31 2005 --- psqlodbc.cleanup\pgtypes.c Tue Dec 20 17:25:29 2005 *************** *** 438,444 **** case PG_TYPE_BPCHAR: case PG_TYPE_VARCHAR: case PG_TYPE_TEXT: ! if (conn->unicode && ! conn->ms_jet && ! stmt->manual_result) return SQL_C_WCHAR; return SQL_C_CHAR; #endif --- 438,444 ---- case PG_TYPE_BPCHAR: case PG_TYPE_VARCHAR: case PG_TYPE_TEXT: ! if (conn->unicode && ! conn->ms_jet && (stmt->manual_result != (BOOL)2)) return SQL_C_WCHAR; return SQL_C_CHAR; #endif *************** *** 535,541 **** { Int4 atttypmod = -1, default_decimal_digits = 6; QResultClass *result; - ColumnInfoClass *flds; mylog("getNumericDecimalDigits: type=%d, col=%d\n", type, col); --- 535,540 ---- *************** *** 544,567 **** result = SC_get_Curres(stmt); ! /* ! * Manual Result Sets -- use assigned column width (i.e., from ! * set_tuplefield_string) ! */ ! if (stmt->manual_result) ! { ! flds = result->fields; ! if (flds) ! { ! atttypmod = flds->atttypmod[col]; ! if (atttypmod < 0 && flds->adtsize[col] > 0) ! return flds->adtsize[col]; ! } ! if (atttypmod < 0) ! return default_decimal_digits; ! } ! else ! atttypmod = QR_get_atttypmod(result, col); if (atttypmod > -1) return (atttypmod & 0xffff); else --- 543,553 ---- result = SC_get_Curres(stmt); ! atttypmod = QR_get_atttypmod(result,col); ! if (atttypmod < 0 && QR_get_fieldsize(result,col) > 0) ! return QR_get_fieldsize(result,col); ! if (atttypmod < 0) ! return default_decimal_digits; if (atttypmod > -1) return (atttypmod & 0xffff); else *************** *** 582,588 **** Int4 atttypmod = -1; Int4 default_column_size = 28; QResultClass *result; - ColumnInfoClass *flds; mylog("getNumericColumnSize: type=%d, col=%d\n", type, col); --- 568,573 ---- *************** *** 591,614 **** result = SC_get_Curres(stmt); ! /* ! * Manual Result Sets -- use assigned column width (i.e., from ! * set_tuplefield_string) ! */ ! if (stmt->manual_result) ! { ! flds = result->fields; ! if (flds) ! { ! atttypmod = flds->atttypmod[col]; ! if (atttypmod < 0 && flds->adtsize[col] > 0) ! return 2 * flds->adtsize[col]; ! } ! if (atttypmod < 0) ! return default_column_size; ! } ! else ! atttypmod = QR_get_atttypmod(result, col); if (atttypmod > -1) return (atttypmod >> 16) & 0xffff; else --- 576,586 ---- result = SC_get_Curres(stmt); ! atttypmod = QR_get_atttypmod(result,col); ! if (atttypmod < 0 && QR_get_fieldsize(result,col) > 0) ! return 2*QR_get_fieldsize(result,col); ! if (atttypmod < 0) ! return default_column_size; if (atttypmod > -1) return (atttypmod >> 16) & 0xffff; else *************** *** 630,636 **** int p = -1, attlen = -1, maxsize; QResultClass *result; - ColumnInfoClass *flds; ConnectionClass *conn = SC_get_conn(stmt); ConnInfo *ci = &(conn->connInfo); --- 602,607 ---- *************** *** 676,693 **** if (result = SC_get_Curres(stmt), NULL == result) return maxsize; ! /* ! * Manual Result Sets -- use assigned column width (i.e., from ! * set_tuplefield_string) ! */ ! if (stmt->manual_result) ! { ! flds = result->fields; ! if (flds) ! return flds->adtsize[col]; ! else ! return maxsize; ! } p = QR_get_display_size(result, col); /* longest */ attlen = QR_get_atttypmod(result, col); --- 647,656 ---- if (result = SC_get_Curres(stmt), NULL == result) return maxsize; ! if (QR_get_fieldsize(result,col) > 0) ! return QR_get_fieldsize(result,col); ! ! mylog("getCharColumnSize: unknown column size\n"); p = QR_get_display_size(result, col); /* longest */ attlen = QR_get_atttypmod(result, col); *************** *** 706,711 **** --- 669,676 ---- } } + mylog("getCharColumnSize: still unknown column size\n"); + /* The type is really unknown */ if (type == PG_TYPE_BPCHAR || handle_unknown_size_as == UNKNOWNS_AS_LONGEST) { *************** *** 738,744 **** ConnectionClass *conn = SC_get_conn(stmt); Int4 atttypmod; QResultClass *result; - ColumnInfoClass *flds; mylog("getTimestampDecimalDigits: type=%d, col=%d\n", type, col); --- 703,708 ---- *************** *** 749,769 **** result = SC_get_Curres(stmt); ! /* ! * Manual Result Sets -- use assigned column width (i.e., from ! * set_tuplefield_string) ! */ ! atttypmod = 0; ! if (stmt->manual_result) ! { ! flds = result->fields; ! if (flds) ! atttypmod = flds->atttypmod[col]; ! mylog("atttypmod1=%d\n", atttypmod); ! } ! else ! atttypmod = QR_get_atttypmod(result, col); ! mylog("atttypmod2=%d\n", atttypmod); return (atttypmod > -1 ? atttypmod : 6); } --- 713,720 ---- result = SC_get_Curres(stmt); ! atttypmod = QR_get_atttypmod(result,col); ! mylog("atttypmod=%d\n", atttypmod); return (atttypmod > -1 ? atttypmod : 6); } diff -c psqlodbc.cleanup.orig\qresult.c psqlodbc.cleanup\qresult.c *** psqlodbc.cleanup.orig\qresult.c Wed Nov 30 13:44:33 2005 --- psqlodbc.cleanup\qresult.c Tue Dec 20 15:35:14 2005 *************** *** 490,790 **** } return ret; - } - - - /* This function is called by fetch_tuples() AND SQLFetch() */ - - int - QR_next_tuple(QResultClass *self) - { - int id; - QResultClass *res; - ConnectionClass *conn; - - /* Speed up access */ - int fetch_count = self->fetch_count; - int num_backend_rows = self->num_backend_rows; - int fetch_size, - offset = 0; - int end_tuple = self->rowset_size + self->base; - char corrected = FALSE; - TupleField *the_tuples = self->backend_tuples; - - char fetch[128]; - QueryInfo qi; - ConnInfo *ci = NULL; - - if (fetch_count < num_backend_rows) - { - /* return a row from cache */ - mylog("next_tuple: fetch_count < fcount: returning tuple %d, fcount = %d\n", fetch_count, num_backend_rows); - self->tupleField = the_tuples + (fetch_count * self->num_fields); /* next row */ - self->fetch_count++; - return TRUE; - } - else if (self->num_backend_rows < self->cache_size) - { - /* last row from cache */ - /* We are done because we didn't even get CACHE_SIZE tuples */ - mylog("next_tuple: fcount < CACHE_SIZE: fcount = %d, fetch_count = %d\n", num_backend_rows, fetch_count); - self->tupleField = NULL; - /* self->status = PGRES_END_TUPLES;*/ - /* end of tuples */ - return -1; - } - else - { - /* - * See if we need to fetch another group of rows. We may be being - * called from send_query(), and if so, don't send another fetch, - * just fall through and read the tuples. - */ - self->tupleField = NULL; - if (!self->inTuples) - { - ci = &(self->conn->connInfo); - if (!self->cursor || !ci->drivers.use_declarefetch) - { - mylog("next_tuple: ALL_ROWS: done, fcount = %d, fetch_count = %d\n", self->num_total_rows, fetch_count); - self->tupleField = NULL; - /* self->status = PGRES_END_TUPLES;*/ - return -1; /* end of tuples */ - } - - if (self->base == num_backend_rows) - { - int row, lf; - TupleField *tuple = self->backend_tuples; - - /* not a correction */ - /* Determine the optimum cache size. */ - if (ci->drivers.fetch_max % self->rowset_size == 0) - fetch_size = ci->drivers.fetch_max; - else if (self->rowset_size < ci->drivers.fetch_max) - fetch_size = (ci->drivers.fetch_max / self->rowset_size) * self->rowset_size; - else - fetch_size = self->rowset_size; - - self->cache_size = fetch_size; - /* clear obsolete tuples */ - inolog("clear obsolete %d tuples\n", num_backend_rows); - for (row = 0; row < num_backend_rows; row++) - { - for (lf = 0; lf < self->num_fields; lf++) - { - if (tuple[lf].value != NULL) - { - free(tuple[lf].value); - tuple[lf].value = NULL; - } - } - tuple += self->num_fields; - } - self->fetch_count = 1; - } - else - { - /* need to correct */ - corrected = TRUE; - - fetch_size = end_tuple - num_backend_rows; - - self->cache_size += fetch_size; - - offset = self->fetch_count; - self->fetch_count++; - } - - if (!self->backend_tuples || self->cache_size > self->count_backend_allocated) - { - self->count_backend_allocated = 0; - if (self->num_fields > 0) - { - QR_REALLOC_return_with_error(self->backend_tuples, TupleField, - (self->num_fields * sizeof(TupleField) * self->cache_size), - self, "Out of memory while reading tuples.", FALSE) - self->count_backend_allocated = self->cache_size; - } - } - if (self->haskeyset && (!self->keyset || self->cache_size > self->count_keyset_allocated)) - { - self->count_keyset_allocated = 0; - QR_REALLOC_return_with_error(self->keyset, KeySet, - (sizeof(KeySet) * self->cache_size), - self, "Out of memory while reading tuples.", FALSE) - self->count_keyset_allocated = self->cache_size; - } - sprintf(fetch, "fetch %d in %s", fetch_size, self->cursor); - - mylog("next_tuple: sending actual fetch (%d) query '%s'\n", fetch_size, fetch); - - /* don't read ahead for the next tuple (self) ! */ - qi.row_size = self->cache_size; - qi.result_in = self; - qi.cursor = NULL; - res = CC_send_query(self->conn, fetch, &qi, CLEAR_RESULT_ON_ABORT); - if (res == NULL) - { - self->status = PGRES_FATAL_ERROR; - QR_set_message(self, "Error fetching next group."); - return FALSE; - } - self->inTuples = TRUE; - } - else - { - mylog("next_tuple: inTuples = true, falling through: fcount = %d, fetch_count = %d\n", self->num_backend_rows, self->fetch_count); - - /* - * This is a pre-fetch (fetching rows right after query but - * before any real SQLFetch() calls. This is done so the - * field attributes are available. - */ - self->fetch_count = 0; - } - } - if (!corrected) - { - self->base = 0; - self->num_backend_rows = 0; - } - - conn = self->conn; - self->tupleField = NULL; - ci = &(self->conn->connInfo); - - for (;;) - { - if (!self->cursor || !ci->drivers.use_declarefetch) - { - if (self->num_fields > 0 && - self->num_total_rows >= self->count_backend_allocated) - { - int tuple_size = self->count_backend_allocated; - mylog("REALLOC: old_count = %d, size = %d\n", tuple_size, self->num_fields * sizeof(TupleField) * tuple_size); - tuple_size *= 2; - QR_REALLOC_return_with_error(self->backend_tuples, TupleField, - (tuple_size * self->num_fields * sizeof(TupleField)), - self, "Out of memory while reading tuples.", FALSE) - self->count_backend_allocated = tuple_size; - } - if (self->haskeyset && self->num_total_rows >= self->count_keyset_allocated) - { - int tuple_size = self->count_keyset_allocated; - tuple_size *= 2; - QR_REALLOC_return_with_error(self->keyset, KeySet, - (sizeof(KeySet) * tuple_size), - self, "Out of memory while reading tuples.", FALSE) - self->count_keyset_allocated = tuple_size; - } - } - id = 67; - if (!QR_read_tuple(self, (char) (id==0))) - { - self->status = PGRES_BAD_RESPONSE; - QR_set_message(self, "Error reading the tuple"); - return FALSE; - } - self->num_total_rows++; - if (self->num_fields > 0) - self->num_backend_rows++; - if (self->num_backend_rows > 0) - { - /* set to first row */ - self->tupleField = self->backend_tuples + (offset * self->num_fields); - return TRUE; - } - else - { - /* We are surely done here (we read 0 tuples) */ - mylog("_next_tuple: 'C': DONE (fcount == 0)\n"); - return -1; /* end of tuples */ - } - /* continue reading */ - } - - mylog("end of tuple list -- setting inUse to false: this = %u\n", self); - - return TRUE; - } - - - char - QR_read_tuple(QResultClass *self, char binary) - { - Int2 field_lf; - TupleField *this_tuplefield; - KeySet *this_keyset = NULL; - Int2 bitmaplen; /* len of the bitmap in bytes */ - Int4 len=0; - char *buffer; - int ci_num_fields = QR_NumResultCols(self); /* speed up access */ - int num_fields = self->num_fields; /* speed up access */ - ColumnInfoClass *flds; - int effective_cols; - char tidoidbuf[32]; - - /* set the current row to read the fields into */ - effective_cols = QR_NumPublicResultCols(self); - this_tuplefield = self->backend_tuples + (self->num_backend_rows * num_fields); - if (self->haskeyset) - { - this_keyset = self->keyset + self->num_total_rows; - this_keyset->status = 0; - } - - bitmaplen = (Int2) ci_num_fields / BYTELEN; - if ((ci_num_fields % BYTELEN) > 0) - bitmaplen++; - - /* - * At first the server sends a bitmap that indicates which database - * fields are null - */ - flds = self->fields; - for (field_lf = 0; field_lf < ci_num_fields; field_lf++) - { - /* - * NO, the field is not null. so get at first the length of - * the field (four bytes) - */ - if (!binary) - len -= VARHDRSZ; - - if (field_lf >= effective_cols) - buffer = tidoidbuf; - else - QR_MALLOC_return_with_error(buffer, char, - (len + 1), self, - PGRES_FATAL_ERROR, - "Couldn't allocate buffer", - FALSE); - if (field_lf >= effective_cols) - { - if (field_lf == effective_cols) - sscanf(buffer, "(%lu,%hu)", - &this_keyset->blocknum, &this_keyset->offset); - else - this_keyset->oid = strtoul(buffer, NULL, 10); - } - else - { - this_tuplefield[field_lf].len = len; - this_tuplefield[field_lf].value = buffer; - /* - * This can be used to set the longest length of the column - * for any row in the tuple cache. It would not be accurate - * for varchar and text fields to use this since a tuple cache - * is only 100 rows. Bpchar can be handled since the strlen of - * all rows is fixed, assuming there are not 100 nulls in a - * row! - */ - if (flds && flds->display_size && flds->display_size[field_lf] < len) - flds->display_size[field_lf] = len; - } - } - - self->currTuple++; - return TRUE; } --- 495,498 ---- diff -c psqlodbc.cleanup.orig\qresult.h psqlodbc.cleanup\qresult.h *** psqlodbc.cleanup.orig\qresult.h Wed Nov 30 13:44:33 2005 --- psqlodbc.cleanup\qresult.h Tue Dec 20 15:35:03 2005 *************** *** 136,143 **** /* Core Functions */ QResultClass *QR_Constructor(void); void QR_Destructor(QResultClass *self); - char QR_read_tuple(QResultClass *self, char binary); - int QR_next_tuple(QResultClass *self); int QR_close(QResultClass *self); char QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor); void QR_free_memory(QResultClass *self); --- 136,141 ---- diff -c psqlodbc.cleanup.orig\results.c psqlodbc.cleanup\results.c *** psqlodbc.cleanup.orig\results.c Fri Dec 09 02:55:48 2005 --- psqlodbc.cleanup\results.c Tue Dec 20 17:36:41 2005 *************** *** 447,453 **** unknown_sizes = UNKNOWNS_AS_MAX; parse_ok = FALSE; ! if (ci->drivers.parse && stmt->statement_type == STMT_TYPE_SELECT) { if (stmt->parse_status == STMT_PARSE_NONE) { --- 447,453 ---- unknown_sizes = UNKNOWNS_AS_MAX; parse_ok = FALSE; ! if (!stmt->manual_result && ci->drivers.parse && stmt->statement_type == STMT_TYPE_SELECT) { if (stmt->parse_status == STMT_PARSE_NONE) { *************** *** 839,900 **** return SQL_ERROR; } } ! if (stmt->manual_result) { ! if(!SC_is_fetchcursor(stmt)) { ! /* make sure we're positioned on a valid row */ ! num_rows = QR_get_num_total_tuples(res); ! if ((stmt->currTuple < 0) || ! (stmt->currTuple >= num_rows)) ! { ! SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row for GetData."); ! SC_log_error(func, "", stmt); ! return SQL_ERROR; ! } ! } ! else ! { ! if (stmt->currTuple < 0) ! { ! SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row for GetData."); ! SC_log_error(func, "", stmt); ! return SQL_ERROR; ! } ! } ! ! if (!get_bookmark) ! { ! if (stmt->manual_result) ! if(SC_is_fetchcursor(stmt)) ! value = QR_get_value_manual(res, (stmt->currTuple % stmt->hdbc->connInfo.drivers.fetch_max), icol); ! else ! value = QR_get_value_manual(res, stmt->currTuple, icol); ! else ! { ! Int4 curt = GIdx2ResultIdx(stmt->currTuple, stmt, res); ! value = QR_get_value_backend_row(res, curt, icol); ! } ! mylog(" value = '%s'\n", value ? value : "(null)"); } } else { ! /* it's a SOCKET result (backend data) */ ! if (stmt->currTuple == -1 || !res || !res->tupleField) { SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row for GetData."); SC_log_error(func, "", stmt); return SQL_ERROR; } - - if (!get_bookmark) - value = QR_get_value_backend(res, icol); - - mylog(" socket: value = '%s'\n", value ? value : "(null)"); } ! if (get_bookmark) { BOOL contents_get = FALSE; --- 839,876 ---- return SQL_ERROR; } } ! if(!SC_is_fetchcursor(stmt)) { ! /* make sure we're positioned on a valid row */ ! num_rows = QR_get_num_total_tuples(res); ! if ((stmt->currTuple < 0) || ! (stmt->currTuple >= num_rows)) { ! SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row for GetData."); ! SC_log_error(func, "", stmt); ! return SQL_ERROR; } } else { ! if (stmt->currTuple < 0) { SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row for GetData."); SC_log_error(func, "", stmt); return SQL_ERROR; } } ! if (!get_bookmark) ! { ! /* Luf - I think this isn't enough condition */ ! if(SC_is_fetchcursor(stmt)) ! value = QR_get_value_manual(res, (stmt->currTuple % stmt->hdbc->connInfo.drivers.fetch_max), icol); ! else ! value = QR_get_value_manual(res, stmt->currTuple, icol); ! mylog(" value = '%s'\n", value ? value : "(null)"); ! } ! else { BOOL contents_get = FALSE; *************** *** 1413,1426 **** * Handle Declare Fetch style specially because the end is not really * the end... */ ! if (SC_is_fetchcursor(stmt) ) ! { ! if(!stmt->manual_result) ! { ! return SQL_NO_DATA_FOUND; ! } ! } ! else { /* If *new* rowset is after the result_set, return no data found */ if (stmt->rowset_start >= num_tuples) --- 1389,1395 ---- * Handle Declare Fetch style specially because the end is not really * the end... */ ! if (!SC_is_fetchcursor(stmt) ) { /* If *new* rowset is after the result_set, return no data found */ if (stmt->rowset_start >= num_tuples) *************** *** 1534,1543 **** /* Move the cursor position to the first row in the result set. */ stmt->currTuple = RowIdx2GIdx(0, stmt); - - /* For declare/fetch, need to reset cursor to beginning of rowset */ - if (SC_is_fetchcursor(stmt) && !stmt->manual_result) - QR_set_position(res, 0); /* Set the number of rows retrieved */ if (pcrow) --- 1503,1508 ---- diff -c psqlodbc.cleanup.orig\statement.c psqlodbc.cleanup\statement.c *** psqlodbc.cleanup.orig\statement.c Sat Dec 10 08:39:31 2005 --- psqlodbc.cleanup\statement.c Tue Dec 20 14:35:17 2005 *************** *** 251,257 **** rv->phstmt = NULL; rv->result = NULL; rv->curres = NULL; ! rv->manual_result = TRUE; rv->prepare = FALSE; rv->prepared = FALSE; rv->status = STMT_ALLOCATED; --- 251,257 ---- rv->phstmt = NULL; rv->result = NULL; rv->curres = NULL; ! rv->manual_result = FALSE; rv->prepare = FALSE; rv->prepared = FALSE; rv->status = STMT_ALLOCATED; *************** *** 636,642 **** * Reset only parameters that have anything to do with results */ self->status = STMT_READY; ! self->manual_result = TRUE; /* very important */ self->currTuple = -1; self->rowset_start = -1; SC_set_current_col(self, -1); --- 636,642 ---- * Reset only parameters that have anything to do with results */ self->status = STMT_READY; ! self->manual_result = FALSE; self->currTuple = -1; self->rowset_start = -1; SC_set_current_col(self, -1); *************** *** 956,1010 **** coli = QR_get_fields(res); /* the column info */ mylog("manual_result = %d, use_declarefetch = %d\n", self->manual_result, ci->drivers.use_declarefetch); ! if (self->manual_result) { ! if(!SC_is_fetchcursor(self)) { ! if (self->currTuple >= QR_get_num_total_tuples(res) - 1 || ! (self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1)) ! { ! /* ! * if at the end of the tuples, return "no data found" and set ! * the cursor past the end of the result set ! */ ! self->currTuple = QR_get_num_total_tuples(res); ! return SQL_NO_DATA_FOUND; ! } ! } ! else ! { ! if ((((self->currTuple + 1) % ci->drivers.fetch_max) >= QR_get_num_total_tuples(res)) && ! QR_get_num_total_tuples(res) < ci->drivers.fetch_max) ! { ! SC_no_fetchcursor(self); ! self->currTuple = QR_get_num_total_tuples(res); ! return SQL_NO_DATA_FOUND; ! } } - - mylog("**** SC_fetch: manual_result\n"); - (self->currTuple)++; } else { ! /* read from the cache or the physical next tuple */ ! retval = QR_next_tuple(res); ! if (retval < 0) { ! mylog("**** SC_fetch: end_tuples\n"); return SQL_NO_DATA_FOUND; } - else if (retval > 0) - (self->currTuple)++; /* all is well */ - else - { - mylog("SC_fetch: error\n"); - SC_set_error(self, STMT_EXEC_ERROR, "Error fetching next row"); - SC_log_error(func, "", self); - return SQL_ERROR; - } } #ifdef DRIVER_CURSOR_IMPLEMENT if (res->haskeyset) { --- 956,988 ---- coli = QR_get_fields(res); /* the column info */ mylog("manual_result = %d, use_declarefetch = %d\n", self->manual_result, ci->drivers.use_declarefetch); ! if(!SC_is_fetchcursor(self)) { ! if (self->currTuple >= QR_get_num_total_tuples(res) - 1 || ! (self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1)) { ! /* ! * if at the end of the tuples, return "no data found" and set ! * the cursor past the end of the result set ! */ ! self->currTuple = QR_get_num_total_tuples(res); ! return SQL_NO_DATA_FOUND; } } else { ! if ((((self->currTuple + 1) % ci->drivers.fetch_max) >= QR_get_num_total_tuples(res)) && ! QR_get_num_total_tuples(res) < ci->drivers.fetch_max) { ! SC_no_fetchcursor(self); ! self->currTuple = QR_get_num_total_tuples(res); return SQL_NO_DATA_FOUND; } } + mylog("**** SC_fetch: data continuing ...\n"); + (self->currTuple)++; + #ifdef DRIVER_CURSOR_IMPLEMENT if (res->haskeyset) { *************** *** 1063,1083 **** mylog("type = %d\n", type); ! if (self->manual_result) ! { ! if ((ci->drivers.use_declarefetch) && (self->currTuple >= QR_get_num_total_tuples(res))) ! value = QR_get_value_manual(res, (self->currTuple >= ci->drivers.fetch_max) ? (self->currTuple % ci->drivers.fetch_max) : self->currTuple, lf); ! else ! value = QR_get_value_manual(res, self->currTuple, lf); ! mylog("manual_result\n"); ! } ! else if (SC_is_fetchcursor(self)) ! value = QR_get_value_backend(res, lf); else ! { ! int curt = GIdx2ResultIdx(self->currTuple, self, res); ! value = QR_get_value_backend_row(res, curt, lf); ! } mylog("value = '%s'\n", (value == NULL) ? "" : value); --- 1041,1051 ---- mylog("type = %d\n", type); ! /* Luf - This is corrected condition */ ! if ((ci->drivers.use_declarefetch) && (self->currTuple >= QR_get_num_total_tuples(res))) ! value = QR_get_value_manual(res, (self->currTuple >= ci->drivers.fetch_max) ? (self->currTuple % ci->drivers.fetch_max) : self->currTuple, lf); else ! value = QR_get_value_manual(res, self->currTuple, lf); mylog("value = '%s'\n", (value == NULL) ? "" : value);