Skip to content

Commit f4b9fcd

Browse files
author
Erlend E. Aasland
committed
bpo-45243: Add support for setting/getting sqlite3 connection limits
1 parent 6c942a8 commit f4b9fcd

File tree

5 files changed

+179
-0
lines changed

5 files changed

+179
-0
lines changed

Doc/library/sqlite3.rst

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,78 @@ Connection Objects
624624
.. versionadded:: 3.7
625625

626626

627+
.. attribute:: SQLITE_LIMIT_SQL_LENGTH
628+
629+
The maximum length of an SQL statement, in bytes.
630+
631+
.. versionadded:: 3.11
632+
633+
.. attribute:: SQLITE_LIMIT_COLUMN
634+
635+
The maximum number of columns in a table definition or in the result set
636+
of a SELECT or the maximum number of columns in an index or in an ORDER
637+
BY or GROUP BY clause.
638+
639+
.. versionadded:: 3.11
640+
641+
.. attribute:: SQLITE_LIMIT_EXPR_DEPTH
642+
643+
The maximum depth of the parse tree on any expression.
644+
645+
.. versionadded:: 3.11
646+
647+
.. attribute:: SQLITE_LIMIT_COMPOUND_SELECT
648+
649+
The maximum number of terms in a compound SELECT statement.
650+
651+
.. versionadded:: 3.11
652+
653+
.. attribute:: SQLITE_LIMIT_VDBE_OP
654+
655+
The maximum number of instructions in a virtual machine program used to
656+
implement an SQL statement.
657+
658+
.. versionadded:: 3.11
659+
660+
.. attribute:: SQLITE_LIMIT_FUNCTION_ARG
661+
662+
The maximum number of arguments on a function.
663+
664+
.. versionadded:: 3.11
665+
666+
.. attribute:: SQLITE_LIMIT_ATTACHED
667+
668+
The maximum number of attached databases.
669+
670+
.. versionadded:: 3.11
671+
672+
.. attribute:: SQLITE_LIMIT_LIKE_PATTERN_LENGTH
673+
674+
The maximum length of the pattern argument to the LIKE or GLOB operators.
675+
676+
.. versionadded:: 3.11
677+
678+
)
679+
.. attribute:: SQLITE_LIMIT_VARIABLE_NUMBER
680+
681+
The maximum index number of any parameter in an SQL statement.
682+
683+
.. versionadded:: 3.11
684+
685+
.. attribute:: SQLITE_LIMIT_TRIGGER_DEPTH
686+
687+
The maximum depth of recursion for triggers.
688+
689+
.. versionadded:: 3.11
690+
691+
.. attribute:: SQLITE_LIMIT_WORKER_THREADS
692+
693+
The maximum number of auxiliary worker threads that a single prepared
694+
statement may start. Only available for SQLite 3.8.3 or newer.
695+
696+
.. versionadded:: 3.11
697+
698+
627699
.. _sqlite3-cursor-objects:
628700

629701
Cursor Objects

Doc/whatsnew/3.11.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,11 @@ sqlite3
239239
(Contributed by Aviv Palivoda, Daniel Shahaf, and Erlend E. Aasland in
240240
:issue:`16379`.)
241241

242+
* Connection limits are now exposed as :class:`sqlite3.Connection`
243+
attributes.
244+
(Contributed by Erlend E. Aasland in :issue:`45243`.)
245+
246+
242247
threading
243248
---------
244249

Lib/sqlite3/test/test_dbapi.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,18 @@ def test_drop_unused_refs(self):
332332
cu = self.cx.execute(f"select {n}")
333333
self.assertEqual(cu.fetchone()[0], n)
334334

335+
def test_connection_limits(self):
336+
setval = 10
337+
limit = self.cx.SQLITE_LIMIT_SQL_LENGTH
338+
try:
339+
self.cx.SQLITE_LIMIT_SQL_LENGTH = setval
340+
self.assertEqual(self.cx.SQLITE_LIMIT_SQL_LENGTH, setval)
341+
msg = "string or blob too big"
342+
self.assertRaisesRegex(sqlite.DataError, msg,
343+
self.cx.execute, "select 1 as '16'")
344+
finally: # restore old limit
345+
self.cx.SQLITE_LIMIT_SQL_LENGTH = limit
346+
335347

336348
class UninitialisedConnectionTests(unittest.TestCase):
337349
def setUp(self):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
SQLite connection limits are now exposed as :class:`sqlite3.Connection`
2+
attributes. Patch by Erlend E. Aasland.

