You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Thesignatureofsqlite3_prepare_v2isasfollows:
intsqlite3_prepare_v2(
sqlite3*db, /* Database handle */constchar*zSql, /* SQL statement, UTF-8 encoded */intnByte, /* Maximum length of zSql in bytes. */sqlite3_stmt**ppStmt, /* OUT: Statement handle */constchar**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.
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.
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.
New changeset fbf25b8 by Erlend Egeberg Aasland in branch 'main': bpo-44165: pysqlite_statement_create now returns a Py object, not an int (GH-26484) fbf25b8
Activity
erlend-aasland commentedon May 18, 2021
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
erlend-aasland commentedon May 18, 2021
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.
erlend-aasland commentedon May 19, 2021
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.
erlend-aasland commentedon May 19, 2021
SQLITE_TOOBIG is currently mapped to sqlite3.DataError. In order to keep the current behaviour, DataError must be raised.
pablogsal commentedon Jun 2, 2021
New changeset a384b6c by Erlend Egeberg Aasland in branch 'main':
bpo-44165: Optimise sqlite3 statement preparation by passing string size (GH-26206)
a384b6c
pablogsal commentedon Jun 2, 2021
Erlend, check out #26206 (comment). After that we can close this issue
pablogsal commentedon Jun 2, 2021
New changeset fbf25b8 by Erlend Egeberg Aasland in branch 'main':
bpo-44165: pysqlite_statement_create now returns a Py object, not an int (GH-26484)
fbf25b8
erlend-aasland commentedon Jun 2, 2021
See msg393857: I'll add a PR for _pysqlite_connection_begin as well. After that, we can close this.
erlend-aasland commentedon May 18, 2022
IMO, the added complexity is not worth it to change the remaining usages. Closing this issue.