diff options
| author | Heikki Linnakangas | 2014-04-11 12:14:26 +0000 |
|---|---|---|
| committer | Heikki Linnakangas | 2014-04-11 12:16:16 +0000 |
| commit | b5c9a65eedc5f16031b7d44421bc161b9758d9fc (patch) | |
| tree | 5cb70b0c18108112d2b031bd11ab9430d4a1083f | |
| parent | c38504ae9064a766d41316b28144d5a05c9cd9f0 (diff) | |
Fix two UseDeclareFetch bugs.
1. NOTICE messages were not delivered to the application, if they arrived
as response to the DECLARE CURSOR statement.
2. Array-bound parameters on SELECT-queries caused a "cursor already open"
error.
These bugs were found by running the regression suite with
UseDeclareFetch=1. It's now clean.
| -rw-r--r-- | convert.c | 2 | ||||
| -rw-r--r-- | statement.c | 15 | ||||
| -rw-r--r-- | statement.h | 10 |
3 files changed, 23 insertions, 4 deletions
@@ -3296,7 +3296,7 @@ inner_process_tokens(QueryParse *qp, QueryBuild *qb) if (0 == (qb->flags & FLGB_CREATE_KEYSET)) { qb->errornumber = STMT_SEQUENCE_ERROR; - qb->errormsg = "Should come here only when hamdling updatable cursors"; + qb->errormsg = "Should come here only when handling updatable cursors"; return SQL_ERROR; } CVT_APPEND_STR(qb, ", \"ctid"); diff --git a/statement.c b/statement.c index 19510bf..0d23ffe 100644 --- a/statement.c +++ b/statement.c @@ -2048,6 +2048,12 @@ inolog("get_Result=%p %p %d\n", res, SC_get_Result(self), self->curr_param_resul res = CC_send_query_append(conn, self->stmt_with_params, qryi, qflag, SC_get_ancestor(self), appendq); if (useCursor && QR_command_maybe_successful(res)) { + /* + * If we sent a DECLARE CURSOR + FETCH, throw away the result of + * the DECLARE CURSOR statement, and only return the result of the + * FETCH to the caller. However, if we received any NOTICEs as + * part of the DECLARE CURSOR, carry those over. + */ if (appendq) { QResultClass *qres, *nres; @@ -2060,6 +2066,15 @@ inolog("get_Result=%p %p %d\n", res, SC_get_Result(self), self->curr_param_resul break; } nres = qres->next; + if (nres && QR_get_notice(qres) != NULL) + { + if (QR_command_successful(nres) && + QR_command_nonfatal(qres)) + { + QR_set_rstatus(nres, PORES_NONFATAL_ERROR); + } + QR_add_notice(nres, QR_get_notice(qres)); + } qres->next = NULL; QR_Destructor(qres); qres = nres; diff --git a/statement.h b/statement.h index aa847e6..6a138be 100644 --- a/statement.h +++ b/statement.h @@ -422,7 +422,13 @@ enum #define SC_ref_CC_error(a) ((a->ref_CC_error) = TRUE) void SC_forget_unnamed(StatementClass *self); #define SC_can_parse_statement(a) (STMT_TYPE_SELECT == (a)->statement_type) -#define SC_may_use_cursor(a) (STMT_TYPE_SELECT == (a)->statement_type || STMT_TYPE_WITH == (a)->statement_type) +/* + * DECLARE CURSOR + FETCH can only be used with SELECT-type queries. And + * it's not currently supported with array-bound parameters. + */ +#define SC_may_use_cursor(a) \ + (SC_get_APDF(a)->paramset_size <= 1 && \ + (STMT_TYPE_SELECT == (a)->statement_type || STMT_TYPE_WITH == (a)->statement_type) ) #define SC_may_fetch_rows(a) (STMT_TYPE_SELECT == (a)->statement_type || STMT_TYPE_WITH == (a)->statement_type) #define SC_can_req_colinfo(a) (STMT_TYPE_SELECT == (a)->statement_type || \ STMT_TYPE_WITH == (a)->statement_type || \ @@ -501,8 +507,6 @@ BOOL SC_SetExecuting(StatementClass *self, BOOL on); BOOL SC_SetCancelRequest(StatementClass *self); BOOL SC_AcceptedCancelRequest(const StatementClass *self); -DescriptorClass *SC_set_ARD(StatementClass *stmt, DescriptorClass *desc); -DescriptorClass *SC_set_APD(StatementClass *stmt, DescriptorClass *desc); int enqueueNeedDataCallback(StatementClass *self, NeedDataCallfunc, void *); RETCODE dequeueNeedDataCallback(RETCODE, StatementClass *self); void cancelNeedDataState(StatementClass *self); |
