surrealdb_core/sql/
index.rs

1use std::fmt;
2use std::fmt::{Display, Formatter};
3
4use crate::sql::ident::Ident;
5use crate::sql::scoring::Scoring;
6use crate::val::Number;
7
8#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
9#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
10pub enum Index {
11	/// (Basic) non unique
12	Idx,
13	/// Unique index
14	Uniq,
15	/// Index with Full-Text search capabilities - single writer
16	Search(SearchParams),
17	/// M-Tree index for distance-based metrics
18	MTree(MTreeParams),
19	/// HNSW index for distance based metrics
20	Hnsw(HnswParams),
21	/// Index with Full-Text search capabilities supporting multiple writers
22	FullText(FullTextParams),
23}
24
25impl From<Index> for crate::expr::index::Index {
26	fn from(v: Index) -> Self {
27		match v {
28			Index::Idx => Self::Idx,
29			Index::Uniq => Self::Uniq,
30			Index::Search(p) => Self::Search(p.into()),
31			Index::MTree(p) => Self::MTree(p.into()),
32			Index::Hnsw(p) => Self::Hnsw(p.into()),
33			Index::FullText(p) => Self::FullText(p.into()),
34		}
35	}
36}
37
38impl From<crate::expr::index::Index> for Index {
39	fn from(v: crate::expr::index::Index) -> Self {
40		match v {
41			crate::expr::index::Index::Idx => Self::Idx,
42			crate::expr::index::Index::Uniq => Self::Uniq,
43			crate::expr::index::Index::Search(p) => Self::Search(p.into()),
44			crate::expr::index::Index::MTree(p) => Self::MTree(p.into()),
45			crate::expr::index::Index::Hnsw(p) => Self::Hnsw(p.into()),
46			crate::expr::index::Index::FullText(p) => Self::FullText(p.into()),
47		}
48	}
49}
50
51#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
52#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
53pub struct SearchParams {
54	pub az: Ident,
55	pub hl: bool,
56	pub sc: Scoring,
57	pub doc_ids_order: u32,
58	pub doc_lengths_order: u32,
59	pub postings_order: u32,
60	pub terms_order: u32,
61	pub doc_ids_cache: u32,
62	pub doc_lengths_cache: u32,
63	pub postings_cache: u32,
64	pub terms_cache: u32,
65}
66
67impl From<SearchParams> for crate::expr::index::SearchParams {
68	fn from(v: SearchParams) -> Self {
69		crate::expr::index::SearchParams {
70			az: v.az.into(),
71			hl: v.hl,
72			sc: v.sc.into(),
73			doc_ids_order: v.doc_ids_order,
74			doc_lengths_order: v.doc_lengths_order,
75			postings_order: v.postings_order,
76			terms_order: v.terms_order,
77			doc_ids_cache: v.doc_ids_cache,
78			doc_lengths_cache: v.doc_lengths_cache,
79			postings_cache: v.postings_cache,
80			terms_cache: v.terms_cache,
81		}
82	}
83}
84impl From<crate::expr::index::SearchParams> for SearchParams {
85	fn from(v: crate::expr::index::SearchParams) -> Self {
86		Self {
87			az: v.az.into(),
88			hl: v.hl,
89			sc: v.sc.into(),
90			doc_ids_order: v.doc_ids_order,
91			doc_lengths_order: v.doc_lengths_order,
92			postings_order: v.postings_order,
93			terms_order: v.terms_order,
94			doc_ids_cache: v.doc_ids_cache,
95			doc_lengths_cache: v.doc_lengths_cache,
96			postings_cache: v.postings_cache,
97			terms_cache: v.terms_cache,
98		}
99	}
100}
101
102#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
103#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
104pub struct FullTextParams {
105	pub az: Ident,
106	pub hl: bool,
107	pub sc: Scoring,
108}
109
110impl From<FullTextParams> for crate::expr::index::FullTextParams {
111	fn from(v: FullTextParams) -> Self {
112		crate::expr::index::FullTextParams {
113			analyzer: v.az.into(),
114			highlight: v.hl,
115			scoring: v.sc.into(),
116		}
117	}
118}
119impl From<crate::expr::index::FullTextParams> for FullTextParams {
120	fn from(v: crate::expr::index::FullTextParams) -> Self {
121		Self {
122			az: v.analyzer.into(),
123			hl: v.highlight,
124			sc: v.scoring.into(),
125		}
126	}
127}
128
129#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
130#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
131pub struct MTreeParams {
132	pub dimension: u16,
133	pub distance: Distance,
134	pub vector_type: VectorType,
135	pub capacity: u16,
136	pub doc_ids_order: u32,
137	pub doc_ids_cache: u32,
138	pub mtree_cache: u32,
139}
140
141impl From<MTreeParams> for crate::expr::index::MTreeParams {
142	fn from(v: MTreeParams) -> Self {
143		crate::expr::index::MTreeParams {
144			dimension: v.dimension,
145			distance: v.distance.into(),
146			vector_type: v.vector_type.into(),
147			capacity: v.capacity,
148			doc_ids_order: v.doc_ids_order,
149			doc_ids_cache: v.doc_ids_cache,
150			mtree_cache: v.mtree_cache,
151		}
152	}
153}
154
155impl From<crate::expr::index::MTreeParams> for MTreeParams {
156	fn from(v: crate::expr::index::MTreeParams) -> Self {
157		Self {
158			dimension: v.dimension,
159			distance: v.distance.into(),
160			vector_type: v.vector_type.into(),
161			capacity: v.capacity,
162			doc_ids_order: v.doc_ids_order,
163			doc_ids_cache: v.doc_ids_cache,
164			mtree_cache: v.mtree_cache,
165		}
166	}
167}
168
169#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
170#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
171pub struct HnswParams {
172	pub dimension: u16,
173	pub distance: Distance,
174	pub vector_type: VectorType,
175	pub m: u8,
176	pub m0: u8,
177	pub ef_construction: u16,
178	pub extend_candidates: bool,
179	pub keep_pruned_connections: bool,
180	pub ml: Number,
181}
182
183impl From<HnswParams> for crate::expr::index::HnswParams {
184	fn from(v: HnswParams) -> Self {
185		crate::expr::index::HnswParams {
186			dimension: v.dimension,
187			distance: v.distance.into(),
188			vector_type: v.vector_type.into(),
189			m: v.m,
190			m0: v.m0,
191			ef_construction: v.ef_construction,
192			ml: v.ml,
193			extend_candidates: v.extend_candidates,
194			keep_pruned_connections: v.keep_pruned_connections,
195		}
196	}
197}
198
199impl From<crate::expr::index::HnswParams> for HnswParams {
200	fn from(v: crate::expr::index::HnswParams) -> Self {
201		Self {
202			dimension: v.dimension,
203			distance: v.distance.into(),
204			vector_type: v.vector_type.into(),
205			m: v.m,
206			m0: v.m0,
207			ef_construction: v.ef_construction,
208			ml: v.ml,
209			extend_candidates: v.extend_candidates,
210			keep_pruned_connections: v.keep_pruned_connections,
211		}
212	}
213}
214
215#[derive(Clone, Default, Debug, Eq, PartialEq, PartialOrd, Hash)]
216#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
217pub enum Distance {
218	Chebyshev,
219	Cosine,
220	#[default]
221	Euclidean,
222	Hamming,
223	Jaccard,
224	Manhattan,
225	Minkowski(Number),
226	Pearson,
227}
228
229impl Display for Distance {
230	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
231		match self {
232			Self::Chebyshev => f.write_str("CHEBYSHEV"),
233			Self::Cosine => f.write_str("COSINE"),
234			Self::Euclidean => f.write_str("EUCLIDEAN"),
235			Self::Hamming => f.write_str("HAMMING"),
236			Self::Jaccard => f.write_str("JACCARD"),
237			Self::Manhattan => f.write_str("MANHATTAN"),
238			Self::Minkowski(order) => write!(f, "MINKOWSKI {}", order),
239			Self::Pearson => f.write_str("PEARSON"),
240		}
241	}
242}
243
244impl From<Distance> for crate::expr::index::Distance {
245	fn from(v: Distance) -> Self {
246		match v {
247			Distance::Chebyshev => crate::expr::index::Distance::Chebyshev,
248			Distance::Cosine => crate::expr::index::Distance::Cosine,
249			Distance::Euclidean => crate::expr::index::Distance::Euclidean,
250			Distance::Hamming => crate::expr::index::Distance::Hamming,
251			Distance::Jaccard => crate::expr::index::Distance::Jaccard,
252			Distance::Manhattan => crate::expr::index::Distance::Manhattan,
253			Distance::Minkowski(n) => crate::expr::index::Distance::Minkowski(n),
254			Distance::Pearson => crate::expr::index::Distance::Pearson,
255		}
256	}
257}
258
259impl From<crate::expr::index::Distance> for Distance {
260	fn from(v: crate::expr::index::Distance) -> Self {
261		match v {
262			crate::expr::index::Distance::Chebyshev => Self::Chebyshev,
263			crate::expr::index::Distance::Cosine => Self::Cosine,
264			crate::expr::index::Distance::Euclidean => Self::Euclidean,
265			crate::expr::index::Distance::Hamming => Self::Hamming,
266			crate::expr::index::Distance::Jaccard => Self::Jaccard,
267			crate::expr::index::Distance::Manhattan => Self::Manhattan,
268			crate::expr::index::Distance::Minkowski(n) => Self::Minkowski(n),
269			crate::expr::index::Distance::Pearson => Self::Pearson,
270		}
271	}
272}
273
274#[derive(Clone, Copy, Default, Debug, Eq, PartialEq, PartialOrd, Hash)]
275#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
276pub enum VectorType {
277	#[default]
278	F64,
279	F32,
280	I64,
281	I32,
282	I16,
283}
284
285impl Display for VectorType {
286	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
287		match self {
288			Self::F64 => f.write_str("F64"),
289			Self::F32 => f.write_str("F32"),
290			Self::I64 => f.write_str("I64"),
291			Self::I32 => f.write_str("I32"),
292			Self::I16 => f.write_str("I16"),
293		}
294	}
295}
296
297impl Display for Index {
298	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
299		match self {
300			Self::Idx => Ok(()),
301			Self::Uniq => f.write_str("UNIQUE"),
302			Self::Search(p) => {
303				write!(
304					f,
305					"SEARCH ANALYZER {} {} DOC_IDS_ORDER {} DOC_LENGTHS_ORDER {} POSTINGS_ORDER {} TERMS_ORDER {} DOC_IDS_CACHE {} DOC_LENGTHS_CACHE {} POSTINGS_CACHE {} TERMS_CACHE {}",
306					p.az,
307					p.sc,
308					p.doc_ids_order,
309					p.doc_lengths_order,
310					p.postings_order,
311					p.terms_order,
312					p.doc_ids_cache,
313					p.doc_lengths_cache,
314					p.postings_cache,
315					p.terms_cache
316				)?;
317				if p.hl {
318					f.write_str(" HIGHLIGHTS")?
319				}
320				Ok(())
321			}
322			Self::FullText(p) => {
323				write!(f, "FULLTEXT ANALYZER {} {}", p.az, p.sc,)?;
324				if p.hl {
325					f.write_str(" HIGHLIGHTS")?
326				}
327				Ok(())
328			}
329			Self::MTree(p) => {
330				write!(
331					f,
332					"MTREE DIMENSION {} DIST {} TYPE {} CAPACITY {} DOC_IDS_ORDER {} DOC_IDS_CACHE {} MTREE_CACHE {}",
333					p.dimension,
334					p.distance,
335					p.vector_type,
336					p.capacity,
337					p.doc_ids_order,
338					p.doc_ids_cache,
339					p.mtree_cache
340				)
341			}
342			Self::Hnsw(p) => {
343				write!(
344					f,
345					"HNSW DIMENSION {} DIST {} TYPE {} EFC {} M {} M0 {} LM {}",
346					p.dimension, p.distance, p.vector_type, p.ef_construction, p.m, p.m0, p.ml
347				)?;
348				if p.extend_candidates {
349					f.write_str(" EXTEND_CANDIDATES")?
350				}
351				if p.keep_pruned_connections {
352					f.write_str(" KEEP_PRUNED_CONNECTIONS")?
353				}
354				Ok(())
355			}
356		}
357	}
358}
359
360impl From<VectorType> for crate::expr::index::VectorType {
361	fn from(v: VectorType) -> Self {
362		match v {
363			VectorType::F64 => Self::F64,
364			VectorType::F32 => Self::F32,
365			VectorType::I64 => Self::I64,
366			VectorType::I32 => Self::I32,
367			VectorType::I16 => Self::I16,
368		}
369	}
370}
371
372impl From<crate::expr::index::VectorType> for VectorType {
373	fn from(v: crate::expr::index::VectorType) -> Self {
374		match v {
375			crate::expr::index::VectorType::F64 => Self::F64,
376			crate::expr::index::VectorType::F32 => Self::F32,
377			crate::expr::index::VectorType::I64 => Self::I64,
378			crate::expr::index::VectorType::I32 => Self::I32,
379			crate::expr::index::VectorType::I16 => Self::I16,
380		}
381	}
382}