_psyco_curs_execute() simplified

Dropped code duplications, more regular increc/decref pattern.

Check the return value of formatting named cursor: would have segfaulted
in case of error.
This commit is contained in:
Daniele Varrazzo 2019-01-02 11:51:54 +01:00
parent 594df09a63
commit c77615adc9

View File

@ -372,20 +372,17 @@ _psyco_curs_merge_query_args(cursorObject *self,
RAISES_NEG static int RAISES_NEG static int
_psyco_curs_execute(cursorObject *self, _psyco_curs_execute(cursorObject *self,
PyObject *operation, PyObject *vars, PyObject *query, PyObject *vars,
long int async, int no_result) long int async, int no_result)
{ {
int res = -1; int res = -1;
int tmp; int tmp;
PyObject *fquery, *cvt = NULL; PyObject *fquery = NULL, *cvt = NULL;
const char *scroll;
operation = psyco_curs_validate_sql_basic(self, operation); /* query becomes NULL or refcount +1, so good to XDECREF at the end */
if (!(query = psyco_curs_validate_sql_basic(self, query))) {
/* Any failure from here forward should 'goto fail' rather than 'return 0' goto exit;
directly. */ }
if (operation == NULL) { goto exit; }
CLEARPGRES(self->pgres); CLEARPGRES(self->pgres);
Py_CLEAR(self->query); Py_CLEAR(self->query);
@ -394,12 +391,24 @@ _psyco_curs_execute(cursorObject *self,
/* here we are, and we have a sequence or a dictionary filled with /* here we are, and we have a sequence or a dictionary filled with
objects to be substituted (bound variables). we try to be smart and do objects to be substituted (bound variables). we try to be smart and do
the right thing (i.e., what the user expects) */ the right thing (i.e., what the user expects) */
if (vars && vars != Py_None) if (vars && vars != Py_None)
{ {
if (0 > _mogrify(vars, operation, self, &cvt)) { goto exit; } if (0 > _mogrify(vars, query, self, &cvt)) { goto exit; }
} }
/* Merge the query to the arguments if needed */
if (cvt) {
if (!(fquery = _psyco_curs_merge_query_args(self, query, cvt))) {
goto exit;
}
}
else {
Py_INCREF(query);
fquery = query;
}
if (self->qname != NULL) {
const char *scroll;
switch (self->scrollable) { switch (self->scrollable) {
case -1: case -1:
scroll = ""; scroll = "";
@ -415,44 +424,23 @@ _psyco_curs_execute(cursorObject *self,
goto exit; goto exit;
} }
if (vars && cvt) { if (!(self->query = Bytes_FromFormat(
if (!(fquery = _psyco_curs_merge_query_args(self, operation, cvt))) { "DECLARE %s %sCURSOR %s HOLD FOR %s",
self->qname,
scroll,
self->withhold ? "WITH" : "WITHOUT",
Bytes_AS_STRING(fquery)))) {
goto exit; goto exit;
} }
if (!self->query) { goto exit; }
if (self->qname != NULL) {
self->query = Bytes_FromFormat(
"DECLARE %s %sCURSOR %s HOLD FOR %s",
self->qname,
scroll,
self->withhold ? "WITH" : "WITHOUT",
Bytes_AS_STRING(fquery));
Py_DECREF(fquery);
} }
else { else {
/* Transfer ownership */
Py_INCREF(fquery);
self->query = fquery; self->query = fquery;
} }
}
else {
if (self->qname != NULL) {
self->query = Bytes_FromFormat(
"DECLARE %s %sCURSOR %s HOLD FOR %s",
self->qname,
scroll,
self->withhold ? "WITH" : "WITHOUT",
Bytes_AS_STRING(operation));
}
else {
/* Transfer reference ownership of the str in operation to
self->query, clearing the local variable to prevent cleanup from
DECREFing it */
self->query = operation;
operation = NULL;
}
}
/* At this point, the SQL statement must be str, not unicode */ /* At this point, the SQL statement must be str, not unicode */
tmp = pq_execute(self, Bytes_AS_STRING(self->query), async, no_result, 0); tmp = pq_execute(self, Bytes_AS_STRING(self->query), async, no_result, 0);
Dprintf("psyco_curs_execute: res = %d, pgres = %p", tmp, self->pgres); Dprintf("psyco_curs_execute: res = %d, pgres = %p", tmp, self->pgres);
if (tmp < 0) { goto exit; } if (tmp < 0) { goto exit; }
@ -460,10 +448,8 @@ _psyco_curs_execute(cursorObject *self,
res = 0; /* Success */ res = 0; /* Success */
exit: exit:
/* Py_XDECREF(operation) is safe because the original reference passed Py_XDECREF(query);
by the caller was overwritten with either NULL or a new Py_XDECREF(fquery);
reference */
Py_XDECREF(operation);
Py_XDECREF(cvt); Py_XDECREF(cvt);
return res; return res;