diff options
author | Erlend Egeberg Aasland <erlend.aasland@innova.no> | 2021-06-02 12:26:06 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-02 12:26:06 (GMT) |
commit | a384b6c04054a2c5050a99059836175cf73e2016 (patch) | |
tree | e55ca9e7067504c22ae77a5ba6df21e4312cd5b3 /Modules/_sqlite/cursor.c | |
parent | ee7637596d8de25f54261bbeabc602d31e74f482 (diff) | |
download | cpython-a384b6c04054a2c5050a99059836175cf73e2016.zip cpython-a384b6c04054a2c5050a99059836175cf73e2016.tar.gz cpython-a384b6c04054a2c5050a99059836175cf73e2016.tar.bz2 |
bpo-44165: Optimise sqlite3 statement preparation by passing string size (GH-26206)
Diffstat (limited to 'Modules/_sqlite/cursor.c')
-rw-r--r-- | Modules/_sqlite/cursor.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 7656c90..757c389 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -696,6 +696,7 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj) const char* script_cstr; sqlite3_stmt* statement; int rc; + Py_ssize_t sql_len; PyObject* result; if (!check_cursor(self)) { @@ -705,10 +706,17 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj) self->reset = 0; if (PyUnicode_Check(script_obj)) { - script_cstr = PyUnicode_AsUTF8(script_obj); + script_cstr = PyUnicode_AsUTF8AndSize(script_obj, &sql_len); if (!script_cstr) { 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 { PyErr_SetString(PyExc_ValueError, "script argument must be unicode."); return NULL; @@ -722,12 +730,14 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj) Py_DECREF(result); while (1) { + const char *tail; + Py_BEGIN_ALLOW_THREADS rc = sqlite3_prepare_v2(self->connection->db, script_cstr, - -1, + (int)sql_len + 1, &statement, - &script_cstr); + &tail); Py_END_ALLOW_THREADS if (rc != SQLITE_OK) { _pysqlite_seterror(self->connection->db); @@ -755,9 +765,11 @@ pysqlite_cursor_executescript(pysqlite_Cursor *self, PyObject *script_obj) goto error; } - if (*script_cstr == (char)0) { + if (*tail == (char)0) { break; } + sql_len -= (tail - script_cstr); + script_cstr = tail; } error: |