fix:convert empty string to NULL in A compatibility mode
This commit is contained in:
@ -46,6 +46,13 @@ extern "C" {
|
|||||||
#define STATE_ON 1
|
#define STATE_ON 1
|
||||||
#define STATE_DEFAULT 2
|
#define STATE_DEFAULT 2
|
||||||
|
|
||||||
|
/* sql_compatibility values */
|
||||||
|
#define SQL_COMPATIBILITY_A 1
|
||||||
|
#define SQL_COMPATIBILITY_OTHER 5
|
||||||
|
// #define SQL_COMPATIBILITY_B 2
|
||||||
|
// #define SQL_COMPATIBILITY_C 3
|
||||||
|
// #define SQL_COMPATIBILITY_PG 4
|
||||||
|
|
||||||
/* connection status */
|
/* connection status */
|
||||||
#define CONN_STATUS_SETUP 0
|
#define CONN_STATUS_SETUP 0
|
||||||
#define CONN_STATUS_READY 1
|
#define CONN_STATUS_READY 1
|
||||||
@ -148,6 +155,8 @@ struct connectionObject {
|
|||||||
|
|
||||||
/* inside a with block */
|
/* inside a with block */
|
||||||
int entered;
|
int entered;
|
||||||
|
|
||||||
|
int sql_compatibility;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* map isolation level values into a numeric const */
|
/* map isolation level values into a numeric const */
|
||||||
|
|||||||
@ -1268,6 +1268,9 @@ static struct PyMemberDef connectionObject_members[] = {
|
|||||||
{"server_version", T_INT,
|
{"server_version", T_INT,
|
||||||
offsetof(connectionObject, server_version), READONLY,
|
offsetof(connectionObject, server_version), READONLY,
|
||||||
"Server version."},
|
"Server version."},
|
||||||
|
{"sql_compatibility", T_INT,
|
||||||
|
offsetof(connectionObject, sql_compatibility), READONLY,
|
||||||
|
"Server sql_compatibility param value."},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1317,6 +1320,7 @@ static int
|
|||||||
connection_setup(connectionObject *self, const char *dsn, long int async)
|
connection_setup(connectionObject *self, const char *dsn, long int async)
|
||||||
{
|
{
|
||||||
int rv = -1;
|
int rv = -1;
|
||||||
|
char *sql_compatibility_value = NULL;
|
||||||
|
|
||||||
Dprintf("connection_setup: init connection object at %p, "
|
Dprintf("connection_setup: init connection object at %p, "
|
||||||
"async %ld, refcnt = " FORMAT_CODE_PY_SSIZE_T,
|
"async %ld, refcnt = " FORMAT_CODE_PY_SSIZE_T,
|
||||||
@ -1334,6 +1338,7 @@ connection_setup(connectionObject *self, const char *dsn, long int async)
|
|||||||
self->isolevel = ISOLATION_LEVEL_DEFAULT;
|
self->isolevel = ISOLATION_LEVEL_DEFAULT;
|
||||||
self->readonly = STATE_DEFAULT;
|
self->readonly = STATE_DEFAULT;
|
||||||
self->deferrable = STATE_DEFAULT;
|
self->deferrable = STATE_DEFAULT;
|
||||||
|
self->sql_compatibility = SQL_COMPATIBILITY_A;
|
||||||
#ifdef CONN_CHECK_PID
|
#ifdef CONN_CHECK_PID
|
||||||
self->procpid = getpid();
|
self->procpid = getpid();
|
||||||
#endif
|
#endif
|
||||||
@ -1356,7 +1361,22 @@ connection_setup(connectionObject *self, const char *dsn, long int async)
|
|||||||
FORMAT_CODE_PY_SSIZE_T,
|
FORMAT_CODE_PY_SSIZE_T,
|
||||||
self, Py_REFCNT(self));
|
self, Py_REFCNT(self));
|
||||||
|
|
||||||
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
|
pthread_mutex_lock(&self->lock);
|
||||||
|
sql_compatibility_value = pq_get_guc_locked(self, "sql_compatibility", &_save);
|
||||||
|
pthread_mutex_unlock(&self->lock);
|
||||||
|
Py_END_ALLOW_THREADS;
|
||||||
|
|
||||||
|
if (strcmp(sql_compatibility_value, "A") == 0) {
|
||||||
|
self->sql_compatibility = SQL_COMPATIBILITY_A;
|
||||||
|
} else {
|
||||||
|
self->sql_compatibility = SQL_COMPATIBILITY_OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
if (sql_compatibility_value){
|
||||||
|
free(sql_compatibility_value);
|
||||||
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -684,8 +684,13 @@ curs_execute_prepared_batch(cursorObject *self, PyObject *args)
|
|||||||
if (!(argItem = psyco_ensure_bytes(argItem))) {
|
if (!(argItem = psyco_ensure_bytes(argItem))) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
// convert empty string to NULL in A compatibility mode
|
||||||
|
if (self->conn->sql_compatibility == SQL_COMPATIBILITY_A && PyObject_Length(argItem) == 0) {
|
||||||
|
paramValues[rowIdx * nParams + colIdx] = NULL;
|
||||||
|
} else {
|
||||||
paramValues[rowIdx * nParams + colIdx] = Bytes_AsString(argItem);
|
paramValues[rowIdx * nParams + colIdx] = Bytes_AsString(argItem);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Py_XDECREF(argItem);
|
Py_XDECREF(argItem);
|
||||||
}
|
}
|
||||||
Py_XDECREF(rowArgs);
|
Py_XDECREF(rowArgs);
|
||||||
@ -771,8 +776,13 @@ curs_execute_params_batch(cursorObject *self, PyObject *args)
|
|||||||
if (!(argItem = psyco_ensure_bytes(argItem))) {
|
if (!(argItem = psyco_ensure_bytes(argItem))) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
// convert empty string to NULL in A compatibility mode
|
||||||
|
if (self->conn->sql_compatibility == SQL_COMPATIBILITY_A && PyObject_Length(argItem) == 0) {
|
||||||
|
paramValues[rowIdx * nParams + colIdx] = NULL;
|
||||||
|
} else {
|
||||||
paramValues[rowIdx * nParams + colIdx] = Bytes_AsString(argItem);
|
paramValues[rowIdx * nParams + colIdx] = Bytes_AsString(argItem);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Py_XDECREF(argItem);
|
Py_XDECREF(argItem);
|
||||||
}
|
}
|
||||||
Py_XDECREF(rowArgs);
|
Py_XDECREF(rowArgs);
|
||||||
|
|||||||
Reference in New Issue
Block a user