Modules/_sqlite/connection.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1866,13 +1866,101 @@ pysqlite_connection_exit_impl(pysqlite_Connection *self, PyObject *exc_type,
18661866
Py_RETURN_FALSE;
18671867
}
18681868

1869+
static
1870+
PyObject *get_limit(pysqlite_Connection *self, void *limit)
1871+
{
1872+
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
1873+
return NULL;
1874+
}
1875+
1876+
int value = sqlite3_limit(self->db, (int)limit, -1);
1877+
return PyLong_FromLong(value);
1878+
}
1879+
1880+
static int
1881+
set_limit(pysqlite_Connection *self, PyObject *value, void *limit)
1882+
{
1883+
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
1884+
return -1;
1885+
}
1886+
if (value == NULL) {
1887+
PyErr_SetString(self->ProgrammingError,
1888+
"Cannot delete limit attributes");
1889+
return -1;
1890+
}
1891+
int setval = _PyLong_AsInt(value);
1892+
if (setval == -1 && PyErr_Occurred()) {
1893+
return -1;
1894+
}
1895+
(void)sqlite3_limit(self->db, (int)limit, setval);
1896+
return 0;
1897+
}
1898+
18691899
static const char connection_doc[] =
18701900
PyDoc_STR("SQLite database connection object.");
18711901

1902+
#define DEF_LIMIT_GETSET(limit, doc) \
1903+
{#limit, (getter)get_limit, (setter)set_limit, doc, (void *)limit},
1904+
18721905
static PyGetSetDef connection_getset[] = {
18731906
{"isolation_level", (getter)pysqlite_connection_get_isolation_level, (setter)pysqlite_connection_set_isolation_level},
18741907
{"total_changes", (getter)pysqlite_connection_get_total_changes, (setter)0},
18751908
{"in_transaction", (getter)pysqlite_connection_get_in_transaction, (setter)0},
1909+
DEF_LIMIT_GETSET(
1910+
SQLITE_LIMIT_LENGTH,
1911+
"The maximum size of any string or BLOB or table row, in bytes."
1912+
)
1913+
DEF_LIMIT_GETSET(
1914+
SQLITE_LIMIT_SQL_LENGTH,
1915+
"The maximum length of an SQL statement, in bytes."
1916+
)
1917+
DEF_LIMIT_GETSET(
1918+
SQLITE_LIMIT_COLUMN,
1919+
"The maximum number of columns in a table definition or in the result "
1920+
"set of a SELECT or the maximum number of columns in an index or in an "
1921+
"ORDER BY or GROUP BY clause."
1922+
)
1923+
DEF_LIMIT_GETSET(
1924+
SQLITE_LIMIT_EXPR_DEPTH,
1925+
"The maximum depth of the parse tree on any expression."
1926+
)
1927+
DEF_LIMIT_GETSET(
1928+
SQLITE_LIMIT_COMPOUND_SELECT,
1929+
"The maximum number of terms in a compound SELECT statement."
1930+
)
1931+
DEF_LIMIT_GETSET(
1932+
SQLITE_LIMIT_VDBE_OP,
1933+
"The maximum number of instructions in a virtual machine program used "
1934+
"to implement an SQL statement."
1935+
)
1936+
DEF_LIMIT_GETSET(
1937+
SQLITE_LIMIT_FUNCTION_ARG,
1938+
"The maximum number of arguments on a function."
1939+
)
1940+
DEF_LIMIT_GETSET(
1941+
SQLITE_LIMIT_ATTACHED,
1942+
"The maximum number of attached databases."
1943+
)
1944+
DEF_LIMIT_GETSET(
1945+
SQLITE_LIMIT_LIKE_PATTERN_LENGTH,
1946+
"The maximum length of the pattern argument to the LIKE or GLOB "
1947+
"operators."
1948+
)
1949+
DEF_LIMIT_GETSET(
1950+
SQLITE_LIMIT_VARIABLE_NUMBER,
1951+
"The maximum index number of any parameter in an SQL statement."
1952+
)
1953+
DEF_LIMIT_GETSET(
1954+
SQLITE_LIMIT_TRIGGER_DEPTH,
1955+
"The maximum depth of recursion for triggers."
1956+
)
1957+
#if SQLITE_VERSION_NUMBER >= 3008003
1958+
DEF_LIMIT_GETSET(
1959+
SQLITE_LIMIT_WORKER_THREADS,
1960+
"The maximum number of auxiliary worker threads that a single "
1961+
"prepared statement may start."
1962+
)
1963+
#endif
18761964
{NULL}
18771965
};
18781966

0 commit comments

Comments
 (0)