bpo-44165: Optimise sqlite3 statement preparation by passing string size (GH-26206)
This commit is contained in:
parent
ee7637596d
commit
a384b6c040
@ -451,7 +451,7 @@ pysqlite_connection_commit_impl(pysqlite_Connection *self)
|
|||||||
if (!sqlite3_get_autocommit(self->db)) {
|
if (!sqlite3_get_autocommit(self->db)) {
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
rc = sqlite3_prepare_v2(self->db, "COMMIT", -1, &statement, NULL);
|
rc = sqlite3_prepare_v2(self->db, "COMMIT", 7, &statement, NULL);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
if (rc != SQLITE_OK) {
|
if (rc != SQLITE_OK) {
|
||||||
_pysqlite_seterror(self->db);
|
_pysqlite_seterror(self->db);
|
||||||
@ -501,7 +501,7 @@ pysqlite_connection_rollback_impl(pysqlite_Connection *self)
|
|||||||
pysqlite_do_all_statements(self, ACTION_RESET, 1);
|
pysqlite_do_all_statements(self, ACTION_RESET, 1);
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
rc = sqlite3_prepare_v2(self->db, "ROLLBACK", -1, &statement, NULL);
|
rc = sqlite3_prepare_v2(self->db, "ROLLBACK", 9, &statement, NULL);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
if (rc != SQLITE_OK) {
|
if (rc != SQLITE_OK) {
|
||||||
_pysqlite_seterror(self->db);
|
_pysqlite_seterror(self->db);
|
||||||
|
@ -696,6 +696,7 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj)
|
|||||||
const char* script_cstr;
|
const char* script_cstr;
|
||||||
sqlite3_stmt* statement;
|
sqlite3_stmt* statement;
|
||||||
int rc;
|
int rc;
|
||||||
|
Py_ssize_t sql_len;
|
||||||
PyObject* result;
|
PyObject* result;
|
||||||
|
|
||||||
if (!check_cursor(self)) {
|
if (!check_cursor(self)) {
|
||||||
@ -705,10 +706,17 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj)
|
|||||||
self->reset = 0;
|
self->reset = 0;
|
||||||
|
|
||||||
if (PyUnicode_Check(script_obj)) {
|
if (PyUnicode_Check(script_obj)) {
|
||||||
script_cstr = PyUnicode_AsUTF8(script_obj);
|
script_cstr = PyUnicode_AsUTF8AndSize(script_obj, &sql_len);
|
||||||
if (!script_cstr) {
|
if (!script_cstr) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int max_length = sqlite3_limit(self->connection->db,
|
||||||
|
SQLITE_LIMIT_LENGTH, -1);
|
||||||
|
if (sql_len >= max_length) {
|
||||||
|
PyErr_SetString(pysqlite_DataError, "query string is too large");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
PyErr_SetString(PyExc_ValueError, "script argument must be unicode.");
|
PyErr_SetString(PyExc_ValueError, "script argument must be unicode.");
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -722,12 +730,14 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj)
|
|||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
const char *tail;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
rc = sqlite3_prepare_v2(self->connection->db,
|
rc = sqlite3_prepare_v2(self->connection->db,
|
||||||
script_cstr,
|
script_cstr,
|
||||||
-1,
|
(int)sql_len + 1,
|
||||||
&statement,
|
&statement,
|
||||||
&script_cstr);
|
&tail);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
if (rc != SQLITE_OK) {
|
if (rc != SQLITE_OK) {
|
||||||
_pysqlite_seterror(self->connection->db);
|
_pysqlite_seterror(self->connection->db);
|
||||||
@ -755,9 +765,11 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*script_cstr == (char)0) {
|
if (*tail == (char)0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
sql_len -= (tail - script_cstr);
|
||||||
|
script_cstr = tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -66,6 +66,12 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql)
|
|||||||
Py_TYPE(sql)->tp_name);
|
Py_TYPE(sql)->tp_name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int max_length = sqlite3_limit(connection->db, SQLITE_LIMIT_LENGTH, -1);
|
||||||
|
if (sql_cstr_len >= max_length) {
|
||||||
|
PyErr_SetString(pysqlite_DataError, "query string is too large");
|
||||||
|
return PYSQLITE_TOO_MUCH_SQL;
|
||||||
|
}
|
||||||
if (strlen(sql_cstr) != (size_t)sql_cstr_len) {
|
if (strlen(sql_cstr) != (size_t)sql_cstr_len) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"the query contains a null character");
|
"the query contains a null character");
|
||||||
@ -106,7 +112,7 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql)
|
|||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
rc = sqlite3_prepare_v2(self->db,
|
rc = sqlite3_prepare_v2(self->db,
|
||||||
sql_cstr,
|
sql_cstr,
|
||||||
-1,
|
(int)sql_cstr_len + 1,
|
||||||
&self->st,
|
&self->st,
|
||||||
&tail);
|
&tail);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
Loading…
x
Reference in New Issue
Block a user