patch for cleanup manual_result

patch for cleanup manual_result

am 20.12.2005 16:55:17 von Ludek Finstrle

--EeQfGwPcQSOJBaQU
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hello,

I hoped I can remove whole manual_result. But I found that it can stay
still in code. Reasons:
1) PGAPI_GetTypeInfo - doesn't fill result with unicode string
2) SQLColumns, SQLTables, ... create answers manualy (it direct create
column informations - so it's SQL could not be parsed)

I change defaul manual_result now to FALSE. I removed a lot of
manual_result conditions in source code.

I tried build and test driver with this patch. I don't see problems.
But it needs to be huge tested.
If noone report bugs in patch I'll try release new development
snapshot before X-mas.

Please review and comment patch

Thanks,

Luf

--EeQfGwPcQSOJBaQU
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="psqlodbc-cleanup_manual_result.diff"

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);


--EeQfGwPcQSOJBaQU
Content-Type: text/plain
Content-Disposition: inline
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable


---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match

--EeQfGwPcQSOJBaQU--