ImageImage

This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: [sqlite3] sqlite3_prepare_v2 micro optimisation: pass string size
Type: performance Stage: patch review
Components: Extension Modules Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: berker.peksag, erlendaasland, pablogsal, serhiy.storchaka
Priority: low Keywords: patch

Created on 2021-05-18 07:23 by erlendaasland, last changed 2022-04-11 14:59 by admin.

Pull Requests
URL Status Linked Edit
PR 26206 merged erlendaasland, 2021-05-18 07:26
PR 26484 merged erlendaasland, 2021-06-02 12:41
PR 26485 closed erlendaasland, 2021-06-02 13:26
Messages (8)
msg393856 - (view) Author: Erlend E. Aasland (erlendaasland) * (Python triager) Date: 2021-05-18 07:23
The signature of sqlite3_prepare_v2 is as follows:
int sqlite3_prepare_v2(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);


Quoting from the SQLite docs[1]:
"If the caller knows that the supplied string is nul-terminated, then there is a small performance advantage to passing an nByte parameter that is the number of bytes in the input string including the nul-terminator."


sqlite3_prepare_v2 is used five places in the sqlite3 module. We can easily provide the string size in those places.



[1] https://sqlite.org/c3ref/prepare.html
msg393857 - (view) Author: Erlend E. Aasland (erlendaasland) * (Python triager) Date: 2021-05-18 07:31
Note, PR 26206 does not include statement creation in _pysqlite_connection_begin (Modules/_sqlite/connection.c). That needs further refactoring, so I'll add that in a separate PR if PR 26206 is accepted.
msg393978 - (view) Author: Erlend E. Aasland (erlendaasland) * (Python triager) Date: 2021-05-19 21:42
Regarding the maximum length of an SQL string, quoting from https://sqlite.org/limits.html:
"The current implementation will only support a string or BLOB length up to 2^31-1 or 2147483647. And some built-in functions such as hex() might fail well before that point. In security-sensitive applications it is best not to try to increase the maximum string and blob length. In fact, you might do well to lower the maximum string and blob length to something more in the range of a few million if that is possible."

The size returned from functions such as PyUnicode_AsUTF8AndSize is Py_ssize_t. I suggest checking the passed SQL string size and raising OverflowError if the SQL string is larger than SQLITE_MAX_LENGTH.
msg393980 - (view) Author: Erlend E. Aasland (erlendaasland) * (Python triager) Date: 2021-05-19 22:10
SQLITE_TOOBIG is currently mapped to sqlite3.DataError. In order to keep the current behaviour, DataError must be raised.
msg394900 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2021-06-02 12:26
New changeset a384b6c04054a2c5050a99059836175cf73e2016 by Erlend Egeberg Aasland in branch 'main':
bpo-44165: Optimise sqlite3 statement preparation by passing string size (GH-26206)
https://github.com/python/cpython/commit/a384b6c04054a2c5050a99059836175cf73e2016
msg394901 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2021-06-02 12:27
Erlend, check out https://github.com/python/cpython/pull/26206#discussion_r643910263. After that we can close this issue
msg394904 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2021-06-02 13:22
New changeset fbf25b8c0dd1e62db59117d53bbd2d4131a06867 by Erlend Egeberg Aasland in branch 'main':
bpo-44165: pysqlite_statement_create now returns a Py object, not an int (GH-26484)
https://github.com/python/cpython/commit/fbf25b8c0dd1e62db59117d53bbd2d4131a06867
msg394905 - (view) Author: Erlend E. Aasland (erlendaasland) * (Python triager) Date: 2021-06-02 13:23
> Erlend, check out https://github.com/python/cpython/pull/26206#discussion_r643910263. After that we can close this issue

See msg393857: I'll add a PR for _pysqlite_connection_begin as well. After that, we can close this.
History
Date User Action Args
2022-04-11 14:59:45adminsetgithub: 88331
2021-06-02 13:26:30erlendaaslandsetpull_requests: + pull_request25081
2021-06-02 13:23:49erlendaaslandsetmessages: + msg394905
2021-06-02 13:22:24pablogsalsetmessages: + msg394904
2021-06-02 12:41:55erlendaaslandsetpull_requests: + pull_request25080
2021-06-02 12:27:23pablogsalsetmessages: + msg394901
2021-06-02 12:26:13pablogsalsetnosy: + pablogsal
messages: + msg394900
2021-05-19 22:10:53erlendaaslandsetmessages: + msg393980
2021-05-19 21:42:45erlendaaslandsetmessages: + msg393978
2021-05-19 21:42:21erlendaaslandsetmessages: - msg393977
2021-05-19 21:40:54erlendaaslandsetmessages: + msg393977
2021-05-18 07:31:49erlendaaslandsetmessages: + msg393857
2021-05-18 07:26:18erlendaaslandsetkeywords: + patch
stage: patch review
pull_requests: + pull_request24823
2021-05-18 07:23:06erlendaaslandcreate