summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeikki Linnakangas2014-04-11 12:14:26 +0000
committerHeikki Linnakangas2014-04-11 12:16:16 +0000
commitb5c9a65eedc5f16031b7d44421bc161b9758d9fc (patch)
tree5cb70b0c18108112d2b031bd11ab9430d4a1083f
parentc38504ae9064a766d41316b28144d5a05c9cd9f0 (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.c2
-rw-r--r--statement.c15
-rw-r--r--statement.h10
3 files changed, 23 insertions, 4 deletions
diff --git a/convert.c b/convert.c
index 3fc68d6..1fef061 100644
--- a/convert.c
+++ b/convert.c
@@ -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);