len = 4;
*((HSTMT *) Value) = descHandleFromStatementHandle(StatementHandle, Attribute);
break;
- case SQL_ATTR_AUTO_IPD: /* 10001 */
- /* case SQL_ATTR_ROW_BIND_TYPE: ** == SQL_BIND_TYPE(ODBC2.0) */
case SQL_ATTR_CURSOR_SCROLLABLE: /* -1 */
+ len = 4;
+ if (SQL_CURSOR_FORWARD_ONLY == stmt->options.cursor_type)
+ *((SQLUINTEGER *) Value) = SQL_NONSCROLLABLE;
+ else
+ *((SQLUINTEGER *) Value) = SQL_SCROLLABLE;
+ break;
case SQL_ATTR_CURSOR_SENSITIVITY: /* -2 */
+ len = 4;
+ if (SQL_CONCUR_READ_ONLY == stmt->options.scroll_concurrency)
+ *((SQLUINTEGER *) Value) = SQL_INSENSITIVE;
+ else
+ *((SQLUINTEGER *) Value) = SQL_UNSPECIFIED;
+ break;
+ case SQL_ATTR_AUTO_IPD: /* 10001 */
+ /* case SQL_ATTR_ROW_BIND_TYPE: ** == SQL_BIND_TYPE(ODBC2.0) */
case SQL_ATTR_ENABLE_AUTO_IPD: /* 15 */
case SQL_ATTR_METADATA_ID: /* 10014 */
StatementClass *stmt = (StatementClass *) hstmt;
ARDFields *opts = SC_get_ARD(stmt);
RETCODE ret;
- UInt4 offset, bind_size = opts->bind_size, *bmark = NULL;
+ UInt4 offset, bind_size = opts->bind_size, *bmark = NULL,
+ global_idx;
int i, processed;
ConnectionClass *conn;
BOOL auto_commit_needed = FALSE;
}
for (i = 0, processed = 0; i < opts->rowset_size; i++)
{
+ global_idx = *bmark - 1;
/* Note opts->row_operation_ptr is ignored */
switch (operation)
{
ret = SC_pos_add(stmt, (UWORD) i);
break;
case SQL_UPDATE_BY_BOOKMARK:
- ret = SC_pos_update(stmt, (UWORD) i, *bmark);
+ ret = SC_pos_update(stmt, (UWORD) i, global_idx);
break;
case SQL_DELETE_BY_BOOKMARK:
- ret = SC_pos_delete(stmt, (UWORD) i, *bmark);
+ ret = SC_pos_delete(stmt, (UWORD) i, global_idx);
break;
case SQL_FETCH_BY_BOOKMARK:
- ret = SC_pos_refresh(stmt, (UWORD) i, *bmark);
+ ret = SC_pos_refresh(stmt, (UWORD) i, global_idx);
break;
}
processed++;
value = QR_get_value_manual(res, stmt->currTuple, icol);
else
{
- Int4 curt = res->base;
- if (stmt->rowset_start >= 0)
- curt += (stmt->currTuple - stmt->rowset_start);
+ Int4 curt = GIdx2ResultIdx(stmt->currTuple, stmt, res);
value = QR_get_value_backend_row(res, curt, icol);
}
mylog(" value = '%s'\n", value);
}
/* currTuple is always 1 row prior to the rowset */
- stmt->currTuple = stmt->rowset_start - 1;
+ stmt->currTuple = RowIdx2GIdx(-1, stmt);
/* increment the base row in the tuple cache */
QR_set_rowset_size(res, opts->rowset_size);
/* Save the fetch count for SQLSetPos */
stmt->last_fetch_count = i;
- stmt->last_fetch_count_include_ommitted = currp - stmt->rowset_start;
+ stmt->last_fetch_count_include_ommitted = GIdx2RowIdx(currp, stmt);
/* Reset next binding row */
stmt->bind_row = 0;
/* Move the cursor position to the first row in the result set. */
- stmt->currTuple = stmt->rowset_start;
+ stmt->currTuple = RowIdx2GIdx(0, stmt);
/* For declare/fetch, need to reset cursor to beginning of rowset */
if (SC_is_fetchcursor(stmt) && !stmt->manual_result)
status = keyset[index].status;
if (0 != (status & CURS_SELF_ADDING))
{
- ridx = index - stmt->rowset_start + res->base;
+ ridx = GIdx2ResultIdx(index, stmt, res);
if (ridx >=0 && ridx < res->num_backend_rows)
{
TupleField *tuple = res->backend_tuples + res->num_fields * ridx;
SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only");
return SQL_ERROR;
}
- res_ridx = global_ridx - stmt->rowset_start + res->base;
+ res_ridx = GIdx2ResultIdx(global_ridx, stmt, res);
if (!(oid = getOid(res, global_ridx)))
{
SC_set_error(stmt, STMT_ROW_VERSION_CHANGED, "the row was already deleted ?");
SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only");
return SQL_ERROR;
}
- limitrow = stmt->rowset_start + res->rowset_size;
+ limitrow = RowIdx2GIdx(res->rowset_size, stmt);
if (limitrow > res->num_total_rows)
limitrow = res->num_total_rows;
if (create_from_scratch)
if (res->backend_tuples[i].value)
free(res->backend_tuples[i].value);
}
- brows = limitrow - stmt->rowset_start;
+ brows = GIdx2RowIdx(limitrow, stmt);
if (brows > res->count_backend_allocated)
{
res->backend_tuples = realloc(res->backend_tuples, sizeof(TupleField) * res->num_fields * brows);
{
if (oid == getOid(res, k))
{
- l = k - stmt->rowset_start + res->base;
+ l = GIdx2ResultIdx(k, stmt, res);
tuple = res->backend_tuples + res->num_fields * l;
tuplew = qres->backend_tuples + qres->num_fields * j;
for (m = 0; m < res->num_fields; m++, tuple++, tuplew++)
}
KeySetSet(tuplen, qres->num_fields, res->keyset + res->num_total_rows);
- if (res->num_total_rows == res->num_backend_rows - res->base + stmt->rowset_start)
+ if (res->num_total_rows == ResultIdx2GIdx(res->num_backend_rows, stmt, res))
{
if (res->num_backend_rows >= res->count_backend_allocated)
{
PGAPI_FreeStmt(hstmt, SQL_DROP);
if (SQL_SUCCESS == ret && res->keyset)
{
- int global_ridx = res->num_total_rows + stmt->rowset_start - res->base - 1;
+ int global_ridx = res->num_total_rows - 1;
if (CC_is_in_trans(conn))
{
ridx = -1;
for (i = nrow = 0, processed = 0; nrow <= end_row; i++)
{
- global_ridx = i + stmt->rowset_start;
+ global_ridx = RowIdx2GIdx(i, stmt);
if (SQL_ADD != fOption)
{
if ((int) global_ridx >= res->num_total_rows)
{
if (SQL_ADD != fOption && ridx >= 0) /* for SQLGetData */
{
- stmt->currTuple = stmt->rowset_start + ridx;
+ stmt->currTuple = RowIdx2GIdx(ridx, stmt);
QR_set_position(res, ridx);
}
}
RETCODE SC_pos_refresh(StatementClass *self, UWORD irow, UDWORD index);
RETCODE SC_pos_add(StatementClass *self, UWORD irow);
+/*
+ * Macros to convert global index <-> relative index in resultset/rowset
+ */
+/* a global index to the relative index in a rowset */
+#define GIdx2RowIdx(gidx, stmt) (gidx - stmt->rowset_start)
+/* a global index to the relative index in a resultset(not a rowset) */
+#define GIdx2ResultIdx(gidx, stmt, res) ((stmt->rowset_start < 0) ? res->base : gidx - stmt->rowset_start + res->base)
+/* a relative index in a rowset to the global index */
+#define RowIdx2GIdx(ridx, stmt) (ridx + stmt->rowset_start)
+/* a relative index in a resultset to the global index */
+#define ResultIdx2GIdx(ridx, stmt, res) (ridx - res->base + stmt->rowset_start)
#endif