mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-11 11:36:37 +03:00
Return input tuple in cur.callproc, factor code to use PQescapeIdentifier in single place
This commit is contained in:
parent
92109e4bba
commit
0772d187e9
|
@ -1015,35 +1015,6 @@ exit:
|
||||||
#define psyco_curs_callproc_doc \
|
#define psyco_curs_callproc_doc \
|
||||||
"callproc(procname, parameters=None) -- Execute stored procedure."
|
"callproc(procname, parameters=None) -- Execute stored procedure."
|
||||||
|
|
||||||
/* Call PQescapeIdentifier.
|
|
||||||
*
|
|
||||||
* In case of error set a Python exception.
|
|
||||||
*
|
|
||||||
* TODO: this function can become more generic and go into utils
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
_escape_identifier(PGconn *pgconn, const char *str, size_t length)
|
|
||||||
{
|
|
||||||
char *rv = NULL;
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= 90000
|
|
||||||
rv = PQescapeIdentifier(pgconn, str, length);
|
|
||||||
if (!rv) {
|
|
||||||
char *msg;
|
|
||||||
msg = PQerrorMessage(pgconn);
|
|
||||||
if (!msg || !msg[0]) {
|
|
||||||
msg = "no message provided";
|
|
||||||
}
|
|
||||||
PyErr_Format(InterfaceError, "failed to escape identifier: %s", msg);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
PyErr_Format(PyExc_NotImplementedError,
|
|
||||||
"named parameters require psycopg2 compiled against libpq 9.0+");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_curs_callproc(cursorObject *self, PyObject *args)
|
psyco_curs_callproc(cursorObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
@ -1107,7 +1078,7 @@ psyco_curs_callproc(cursorObject *self, PyObject *args)
|
||||||
if (!(pname = psycopg_ensure_bytes(pname))) { goto exit; }
|
if (!(pname = psycopg_ensure_bytes(pname))) { goto exit; }
|
||||||
if (!(cpname = Bytes_AsString(pname))) { goto exit; }
|
if (!(cpname = Bytes_AsString(pname))) { goto exit; }
|
||||||
|
|
||||||
if (!(scpnames[i] = _escape_identifier(
|
if (!(scpnames[i] = psycopg_escape_identifier(
|
||||||
self->conn->pgconn, cpname, strlen(cpname)))) {
|
self->conn->pgconn, cpname, strlen(cpname)))) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
@ -1158,11 +1129,15 @@ psyco_curs_callproc(cursorObject *self, PyObject *args)
|
||||||
|
|
||||||
if (0 <= _psyco_curs_execute(
|
if (0 <= _psyco_curs_execute(
|
||||||
self, operation, pvals, self->conn->async, 0)) {
|
self, operation, pvals, self->conn->async, 0)) {
|
||||||
|
/* The dict case is outside DBAPI scope anyway, so simply return None */
|
||||||
/* return None from this until it's DBAPI compliant... */
|
if (using_dict) {
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
res = Py_None;
|
res = Py_None;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
res = pvals;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (scpnames != NULL) {
|
if (scpnames != NULL) {
|
||||||
|
|
|
@ -124,6 +124,7 @@ RAISES HIDDEN PyObject *psyco_set_error(PyObject *exc, cursorObject *curs, const
|
||||||
HIDDEN char *psycopg_escape_string(connectionObject *conn,
|
HIDDEN char *psycopg_escape_string(connectionObject *conn,
|
||||||
const char *from, Py_ssize_t len, char *to, Py_ssize_t *tolen);
|
const char *from, Py_ssize_t len, char *to, Py_ssize_t *tolen);
|
||||||
HIDDEN char *psycopg_escape_identifier_easy(const char *from, Py_ssize_t len);
|
HIDDEN char *psycopg_escape_identifier_easy(const char *from, Py_ssize_t len);
|
||||||
|
HIDDEN char *psycopg_escape_identifier(PGconn *pgconn, const char *str, size_t length);
|
||||||
HIDDEN int psycopg_strdup(char **to, const char *from, Py_ssize_t len);
|
HIDDEN int psycopg_strdup(char **to, const char *from, Py_ssize_t len);
|
||||||
HIDDEN int psycopg_is_text_file(PyObject *f);
|
HIDDEN int psycopg_is_text_file(PyObject *f);
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,6 @@
|
||||||
HIDDEN PyObject *pyDateTimeModuleP = NULL;
|
HIDDEN PyObject *pyDateTimeModuleP = NULL;
|
||||||
|
|
||||||
HIDDEN PyObject *psycoEncodings = NULL;
|
HIDDEN PyObject *psycoEncodings = NULL;
|
||||||
|
|
||||||
#ifdef PSYCOPG_DEBUG
|
#ifdef PSYCOPG_DEBUG
|
||||||
HIDDEN int psycopg_debug_enabled = 0;
|
HIDDEN int psycopg_debug_enabled = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -175,7 +174,6 @@ exit:
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_quote_ident(PyObject *self, PyObject *args, PyObject *kwargs)
|
psyco_quote_ident(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
#if PG_VERSION_NUM >= 90000
|
|
||||||
PyObject *ident = NULL, *obj = NULL, *result = NULL;
|
PyObject *ident = NULL, *obj = NULL, *result = NULL;
|
||||||
connectionObject *conn;
|
connectionObject *conn;
|
||||||
const char *str;
|
const char *str;
|
||||||
|
@ -203,9 +201,8 @@ psyco_quote_ident(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
|
|
||||||
str = Bytes_AS_STRING(ident);
|
str = Bytes_AS_STRING(ident);
|
||||||
|
|
||||||
quoted = PQescapeIdentifier(conn->pgconn, str, strlen(str));
|
quoted = psycopg_escape_identifier(conn->pgconn, str, strlen(str));
|
||||||
if (!quoted) {
|
if (!quoted) {
|
||||||
PyErr_NoMemory();
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
result = conn_text_from_chars(conn, quoted);
|
result = conn_text_from_chars(conn, quoted);
|
||||||
|
@ -215,10 +212,6 @@ exit:
|
||||||
Py_XDECREF(ident);
|
Py_XDECREF(ident);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
#else
|
|
||||||
PyErr_SetString(NotSupportedError, "PQescapeIdentifier not available in libpq < 9.0");
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** type registration **/
|
/** type registration **/
|
||||||
|
|
|
@ -95,8 +95,8 @@ psycopg_escape_string(connectionObject *conn, const char *from, Py_ssize_t len,
|
||||||
* The returned string doesn't include quotes.
|
* The returned string doesn't include quotes.
|
||||||
*
|
*
|
||||||
* WARNING: this function is not so safe to allow untrusted input: it does no
|
* WARNING: this function is not so safe to allow untrusted input: it does no
|
||||||
* check for multibyte chars. Such a function should be built on
|
* check for multibyte chars. Functions otherwise reliant on PostgreSQL 9.0
|
||||||
* PQescapeIdentifier, which is only available from PostgreSQL 9.0.
|
* and above should use the below function psycopg_escape_identifier instead.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
psycopg_escape_identifier_easy(const char *from, Py_ssize_t len)
|
psycopg_escape_identifier_easy(const char *from, Py_ssize_t len)
|
||||||
|
@ -124,6 +124,35 @@ psycopg_escape_identifier_easy(const char *from, Py_ssize_t len)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Call PostgreSQL 9.0+ function PQescapeIdentifier.
|
||||||
|
*
|
||||||
|
* In case of error set a Python exception.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
psycopg_escape_identifier(PGconn *pgconn, const char *str, size_t length)
|
||||||
|
{
|
||||||
|
char *rv = NULL;
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= 90000
|
||||||
|
rv = PQescapeIdentifier(pgconn, str, length);
|
||||||
|
if (!rv) {
|
||||||
|
char *msg;
|
||||||
|
msg = PQerrorMessage(pgconn);
|
||||||
|
if (!msg || !msg[0]) {
|
||||||
|
msg = "no message provided";
|
||||||
|
}
|
||||||
|
PyErr_Format(InterfaceError, "failed to escape identifier: %s", msg);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
PyErr_Format(PyExc_NotImplementedError,
|
||||||
|
"PQescapeIdentifier requires psycopg2 compiled against libpq 9.0+");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Duplicate a string.
|
/* Duplicate a string.
|
||||||
*
|
*
|
||||||
* Allocate a new buffer on the Python heap containing the new string.
|
* Allocate a new buffer on the Python heap containing the new string.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user