summaryrefslogtreecommitdiff
path: root/src/interfaces/odbc/statement.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/odbc/statement.c')
-rw-r--r--src/interfaces/odbc/statement.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/interfaces/odbc/statement.c b/src/interfaces/odbc/statement.c
index f185e2220a4..86bce41a8f9 100644
--- a/src/interfaces/odbc/statement.c
+++ b/src/interfaces/odbc/statement.c
@@ -566,6 +566,142 @@ char rv;
return rv;
}
+
+RETCODE
+SC_fetch(StatementClass *self)
+{
+static char *func = "SC_fetch";
+QResultClass *res = self->result;
+int retval, result;
+Int2 num_cols, lf;
+Oid type;
+char *value;
+ColumnInfoClass *ci;
+// TupleField *tupleField;
+
+ self->last_fetch_count = 0;
+ ci = QR_get_fields(res); /* the column info */
+
+ mylog("manual_result = %d, use_declarefetch = %d\n", self->manual_result, globals.use_declarefetch);
+
+ if ( self->manual_result || ! globals.use_declarefetch) {
+
+ if (self->currTuple >= QR_get_num_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_tuples(res);
+ return SQL_NO_DATA_FOUND;
+ }
+
+ mylog("**** SQLFetch: manual_result\n");
+ (self->currTuple)++;
+ }
+ else {
+
+ // read from the cache or the physical next tuple
+ retval = QR_next_tuple(res);
+ if (retval < 0) {
+ mylog("**** SQLFetch: end_tuples\n");
+ return SQL_NO_DATA_FOUND;
+ }
+ else if (retval > 0)
+ (self->currTuple)++; // all is well
+
+ else {
+ mylog("SQLFetch: error\n");
+ self->errornumber = STMT_EXEC_ERROR;
+ self->errormsg = "Error fetching next row";
+ SC_log_error(func, "", self);
+ return SQL_ERROR;
+ }
+ }
+
+ num_cols = QR_NumResultCols(res);
+
+ result = SQL_SUCCESS;
+ self->last_fetch_count = 1;
+
+ for (lf=0; lf < num_cols; lf++) {
+
+ mylog("fetch: cols=%d, lf=%d, self = %u, self->bindings = %u, buffer[] = %u\n", num_cols, lf, self, self->bindings, self->bindings[lf].buffer);
+
+ /* reset for SQLGetData */
+ self->bindings[lf].data_left = -1;
+
+ if (self->bindings[lf].buffer != NULL) {
+ // this column has a binding
+
+ // type = QR_get_field_type(res, lf);
+ type = CI_get_oid(ci, lf); /* speed things up */
+
+ mylog("type = %d\n", type);
+
+ if (self->manual_result) {
+ value = QR_get_value_manual(res, self->currTuple, lf);
+ mylog("manual_result\n");
+ }
+ else if (globals.use_declarefetch)
+ value = QR_get_value_backend(res, lf);
+ else {
+ value = QR_get_value_backend_row(res, self->currTuple, lf);
+ }
+
+ mylog("value = '%s'\n", (value==NULL)?"<NULL>":value);
+
+ retval = copy_and_convert_field_bindinfo(self, type, value, lf);
+
+ mylog("copy_and_convert: retval = %d\n", retval);
+
+ switch(retval) {
+ case COPY_OK:
+ break; /* OK, do next bound column */
+
+ case COPY_UNSUPPORTED_TYPE:
+ self->errormsg = "Received an unsupported type from Postgres.";
+ self->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR;
+ SC_log_error(func, "", self);
+ result = SQL_ERROR;
+ break;
+
+ case COPY_UNSUPPORTED_CONVERSION:
+ self->errormsg = "Couldn't handle the necessary data type conversion.";
+ self->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR;
+ SC_log_error(func, "", self);
+ result = SQL_ERROR;
+ break;
+
+ case COPY_RESULT_TRUNCATED:
+ self->errornumber = STMT_TRUNCATED;
+ self->errormsg = "The buffer was too small for the result.";
+ result = SQL_SUCCESS_WITH_INFO;
+ break;
+
+ case COPY_GENERAL_ERROR: /* error msg already filled in */
+ SC_log_error(func, "", self);
+ result = SQL_ERROR;
+ break;
+
+ /* This would not be meaningful in SQLFetch. */
+ case COPY_NO_DATA_FOUND:
+ break;
+
+ default:
+ self->errormsg = "Unrecognized return value from copy_and_convert_field.";
+ self->errornumber = STMT_INTERNAL_ERROR;
+ SC_log_error(func, "", self);
+ result = SQL_ERROR;
+ break;
+ }
+ }
+ }
+
+ return result;
+}
+
+
RETCODE SC_execute(StatementClass *self)
{
static char *func="SC_execute";