summaryrefslogtreecommitdiff
path: root/src/interfaces/odbc/qresult.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/odbc/qresult.c')
-rw-r--r--src/interfaces/odbc/qresult.c107
1 files changed, 70 insertions, 37 deletions
diff --git a/src/interfaces/odbc/qresult.c b/src/interfaces/odbc/qresult.c
index 89ce0396eca..923448abeba 100644
--- a/src/interfaces/odbc/qresult.c
+++ b/src/interfaces/odbc/qresult.c
@@ -123,6 +123,8 @@ QR_Constructor()
rv->rowset_size = 1;
rv->haskeyset = 0;
rv->keyset = NULL;
+ rv->rb_count = 0;
+ rv->rollback = NULL;
}
mylog("exit QR_Constructor\n");
@@ -228,6 +230,12 @@ QR_free_memory(QResultClass *self)
free(self->keyset);
self->keyset = NULL;
}
+ if (self->rollback)
+ {
+ free(self->rollback);
+ self->rb_count = 0;
+ self->rollback = NULL;
+ }
self->fcount = 0;
@@ -280,6 +288,8 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
{
self->status = PGRES_FIELDS_OK;
self->num_fields = CI_get_num_fields(self->fields);
+ if (self->haskeyset)
+ self->num_fields -= 2;
}
else
{
@@ -302,15 +312,18 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor)
/* allocate memory for the tuple cache */
mylog("MALLOC: tuple_size = %d, size = %d\n", tuple_size, self->num_fields * sizeof(TupleField) * tuple_size);
self->count_allocated = 0;
- self->backend_tuples = (TupleField *) malloc(self->num_fields * sizeof(TupleField) * tuple_size);
- if (self->haskeyset)
- self->keyset = (KeySet *) calloc(sizeof(KeySet), tuple_size);
- if (!self->backend_tuples)
+ if (self->num_fields > 0)
{
- self->status = PGRES_FATAL_ERROR;
- QR_set_message(self, "Could not get memory for tuple cache.");
- return FALSE;
+ self->backend_tuples = (TupleField *) malloc(self->num_fields * sizeof(TupleField) * tuple_size);
+ if (!self->backend_tuples)
+ {
+ self->status = PGRES_FATAL_ERROR;
+ QR_set_message(self, "Could not get memory for tuple cache.");
+ return FALSE;
+ }
}
+ if (self->haskeyset)
+ self->keyset = (KeySet *) calloc(sizeof(KeySet), tuple_size);
self->count_allocated = tuple_size;
self->inTuples = TRUE;
@@ -415,6 +428,7 @@ QR_next_tuple(QResultClass *self)
char fetch[128];
QueryInfo qi;
ConnInfo *ci = NULL;
+ BOOL set_no_trans;
if (fetch_count < fcount)
{
@@ -484,12 +498,16 @@ QR_next_tuple(QResultClass *self)
if (!self->backend_tuples || self->cache_size > self->count_allocated)
{
self->count_allocated = 0;
- self->backend_tuples = (TupleField *) realloc(self->backend_tuples, self->num_fields * sizeof(TupleField) * self->cache_size);
- if (!self->backend_tuples)
+ if (self->num_fields > 0)
{
- self->status = PGRES_FATAL_ERROR;
- QR_set_message(self, "Out of memory while reading tuples.");
- return FALSE;
+ self->backend_tuples = (TupleField *) realloc(self->backend_tuples,
+ self->num_fields * sizeof(TupleField) * self->cache_size);
+ if (!self->backend_tuples)
+ {
+ self->status = PGRES_FATAL_ERROR;
+ QR_set_message(self, "Out of memory while reading tuples.");
+ return FALSE;
+ }
}
if (self->haskeyset)
self->keyset = (KeySet *) realloc(self->keyset, sizeof(KeySet) * self->cache_size);
@@ -555,13 +573,16 @@ QR_next_tuple(QResultClass *self)
mylog("REALLOC: old_count = %d, size = %d\n", tuple_size, self->num_fields * sizeof(TupleField) * tuple_size);
tuple_size *= 2;
- self->backend_tuples = (TupleField *) realloc(self->backend_tuples,
- tuple_size * self->num_fields * sizeof(TupleField));
- if (!self->backend_tuples)
+ if (self->num_fields > 0)
{
- self->status = PGRES_FATAL_ERROR;
- QR_set_message(self, "Out of memory while reading tuples.");
- return FALSE;
+ self->backend_tuples = (TupleField *) realloc(self->backend_tuples,
+ tuple_size * self->num_fields * sizeof(TupleField));
+ if (!self->backend_tuples)
+ {
+ self->status = PGRES_FATAL_ERROR;
+ QR_set_message(self, "Out of memory while reading tuples.");
+ return FALSE;
+ }
}
if (self->haskeyset)
self->keyset = (KeySet *) realloc(self->keyset, sizeof(KeySet) * tuple_size);
@@ -606,8 +627,10 @@ QR_next_tuple(QResultClass *self)
QR_set_message(self, msgbuffer);
self->status = PGRES_FATAL_ERROR;
+ set_no_trans = FALSE;
if (!strncmp(msgbuffer, "FATAL", 5))
- CC_set_no_trans(self->conn);
+ set_no_trans = TRUE;
+ CC_on_abort(self->conn, set_no_trans);
qlog("ERROR from backend in next_tuple: '%s'\n", msgbuffer);
@@ -626,7 +649,7 @@ QR_next_tuple(QResultClass *self)
qlog("QR_next_tuple: Unexpected result from backend: id = '%c' (%d)\n", id, id);
QR_set_message(self, "Unexpected result from backend. It probably crashed");
self->status = PGRES_FATAL_ERROR;
- CC_set_no_trans(self->conn);
+ CC_on_abort(self->conn, TRUE);
return FALSE;
}
}
@@ -647,16 +670,21 @@ QR_read_tuple(QResultClass *self, char binary)
Int2 bitcnt;
Int4 len;
char *buffer;
- int num_fields = self->num_fields; /* speed up access */
+ int ci_num_fields = QR_NumResultCols(self); /* speed up access */
+ int num_fields = self->num_fields; /* speed up access */
SocketClass *sock = CC_get_socket(self->conn);
ColumnInfoClass *flds;
+ int effective_cols;
+ char tidoidbuf[32];
/* set the current row to read the fields into */
+ effective_cols = ci_num_fields;
this_tuplefield = self->backend_tuples + (self->fcount * num_fields);
if (self->haskeyset)
{
this_keyset = self->keyset + self->fcount;
this_keyset->status = 0;
+ effective_cols -= 2;
}
bitmaplen = (Int2) num_fields / BYTELEN;
@@ -672,8 +700,9 @@ QR_read_tuple(QResultClass *self, char binary)
bitmap_pos = 0;
bitcnt = 0;
bmp = bitmap[bitmap_pos];
+ flds = self->fields;
- for (field_lf = 0; field_lf < num_fields; field_lf++)
+ for (field_lf = 0; field_lf < ci_num_fields; field_lf++)
{
/* Check if the current field is NULL */
if (!(bmp & 0200))
@@ -692,14 +721,27 @@ QR_read_tuple(QResultClass *self, char binary)
if (!binary)
len -= VARHDRSZ;
- buffer = (char *) malloc(len + 1);
+ if (field_lf >= effective_cols)
+ buffer = tidoidbuf;
+ else
+ buffer = (char *) malloc(len + 1);
SOCK_get_n_char(sock, buffer, len);
buffer[len] = '\0';
mylog("qresult: len=%d, buffer='%s'\n", len, buffer);
- this_tuplefield[field_lf].len = len;
- this_tuplefield[field_lf].value = buffer;
+ 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
@@ -710,9 +752,9 @@ QR_read_tuple(QResultClass *self, char binary)
* row!
*/
- flds = self->fields;
- if (flds && flds->display_size && flds->display_size[field_lf] < len)
- flds->display_size[field_lf] = len;
+ if (flds && flds->display_size && flds->display_size[field_lf] < len)
+ flds->display_size[field_lf] = len;
+ }
}
/*
@@ -728,15 +770,6 @@ QR_read_tuple(QResultClass *self, char binary)
else
bmp <<= 1;
}
- if (this_keyset)
- {
- if (this_tuplefield[num_fields - 2].value)
- sscanf(this_tuplefield[num_fields - 2].value, "(%lu,%hu)",
- &this_keyset->blocknum, &this_keyset->offset);
- if (this_tuplefield[num_fields - 1].value)
- sscanf(this_tuplefield[num_fields - 1].value, "%lu",
- &this_keyset->oid);
- }
self->currTuple++;
return TRUE;
}