cqlc_core/ir.rs
1//! The typed intermediate representation consumed by code generators.
2//!
3//! Every query is fully resolved: bind parameters and result columns have
4//! types and nullability, and names are unique.
5
6use crate::schema::Udt;
7use crate::span::Span;
8use crate::types::{CqlType, QueryKind, RelOp};
9
10/// The kind of CQL statement a query runs.
11#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12#[non_exhaustive]
13pub enum StatementKind {
14 /// `SELECT`
15 Select,
16 /// `INSERT`
17 Insert,
18 /// `UPDATE`
19 Update,
20 /// `DELETE`
21 Delete,
22}
23
24/// Where a bind parameter comes from.
25#[derive(Clone, Debug, PartialEq, Eq)]
26#[non_exhaustive]
27pub enum ParamSource {
28 /// Compared in a `WHERE` clause. `column` is `token` for token relations.
29 Restriction {
30 /// The restricted column.
31 column: String,
32 /// The comparison operator.
33 op: RelOp,
34 },
35 /// Compared in an `IF` condition.
36 Condition {
37 /// The tested column.
38 column: String,
39 /// The comparison operator.
40 op: RelOp,
41 },
42 /// Value written to a column (`VALUES` / `SET`).
43 Assignment {
44 /// The written column.
45 column: String,
46 },
47 /// Map key or list index of an element update, delete or restriction.
48 ElementKey {
49 /// The collection column.
50 column: String,
51 },
52 /// Value of an element update (`col[?] = value`).
53 ElementValue {
54 /// The collection column.
55 column: String,
56 },
57 /// `INSERT ... JSON ?`
58 Json,
59 /// Marker inside a selection expression.
60 Expression,
61 /// `LIMIT ?`
62 Limit,
63 /// `PER PARTITION LIMIT ?`
64 PerPartitionLimit,
65 /// `USING TTL ?`
66 Ttl,
67 /// `USING TIMESTAMP ?`
68 Timestamp,
69}
70
71/// One bind parameter of a query.
72#[derive(Clone, Debug, PartialEq)]
73#[non_exhaustive]
74pub struct Param {
75 /// Unique within the query; derived from the column (or `limit`, `ttl`,
76 /// `timestamp`, ...).
77 pub name: String,
78 /// The type the driver must bind.
79 pub cql_type: CqlType,
80 /// Whether the caller may pass NULL for this value. This concerns bind
81 /// values only and is independent of result nullability.
82 pub nullable: bool,
83 /// What the marker stands for.
84 pub source: ParamSource,
85 /// Position of the `?` in the source.
86 pub span: Span,
87}
88
89/// One column of a result row.
90#[derive(Clone, Debug, PartialEq)]
91#[non_exhaustive]
92pub struct ResultColumn {
93 /// Alias if given, otherwise the column name. `[json]` for `SELECT JSON`.
94 pub name: String,
95 /// The column type.
96 pub cql_type: CqlType,
97 /// Whether the database cell may be absent.
98 pub nullable: bool,
99}
100
101/// A fully analyzed query.
102#[derive(Clone, Debug, PartialEq)]
103#[non_exhaustive]
104pub struct Query {
105 /// Name exactly as written in the annotation.
106 pub name: String,
107 /// How the result is exposed.
108 pub kind: QueryKind,
109 /// The statement type.
110 pub statement: StatementKind,
111 /// Whitespace-normalized CQL text without comments or the trailing `;`.
112 pub cql: String,
113 /// Keyspace of the table, if the schema qualified it.
114 pub keyspace: Option<String>,
115 /// The table the query runs against.
116 pub table: String,
117 /// In bind-marker order.
118 pub params: Vec<Param>,
119 /// Result columns of a `SELECT`. For [`QueryKind::Lwt`] these are the
120 /// columns the database reports back when the write was *not* applied;
121 /// all of them are nullable.
122 pub columns: Vec<ResultColumn>,
123 /// For [`QueryKind::Lwt`]: every column of the table. Some servers (e.g.
124 /// ScyllaDB) report the whole row for a failed conditional write, others
125 /// only the tested columns. Empty for other queries.
126 pub row_columns: Vec<ResultColumn>,
127 /// The whole statement in the source.
128 pub span: Span,
129}
130
131/// The result of analyzing all queries.
132#[derive(Clone, Debug, Default, PartialEq)]
133#[non_exhaustive]
134pub struct Ir {
135 /// Queries without errors, in source order.
136 pub queries: Vec<Query>,
137 /// All user-defined types of the schema.
138 pub udts: Vec<Udt>,
139}