1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//! The four statement types, each shaped by SQLite's own syntax diagrams.
//!
//! Every one composes the shared clause structs as named fields, in the order
//! <https://www.sqlite.org/lang.html> lists them, and implements the `Has*` traits
//! for the clauses it actually has. *Not* implementing one is how "this statement
//! has no such clause" is said: `select::having(..)` will not compile against an
//! `UpdateQuery`.
//!
//! # Which table a mod means
//!
//! | statement | [`HasTableRef`](keelson_core::clause::HasTableRef) | [`HasTargetTable`] | [`HasExtraTables`] |
//! |---|---|---|---|
//! | `SELECT` | `FROM` item | — | further `FROM` items |
//! | `INSERT` | `INTO` target | — | — |
//! | `UPDATE` | `FROM` item | the updated table | further `FROM` items |
//! | `DELETE` | — | the deleted-from table | — |
//!
//! A `DELETE` has one table and nothing else: SQLite has no `USING`, so
//! `HasTableRef` and `HasExtraTables` are deliberately unimplemented for it and
//! there is no `delete::using` to import.
//!
//! # What SQLite does not have, and so is not here
//!
//! - **No locking clause.** SQLite locks whole database files, so there is no
//! `FOR UPDATE`, no `SKIP LOCKED`, and no [`Locks`](keelson_core::clause::Locks).
//! - **No `FETCH … ROWS ONLY`.** `LIMIT` is the only spelling, and `OFFSET` is part
//! of the `LIMIT` production rather than a clause of its own.
//! - **No `ORDER BY`/`LIMIT` on `UPDATE` or `DELETE`.** SQLite's parser accepts
//! them, but only a build configured with `SQLITE_ENABLE_UPDATE_DELETE_LIMIT`
//! does, and the default — including the one linked into these tests — rejects
//! them outright. A mod that produced SQL an ordinary SQLite refuses would be a
//! trap, so none exists.
//! - **No `RETURNING` on `SELECT`**, and no `WHERE CURRENT OF`: SQLite has no
//! cursors.
pub use DeleteQuery;
pub use InsertQuery;
pub use SelectQuery;
pub use UpdateQuery;
use TableRef;
/// A statement whose *target* table is separate from its from-item: the table an
/// `UPDATE` writes to, or the one a `DELETE` removes from.
///
/// In SQLite both are a `qualified-table-name`
/// (<https://www.sqlite.org/syntax/qualified-table-name.html>), which is what makes
/// `INDEXED BY` available there as well as on a `FROM` item.
/// A statement whose from-item list may hold more than one entry.
///
/// SQLite's `FROM` takes either a comma-separated `table-or-subquery` list or a
/// `join-clause`, and `,` is itself one of the `join-operator`s — so the two are
/// the same thing and mixing them is legal. The first entry lives in
/// [`HasTableRef`](keelson_core::clause::HasTableRef); the rest are appended here.
/// Write `FROM` and its comma-separated list, skipping absent entries.
///
/// An entry with no table renders nothing, so it must not contribute a comma
/// either; and if the leading item is absent the whole clause goes, because
/// `FROM , "x"` is not a repair of anything.
///
/// Two things must not go with it: joins and the extra items. Joins hang off
/// the leading item, so with no item they have nowhere to attach; extra items
/// are second and later entries of a list the leading item opens, so with no
/// item there is no list to be in. Dropping either one the caller asked for
/// would build *valid* SQL that silently means something else, which no
/// grammar or engine can catch after the fact. That is recorded as
/// [`Error::Incomplete`](keelson_core::Error::Incomplete) with `missing`
/// naming the absent item.