• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Run-Time Limits
2 
3 use crate::{ffi, Connection};
4 use std::os::raw::c_int;
5 
6 /// Run-Time limit categories, for use with [`Connection::limit`] and
7 /// [`Connection::set_limit`].
8 ///
9 /// See the official documentation for more information:
10 /// - <https://www.sqlite.org/c3ref/c_limit_attached.html>
11 /// - <https://www.sqlite.org/limits.html>
12 #[repr(i32)]
13 #[non_exhaustive]
14 #[allow(clippy::upper_case_acronyms, non_camel_case_types)]
15 #[cfg_attr(docsrs, doc(cfg(feature = "limits")))]
16 pub enum Limit {
17     /// The maximum size of any string or BLOB or table row, in bytes.
18     SQLITE_LIMIT_LENGTH = ffi::SQLITE_LIMIT_LENGTH,
19     /// The maximum length of an SQL statement, in bytes.
20     SQLITE_LIMIT_SQL_LENGTH = ffi::SQLITE_LIMIT_SQL_LENGTH,
21     /// The maximum number of columns in a table definition or in the result set
22     /// of a SELECT or the maximum number of columns in an index or in an
23     /// ORDER BY or GROUP BY clause.
24     SQLITE_LIMIT_COLUMN = ffi::SQLITE_LIMIT_COLUMN,
25     /// The maximum depth of the parse tree on any expression.
26     SQLITE_LIMIT_EXPR_DEPTH = ffi::SQLITE_LIMIT_EXPR_DEPTH,
27     /// The maximum number of terms in a compound SELECT statement.
28     SQLITE_LIMIT_COMPOUND_SELECT = ffi::SQLITE_LIMIT_COMPOUND_SELECT,
29     /// The maximum number of instructions in a virtual machine program used to
30     /// implement an SQL statement.
31     SQLITE_LIMIT_VDBE_OP = ffi::SQLITE_LIMIT_VDBE_OP,
32     /// The maximum number of arguments on a function.
33     SQLITE_LIMIT_FUNCTION_ARG = ffi::SQLITE_LIMIT_FUNCTION_ARG,
34     /// The maximum number of attached databases.
35     SQLITE_LIMIT_ATTACHED = ffi::SQLITE_LIMIT_ATTACHED,
36     /// The maximum length of the pattern argument to the LIKE or GLOB
37     /// operators.
38     SQLITE_LIMIT_LIKE_PATTERN_LENGTH = ffi::SQLITE_LIMIT_LIKE_PATTERN_LENGTH,
39     /// The maximum index number of any parameter in an SQL statement.
40     SQLITE_LIMIT_VARIABLE_NUMBER = ffi::SQLITE_LIMIT_VARIABLE_NUMBER,
41     /// The maximum depth of recursion for triggers.
42     SQLITE_LIMIT_TRIGGER_DEPTH = 10,
43     /// The maximum number of auxiliary worker threads that a single prepared
44     /// statement may start.
45     SQLITE_LIMIT_WORKER_THREADS = 11,
46 }
47 
48 impl Connection {
49     /// Returns the current value of a [`Limit`].
50     #[inline]
51     #[cfg_attr(docsrs, doc(cfg(feature = "limits")))]
limit(&self, limit: Limit) -> i3252     pub fn limit(&self, limit: Limit) -> i32 {
53         let c = self.db.borrow();
54         unsafe { ffi::sqlite3_limit(c.db(), limit as c_int, -1) }
55     }
56 
57     /// Changes the [`Limit`] to `new_val`, returning the prior
58     /// value of the limit.
59     #[inline]
60     #[cfg_attr(docsrs, doc(cfg(feature = "limits")))]
set_limit(&self, limit: Limit, new_val: i32) -> i3261     pub fn set_limit(&self, limit: Limit, new_val: i32) -> i32 {
62         let c = self.db.borrow_mut();
63         unsafe { ffi::sqlite3_limit(c.db(), limit as c_int, new_val) }
64     }
65 }
66 
67 #[cfg(test)]
68 mod test {
69     use super::*;
70     use crate::{Connection, Result};
71 
72     #[test]
test_limit_values()73     fn test_limit_values() {
74         assert_eq!(
75             Limit::SQLITE_LIMIT_LENGTH as i32,
76             ffi::SQLITE_LIMIT_LENGTH as i32,
77         );
78         assert_eq!(
79             Limit::SQLITE_LIMIT_SQL_LENGTH as i32,
80             ffi::SQLITE_LIMIT_SQL_LENGTH as i32,
81         );
82         assert_eq!(
83             Limit::SQLITE_LIMIT_COLUMN as i32,
84             ffi::SQLITE_LIMIT_COLUMN as i32,
85         );
86         assert_eq!(
87             Limit::SQLITE_LIMIT_EXPR_DEPTH as i32,
88             ffi::SQLITE_LIMIT_EXPR_DEPTH as i32,
89         );
90         assert_eq!(
91             Limit::SQLITE_LIMIT_COMPOUND_SELECT as i32,
92             ffi::SQLITE_LIMIT_COMPOUND_SELECT as i32,
93         );
94         assert_eq!(
95             Limit::SQLITE_LIMIT_VDBE_OP as i32,
96             ffi::SQLITE_LIMIT_VDBE_OP as i32,
97         );
98         assert_eq!(
99             Limit::SQLITE_LIMIT_FUNCTION_ARG as i32,
100             ffi::SQLITE_LIMIT_FUNCTION_ARG as i32,
101         );
102         assert_eq!(
103             Limit::SQLITE_LIMIT_ATTACHED as i32,
104             ffi::SQLITE_LIMIT_ATTACHED as i32,
105         );
106         assert_eq!(
107             Limit::SQLITE_LIMIT_LIKE_PATTERN_LENGTH as i32,
108             ffi::SQLITE_LIMIT_LIKE_PATTERN_LENGTH as i32,
109         );
110         assert_eq!(
111             Limit::SQLITE_LIMIT_VARIABLE_NUMBER as i32,
112             ffi::SQLITE_LIMIT_VARIABLE_NUMBER as i32,
113         );
114         #[cfg(feature = "bundled")]
115         assert_eq!(
116             Limit::SQLITE_LIMIT_TRIGGER_DEPTH as i32,
117             ffi::SQLITE_LIMIT_TRIGGER_DEPTH as i32,
118         );
119         #[cfg(feature = "bundled")]
120         assert_eq!(
121             Limit::SQLITE_LIMIT_WORKER_THREADS as i32,
122             ffi::SQLITE_LIMIT_WORKER_THREADS as i32,
123         );
124     }
125 
126     #[test]
test_limit() -> Result<()>127     fn test_limit() -> Result<()> {
128         let db = Connection::open_in_memory()?;
129         db.set_limit(Limit::SQLITE_LIMIT_LENGTH, 1024);
130         assert_eq!(1024, db.limit(Limit::SQLITE_LIMIT_LENGTH));
131 
132         db.set_limit(Limit::SQLITE_LIMIT_SQL_LENGTH, 1024);
133         assert_eq!(1024, db.limit(Limit::SQLITE_LIMIT_SQL_LENGTH));
134 
135         db.set_limit(Limit::SQLITE_LIMIT_COLUMN, 64);
136         assert_eq!(64, db.limit(Limit::SQLITE_LIMIT_COLUMN));
137 
138         db.set_limit(Limit::SQLITE_LIMIT_EXPR_DEPTH, 256);
139         assert_eq!(256, db.limit(Limit::SQLITE_LIMIT_EXPR_DEPTH));
140 
141         db.set_limit(Limit::SQLITE_LIMIT_COMPOUND_SELECT, 32);
142         assert_eq!(32, db.limit(Limit::SQLITE_LIMIT_COMPOUND_SELECT));
143 
144         db.set_limit(Limit::SQLITE_LIMIT_FUNCTION_ARG, 32);
145         assert_eq!(32, db.limit(Limit::SQLITE_LIMIT_FUNCTION_ARG));
146 
147         db.set_limit(Limit::SQLITE_LIMIT_ATTACHED, 2);
148         assert_eq!(2, db.limit(Limit::SQLITE_LIMIT_ATTACHED));
149 
150         db.set_limit(Limit::SQLITE_LIMIT_LIKE_PATTERN_LENGTH, 128);
151         assert_eq!(128, db.limit(Limit::SQLITE_LIMIT_LIKE_PATTERN_LENGTH));
152 
153         db.set_limit(Limit::SQLITE_LIMIT_VARIABLE_NUMBER, 99);
154         assert_eq!(99, db.limit(Limit::SQLITE_LIMIT_VARIABLE_NUMBER));
155 
156         // SQLITE_LIMIT_TRIGGER_DEPTH was added in SQLite 3.6.18.
157         if crate::version_number() >= 3_006_018 {
158             db.set_limit(Limit::SQLITE_LIMIT_TRIGGER_DEPTH, 32);
159             assert_eq!(32, db.limit(Limit::SQLITE_LIMIT_TRIGGER_DEPTH));
160         }
161 
162         // SQLITE_LIMIT_WORKER_THREADS was added in SQLite 3.8.7.
163         if crate::version_number() >= 3_008_007 {
164             db.set_limit(Limit::SQLITE_LIMIT_WORKER_THREADS, 2);
165             assert_eq!(2, db.limit(Limit::SQLITE_LIMIT_WORKER_THREADS));
166         }
167         Ok(())
168     }
169 }
170