qql_core/ast/statement/ddl.rs
1//! Typed AST for DDL statements and collection configuration.
2
3use super::types::*;
4use crate::ast::Value;
5use alloc::string::String;
6use alloc::vec::Vec;
7
8/// `WITH MULTIVECTOR (…)` settings on a vector definition.
9#[derive(Debug, Clone, PartialEq)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct MultivectorConfig {
12 /// Scoring comparator (currently `max_sim`).
13 pub comparator: MultivectorComparator,
14}
15
16/// One named dense vector definition of `CREATE COLLECTION`.
17#[derive(Debug, Clone, PartialEq)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19pub struct VectorDef {
20 /// Vector name.
21 pub name: String,
22 /// Vector dimension.
23 pub size: u64,
24 /// Distance metric.
25 pub distance: VectorDistance,
26 /// Per-vector `WITH HNSW` overrides.
27 pub hnsw: Option<Box<HnswRuntimeConfig>>,
28 /// Per-vector `WITH QUANTIZATION` settings.
29 pub quantization: Option<Box<QuantizationConfig>>,
30 /// `WITH MULTIVECTOR` settings for late-interaction vectors.
31 pub multivector: Option<MultivectorConfig>,
32 /// `WITH VECTOR` storage settings (memory placement, datatype).
33 pub vectors: Option<Box<VectorsConfig>>,
34}
35
36/// `WITH SPARSE (…)` index settings for a sparse vector definition.
37#[derive(Debug, Clone, PartialEq)]
38#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
39pub struct SparseIndexConfig {
40 /// Vector count below which full scans are used.
41 pub full_scan_threshold: Option<u64>,
42 /// Legacy flag storing the index on disk (prefer `memory`).
43 pub on_disk: Option<bool>,
44 /// Storage datatype (`float32` / `float16` / `uint8`). Turbo4 is rejected.
45 pub datatype: Option<VectorDatatype>,
46 /// Memory placement of the index.
47 pub memory: Option<MemoryPlacement>,
48}
49
50/// One named sparse vector definition of `CREATE COLLECTION`.
51#[derive(Debug, Clone, PartialEq)]
52#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
53pub struct SparseVectorDef {
54 /// Sparse vector name.
55 pub name: String,
56 /// Optional `WITH SPARSE` index settings.
57 pub index: Option<Box<SparseIndexConfig>>,
58 /// Optional index modifier, e.g. `idf`.
59 pub modifier: Option<String>,
60}
61
62/// `WITH QUANTIZATION (…)` settings for a vector definition.
63#[derive(Debug, Clone, PartialEq)]
64#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
65pub struct QuantizationConfig {
66 /// Quantization family.
67 pub qtype: QuantizationType,
68 /// Legacy flag keeping quantized vectors in RAM (prefer `memory`).
69 pub always_ram: bool,
70 /// Scalar quantization quantile in `[0, 1]`.
71 pub quantile: Option<f64>,
72 /// Bits per dimension (Turbo accepts 1, 1.5, 2, or 4).
73 pub bits: Option<f64>,
74 /// Product quantization compression (`x4`–`x64`).
75 pub compression: Option<String>,
76 /// Binary quantization encoding (`one_bit`, `two_bits`, `one_and_half_bits`).
77 pub encoding: Option<String>,
78 /// Binary query encoding (`default`, `binary`, `scalar4bits`, `scalar8bits`).
79 pub query_encoding: Option<String>,
80 /// Memory placement of quantized vectors.
81 pub memory: Option<MemoryPlacement>,
82}
83
84/// `WITH QUANTIZATION` replacement emitted by `ALTER COLLECTION`.
85#[derive(Debug, Clone, PartialEq)]
86#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
87pub struct QuantizationUpdate {
88 /// `disabled = true` — drop the collection's quantization config.
89 pub disabled: bool,
90 /// Replacement quantization settings; `None` only when disabled.
91 pub config: Option<Box<QuantizationConfig>>,
92}
93
94/// Per-vector dense diff emitted by `ALTER COLLECTION … WITH VECTOR <name> (…)`.
95///
96/// Mirrors the OpenAPI/gRPC `VectorParamsDiff`: only `hnsw_config`,
97/// `quantization_config`, `on_disk`, and `memory` can be changed after create.
98/// `datatype` has no diff field on the wire and fails planning.
99#[derive(Debug, Clone, PartialEq)]
100#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
101pub struct VectorDiff {
102 /// Vector name; the empty string addresses the default unnamed vector.
103 pub name: String,
104 /// Replacement HNSW diff (field-wise).
105 pub hnsw: Option<Box<HnswRuntimeConfig>>,
106 /// Replacement quantization settings or `disabled = true`.
107 pub quantization: Option<Box<QuantizationUpdate>>,
108 /// Storage diff (`on_disk` / `memory`); `datatype` is rejected at planning.
109 pub vectors: Option<Box<VectorsConfig>>,
110}
111
112/// Per-vector sparse diff emitted by `ALTER COLLECTION … WITH SPARSE <name> (…)`.
113///
114/// Mirrors OpenAPI `SparseVectorParams` as a diff: `modifier` and the sparse
115/// `index` settings are each optional.
116#[derive(Debug, Clone, PartialEq)]
117#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
118pub struct SparseVectorDiff {
119 /// Sparse vector name.
120 pub name: String,
121 /// Replacement sparse index settings (field-wise).
122 pub index: Option<Box<SparseIndexConfig>>,
123 /// Replacement index modifier (`none` / `idf`).
124 pub modifier: Option<String>,
125}
126
127/// `WITH HNSW (…)` graph settings (collection- or vector-scoped).
128#[derive(Debug, Clone, PartialEq)]
129#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
130pub struct HnswRuntimeConfig {
131 /// Number of edges per node in the HNSW graph.
132 pub m: Option<u64>,
133 /// Size of the candidate list used while building the graph.
134 pub ef_construct: Option<u64>,
135 /// Vector count below which full scans are used.
136 pub full_scan_threshold: Option<u64>,
137 /// Parallel indexing thread cap (`0` = automatic).
138 pub max_indexing_threads: Option<u64>,
139 /// Legacy flag storing the graph on disk (prefer `memory`).
140 pub on_disk: Option<bool>,
141 /// Extra graph edges for payload-aware links.
142 pub payload_m: Option<u64>,
143 /// Inline-storage flag for the HNSW graph.
144 pub inline_storage: Option<bool>,
145 /// Memory placement of the HNSW graph.
146 pub memory: Option<MemoryPlacement>,
147}
148
149/// `WITH VECTOR (…)` storage settings.
150#[derive(Debug, Clone, PartialEq)]
151#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
152pub struct VectorsConfig {
153 /// Legacy flag storing original vectors on disk (prefer `memory`).
154 pub on_disk: Option<bool>,
155 /// Memory placement of the original vector storage.
156 pub memory: Option<MemoryPlacement>,
157 /// Storage datatype for dense vectors.
158 pub datatype: Option<VectorDatatype>,
159}
160
161/// `max_optimization_threads` value with `auto` support.
162#[derive(Debug, Clone, Copy, PartialEq)]
163#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
164pub struct OptimizationThreads {
165 /// `auto` — let the server choose the thread count.
166 pub auto_: bool,
167 /// Explicit thread count used when `auto_` is false.
168 pub value: u64,
169}
170
171/// `WITH OPTIMIZERS (…)` background segment and optimizer settings.
172#[derive(Debug, Clone, PartialEq)]
173#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
174pub struct OptimizersRuntimeConfig {
175 /// Deleted-record ratio (`0.0..=1.0`) that triggers a segment rebuild.
176 pub deleted_threshold: Option<f64>,
177 /// Minimum vector count before a segment is optimized.
178 pub vacuum_min_vector_number: Option<u64>,
179 /// Target number of segments.
180 pub default_segment_number: Option<u64>,
181 /// Maximum segment size, in kilobytes.
182 pub max_segment_size: Option<u64>,
183 /// Vector count above which a segment switches to memmap storage.
184 pub memmap_threshold: Option<u64>,
185 /// Vector count below which a segment is not HNSW-indexed.
186 pub indexing_threshold: Option<u64>,
187 /// Seconds between automatic storage flushes.
188 pub flush_interval_sec: Option<u64>,
189 /// Optimization thread budget (explicit or `auto`).
190 pub max_optimization_threads: Option<OptimizationThreads>,
191 /// Suspend background optimization while set.
192 pub prevent_unoptimized: Option<bool>,
193}
194
195/// `WITH PARAMS (…)` collection-level cluster and storage parameters.
196#[derive(Debug, Clone, PartialEq)]
197#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
198pub struct CollectionParamsConfig {
199 /// Number of replicas per shard.
200 pub replication_factor: Option<u64>,
201 /// Minimum replicas that must acknowledge a write.
202 pub write_consistency_factor: Option<u64>,
203 /// Number of replicas queried in parallel for reads.
204 pub read_fan_out_factor: Option<u64>,
205 /// Delay between read fan-out attempts, in milliseconds.
206 pub read_fan_out_delay_ms: Option<u64>,
207 /// Legacy flag storing payload on disk (prefer `payload_memory`).
208 pub on_disk_payload: Option<bool>,
209 /// Memory placement of the payload storage (`Cold` / `Cached` only; never `Pinned`).
210 pub payload_memory: Option<MemoryPlacement>,
211 /// Total number of shards.
212 pub shard_number: Option<u64>,
213 /// Shard placement method: `auto` or `custom`.
214 pub sharding_method: Option<String>,
215 /// Tenant keys enabled for custom sharding.
216 pub shard_keys: Option<Vec<super::ShardKey>>,
217}
218
219/// Full `WITH`-clause configuration of a collection.
220#[derive(Debug, Clone, PartialEq)]
221#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
222pub struct CollectionConfig {
223 /// Default dense vector storage settings.
224 pub vectors: Option<Box<VectorsConfig>>,
225 /// Collection-wide HNSW settings.
226 pub hnsw: Option<Box<HnswRuntimeConfig>>,
227 /// Collection-wide optimizer settings.
228 pub optimizers: Option<Box<OptimizersRuntimeConfig>>,
229 /// Cluster and storage parameters.
230 pub params: Option<Box<CollectionParamsConfig>>,
231 /// Collection-wide quantization settings.
232 pub quantization: Option<Box<QuantizationConfig>>,
233 /// Quantization replacement emitted by `ALTER COLLECTION`.
234 pub quantization_update: Option<Box<QuantizationUpdate>>,
235 /// Write-ahead log settings (`WITH WAL (…)`); raw pairs, validated by plan.
236 pub wal: Option<Vec<(String, Value)>>,
237 /// Strict-mode settings (`WITH STRICT_MODE (…)`); raw pairs, validated by plan.
238 pub strict_mode: Option<Vec<(String, Value)>>,
239 /// Collection metadata (`WITH METADATA (…)`); raw pairs, serialized as a map.
240 pub metadata: Option<Vec<(String, Value)>>,
241 /// Per-vector dense diffs emitted by `ALTER COLLECTION … WITH VECTOR <name>`.
242 pub vector_diffs: Vec<VectorDiff>,
243 /// Per-sparse-vector diffs emitted by `ALTER COLLECTION … WITH SPARSE <name>`.
244 pub sparse_vector_diffs: Vec<SparseVectorDiff>,
245}
246
247/// `CREATE COLLECTION` topology mode.
248#[derive(Debug, Clone, PartialEq)]
249#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
250pub enum CollectionMode {
251 /// `USING [DENSE] MODEL '…'` — single dense vector sized by the model.
252 Dense {
253 /// Model whose embedding dimension defines the vector.
254 model: Option<String>,
255 },
256 /// `HYBRID` / `USING HYBRID` — dense + sparse topology.
257 Hybrid {
258 /// Name assigned to the dense role vector.
259 dense_vector: Option<String>,
260 /// Name assigned to the sparse role vector.
261 sparse_vector: Option<String>,
262 },
263 /// `HYBRID RERANK` — dense + sparse + `colbert` multivector topology.
264 Rerank,
265}
266
267/// `CREATE COLLECTION <name>` statement.
268#[derive(Debug, Clone, PartialEq)]
269#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
270pub struct CreateCollectionStmt {
271 /// Name of the collection to create.
272 pub collection: String,
273 /// Topology mode (model, hybrid, or rerank).
274 pub mode: CollectionMode,
275 /// Named dense vector definitions.
276 pub vectors: Vec<VectorDef>,
277 /// Named sparse vector definitions.
278 pub sparse_vectors: Vec<SparseVectorDef>,
279 /// `WITH` config blocks (HNSW, PARAMS, OPTIMIZERS, QUANTIZATION, VECTOR).
280 pub config: Option<Box<CollectionConfig>>,
281}
282
283/// `ALTER COLLECTION <name>` statement.
284#[derive(Debug, Clone, PartialEq)]
285#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
286pub struct AlterCollectionStmt {
287 /// Collection to alter.
288 pub collection: String,
289 /// Replacement `WITH` config blocks.
290 pub config: Option<Box<CollectionConfig>>,
291}
292
293/// `DROP COLLECTION <name>` statement.
294#[derive(Debug, Clone, PartialEq)]
295#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
296pub struct DropCollectionStmt {
297 /// Collection to drop.
298 pub collection: String,
299}
300
301/// `CREATE INDEX ON COLLECTION <c> FOR <field> [TYPE t] [WITH (…)]`.
302#[derive(Debug, Clone, PartialEq)]
303#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
304pub struct CreateIndexStmt {
305 /// Collection to index.
306 pub collection: String,
307 /// Payload field to index.
308 pub field: String,
309 /// Index type (keyword, integer, float, geo, text, bool, datetime, uuid).
310 pub field_type: String,
311 /// `WITH (…)` index options (e.g. `is_tenant`, `prefix`).
312 pub options: Vec<(String, Value)>,
313 /// Optional index creation durability confirmation (`WAIT true` / `WAIT false`).
314 pub wait: Option<bool>,
315}
316
317/// `DROP INDEX ON COLLECTION <c> FOR <field>` statement.
318#[derive(Debug, Clone, PartialEq)]
319#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
320pub struct DropIndexStmt {
321 /// Collection to update.
322 pub collection: String,
323 /// Indexed field to drop.
324 pub field: String,
325}
326
327/// `CREATE SHARD KEY '<key>' ON COLLECTION <c> [WITH (…)]`.
328#[derive(Debug, Clone, PartialEq)]
329#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
330pub struct CreateShardKeyStmt {
331 /// Collection to partition.
332 pub collection: String,
333 /// Shard key value to register (`'acme'` or `101`).
334 pub shard_key: super::ShardKey,
335 /// Number of shards behind this key.
336 pub shards_number: Option<u64>,
337 /// Replication factor for these shards.
338 pub replication_factor: Option<u64>,
339 /// Peer ids placing the key's shards (`placement = […]`).
340 pub placement: Option<Vec<u64>>,
341 /// Initial replica state (`initial_state = '…'`), canonical casing.
342 pub initial_state: Option<String>,
343}
344
345/// `DROP SHARD KEY '<key>' ON COLLECTION <c>`.
346#[derive(Debug, Clone, PartialEq)]
347#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
348pub struct DropShardKeyStmt {
349 /// Collection to update.
350 pub collection: String,
351 /// Shard key value to remove.
352 pub shard_key: super::ShardKey,
353}
354
355/// Global quota configuration statement (`SET QUOTA (…) [WAIT bool]`).
356///
357/// `config` keeps the raw `key = value` pairs (enabled,
358/// max_resident_memory_percent, max_disk_usage_percent,
359/// release_margin_percent); the plan layer validates and serializes them.
360#[derive(Debug, Clone, PartialEq)]
361#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
362pub struct SetQuotaStmt {
363 /// Raw `key = value` quota settings; validated and serialized by the planner.
364 pub config: Vec<(String, Value)>,
365 /// `WAIT` — block until the new limits take effect.
366 pub wait: Option<bool>,
367}