fix:convert empty string to NULL in A compatibility mode

This commit is contained in:
vimiix
2023-09-20 17:01:16 +08:00
parent a818ac9ae9
commit 12b2823c32
3 changed files with 41 additions and 2 deletions

View File

@ -46,6 +46,13 @@ extern "C" {
#define STATE_ON 1
#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 */
#define CONN_STATUS_SETUP 0
#define CONN_STATUS_READY 1
@ -148,6 +155,8 @@ struct connectionObject {
/* inside a with block */
int entered;
int sql_compatibility;
};
/* map isolation level values into a numeric const */

View File

@ -1268,6 +1268,9 @@ static struct PyMemberDef connectionObject_members[] = {
{"server_version", T_INT,
offsetof(connectionObject, server_version), READONLY,
"Server version."},
{"sql_compatibility", T_INT,
offsetof(connectionObject, sql_compatibility), READONLY,
"Server sql_compatibility param value."},
{NULL}
};
@ -1317,6 +1320,7 @@ static int
connection_setup(connectionObject *self, const char *dsn, long int async)
{
int rv = -1;
char *sql_compatibility_value = NULL;
Dprintf("connection_setup: init connection object at %p, "
"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->readonly = STATE_DEFAULT;
self->deferrable = STATE_DEFAULT;
self->sql_compatibility = SQL_COMPATIBILITY_A;
#ifdef CONN_CHECK_PID
self->procpid = getpid();
#endif
@ -1356,7 +1361,22 @@ connection_setup(connectionObject *self, const char *dsn, long int async)
FORMAT_CODE_PY_SSIZE_T,
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:
if (sql_compatibility_value){
free(sql_compatibility_value);
}
return rv;
}

View File

@ -684,7 +684,12 @@ curs_execute_prepared_batch(cursorObject *self, PyObject *args)
if (!(argItem = psyco_ensure_bytes(argItem))) {
goto exit;
}
paramValues[rowIdx * nParams + colIdx] = Bytes_AsString(argItem);
// 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);
}
}
Py_XDECREF(argItem);
}
@ -771,7 +776,12 @@ curs_execute_params_batch(cursorObject *self, PyObject *args)
if (!(argItem = psyco_ensure_bytes(argItem))) {
goto exit;
}
paramValues[rowIdx * nParams + colIdx] = Bytes_AsString(argItem);
// 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);
}
}
Py_XDECREF(argItem);
}