Skip to content
This repository was archived by the owner on Oct 18, 2023. It is now read-only.

Commit 6963ef6

Browse files
bors[bot]psarna
andauthored
Merge #363
363: query_analysis: qualify pragmas for reads/writes r=MarinPostma a=psarna This commit changes the way PRAGMA statements are qualified: instead of treating all of them as writes, read-only pragmas are qualified as reads, so that they are available for connections that authenticated with a read-only token. Co-authored-by: Piotr Sarna <[email protected]>
2 parents 2c39268 + 5a14fea commit 6963ef6

File tree

1 file changed

+64
-66
lines changed

1 file changed

+64
-66
lines changed

sqld/src/query_analysis.rs

Lines changed: 64 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -62,77 +62,75 @@ impl StmtKind {
6262
| Stmt::CreateIndex { .. },
6363
) => Some(Self::Write),
6464
Cmd::Stmt(Stmt::Select { .. }) => Some(Self::Read),
65-
Cmd::Stmt(Stmt::Pragma(name, body)) => {
66-
if is_pragma_allowed(name, body.as_ref()) {
67-
Some(Self::Write)
68-
} else {
69-
None
70-
}
71-
}
65+
Cmd::Stmt(Stmt::Pragma(name, body)) => Self::pragma_kind(name, body.as_ref()),
7266
_ => None,
7367
}
7468
}
75-
}
7669

77-
fn is_pragma_allowed(name: &QualifiedName, body: Option<&PragmaBody>) -> bool {
78-
let name = name.name.0.as_str();
79-
match name {
80-
// always ok
81-
"foreign_key" | "foreign_key_list" | "foreign_key_check" | "collation_list"
82-
| "compile_options" | "data_version" | "database_list" | "freelist_count"
83-
| "function_list" | "index_list" | "index_xinfo" | "integrity_check"
84-
| "legacy_file_format" | "page_count" | "pragma_list" | "quick_check" | "stats" | "table_info" | "table_list" | "table_xinfo" => true,
85-
// ok without args
86-
"analysis_limit"
87-
| "application_id"
88-
| "auto_vacuum"
89-
| "automatic_index"
90-
| "busy_timeout"
91-
| "cache_size"
92-
| "cache_spill"
93-
| "cell_size_check"
94-
| "checkpoint_fullfsync"
95-
| "defer_foreign_keys"
96-
| "encoding"
97-
| "fullfsync"
98-
| "hard_heap_limit"
99-
| "journal_mode"
100-
| "journal_size_limit"
101-
| "legacy_alter_table"
102-
| "locking_mode"
103-
| "max_page_count"
104-
| "mmap_size"
105-
| "page_size"
106-
| "query_only"
107-
| "read_uncommitted"
108-
| "recursive_triggers"
109-
| "reverse_unordered_selects"
110-
| "schema_version"
111-
| "secure_delete"
112-
| "soft_heap_limit"
113-
| "synchronous"
114-
| "temp_store"
115-
| "threads"
116-
| "trusted_schema"
117-
| "user_version"
118-
| "wal_autocheckpoint"
119-
120-
if body.is_none() =>
121-
{
122-
true
123-
}
124-
// changes the state of the connection, and can't be allowed rn:
125-
"case_sensitive_like" | "ignore_check_constraints" | "incremental_vacuum"
126-
// TODO: check if optimize can be safely performed
127-
| "optimize"
128-
| "parser_trace"
129-
| "shrink_memory"
130-
| "wal_checkpoint"
131-
132-
=> {
133-
false
70+
fn pragma_kind(name: &QualifiedName, body: Option<&PragmaBody>) -> Option<Self> {
71+
let name = name.name.0.as_str();
72+
match name {
73+
// always ok to be served by primary or replicas - pure readonly pragmas
74+
"table_list" | "index_list" | "table_info" | "table_xinfo" | "index_xinfo"
75+
| "pragma_list" | "compile_options" | "database_list" | "function_list"
76+
| "module_list" => Some(Self::Read),
77+
// special case for `encoding` - it's effectively readonly for connections
78+
// that already created a database, which is always the case for sqld
79+
"encoding" => Some(Self::Read),
80+
// always ok to be served by primary
81+
"foreign_key" | "foreign_key_list" | "foreign_key_check" | "collation_list"
82+
| "data_version" | "freelist_count" | "integrity_check" | "legacy_file_format"
83+
| "page_count" | "quick_check" | "stats" => Some(Self::Write),
84+
// ok to be served by primary without args
85+
"analysis_limit"
86+
| "application_id"
87+
| "auto_vacuum"
88+
| "automatic_index"
89+
| "busy_timeout"
90+
| "cache_size"
91+
| "cache_spill"
92+
| "cell_size_check"
93+
| "checkpoint_fullfsync"
94+
| "defer_foreign_keys"
95+
| "fullfsync"
96+
| "hard_heap_limit"
97+
| "journal_mode"
98+
| "journal_size_limit"
99+
| "legacy_alter_table"
100+
| "locking_mode"
101+
| "max_page_count"
102+
| "mmap_size"
103+
| "page_size"
104+
| "query_only"
105+
| "read_uncommitted"
106+
| "recursive_triggers"
107+
| "reverse_unordered_selects"
108+
| "schema_version"
109+
| "secure_delete"
110+
| "soft_heap_limit"
111+
| "synchronous"
112+
| "temp_store"
113+
| "threads"
114+
| "trusted_schema"
115+
| "user_version"
116+
| "wal_autocheckpoint" => {
117+
match body {
118+
Some(_) => None,
119+
None => Some(Self::Write),
120+
}
121+
}
122+
// changes the state of the connection, and can't be allowed rn:
123+
"case_sensitive_like" | "ignore_check_constraints" | "incremental_vacuum"
124+
// TODO: check if optimize can be safely performed
125+
| "optimize"
126+
| "parser_trace"
127+
| "shrink_memory"
128+
| "wal_checkpoint" => None,
129+
_ => {
130+
tracing::debug!("Unknown pragma: {name}");
131+
None
132+
},
134133
}
135-
_ => false,
136134
}
137135
}
138136

0 commit comments

Comments
 (0)