Skip to main content

surql_parser/
compat.rs

1//! Compatibility stubs for types referenced by the upstream parser code.
2//!
3//! The SurrealDB parser references several engine-internal types.
4//! This module provides minimal stubs or re-exports to satisfy compilation.
5//!
6//! These stubs are stable — they only change when SurrealDB adds new types
7//! to the parser AST, which is rare. When it happens, CI fails with
8//! "cannot find type X" and you add one line here.
9
10// ─── types (Public* aliases from surrealdb-core) ───
11
12/// Re-exports from surrealdb-types with the Public* aliases that surrealdb-core uses.
13pub mod types {
14	pub use surrealdb_types::{
15		Array as PublicArray, Bytes as PublicBytes, Datetime as PublicDatetime,
16		Duration as PublicDuration, File as PublicFile, Geometry as PublicGeometry,
17		GeometryKind as PublicGeometryKind, Kind as PublicKind, KindLiteral as PublicKindLiteral,
18		Number as PublicNumber, Object as PublicObject, Range as PublicRange,
19		RecordId as PublicRecordId, RecordIdKey as PublicRecordIdKey,
20		RecordIdKeyRange as PublicRecordIdKeyRange, Regex as PublicRegex, Set as PublicSet,
21		Table as PublicTable, Uuid as PublicUuid, Value as PublicValue,
22	};
23}
24
25// ─── val (crate::val::* paths) ───
26
27/// Re-exports from surrealdb-types matching crate::val::* paths in upstream code.
28pub mod val {
29	pub use surrealdb_types::GeometryKind;
30	pub use surrealdb_types::{
31		Array, Bytes, Datetime, Decimal, Duration, File, Geometry, Number, Object, Range, RecordId,
32		RecordIdKey, RecordIdKeyRange, Regex, Set, Table, Uuid, Value,
33	};
34
35	/// TableName newtype
36	#[derive(Debug, Clone, PartialEq, Eq, Hash)]
37	pub struct TableName(pub String);
38
39	impl TableName {
40		pub fn new(s: impl Into<String>) -> Self {
41			Self(s.into())
42		}
43	}
44
45	impl std::fmt::Display for TableName {
46		fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
47			write!(f, "{}", self.0)
48		}
49	}
50
51	/// Decimal extension trait
52	pub trait DecimalExt {
53		fn is_integer(&self) -> bool;
54	}
55
56	impl DecimalExt for Decimal {
57		fn is_integer(&self) -> bool {
58			self.fract().is_zero()
59		}
60	}
61
62	pub mod duration {
63		pub use surrealdb_types::Duration;
64		pub const SECONDS_PER_MINUTE: u64 = 60;
65		pub const SECONDS_PER_HOUR: u64 = 3600;
66		pub const SECONDS_PER_DAY: u64 = 86400;
67		pub const SECONDS_PER_WEEK: u64 = 604800;
68		pub const SECONDS_PER_YEAR: u64 = 31536000;
69	}
70
71	pub mod range {
72		pub use surrealdb_types::{Range, RecordIdKey, RecordIdKeyRange};
73
74		/// TypedRange used in mock.rs
75		#[derive(Debug, Clone, PartialEq, Eq, Hash)]
76		pub struct TypedRange<T> {
77			pub start: std::ops::Bound<T>,
78			pub end: std::ops::Bound<T>,
79		}
80
81		impl<T: PartialOrd> PartialOrd for TypedRange<T> {
82			fn partial_cmp(&self, _other: &Self) -> Option<std::cmp::Ordering> {
83				None // Range comparison not meaningful
84			}
85		}
86	}
87}
88
89// ─── catalog (schema definition types) ───
90
91/// Stubs for catalog types used in parser AST (DEFINE TABLE/INDEX/EVENT etc.)
92///
93/// These are schema-level type definitions — they rarely change.
94/// If SurrealDB adds a new variant, CI will fail and you add it here.
95pub mod catalog {
96	use serde::{Deserialize, Serialize};
97
98	#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
99	pub enum EventKind {
100		Create,
101		Update,
102		Delete,
103		Sync,
104		Async { retry: u32, max_depth: u32 },
105	}
106
107	#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
108	pub enum ApiMethod {
109		Get,
110		Post,
111		Put,
112		Patch,
113		Delete,
114		Trace,
115	}
116
117	impl surrealdb_types::ToSql for ApiMethod {
118		fn fmt_sql(&self, f: &mut String, _fmt: surrealdb_types::SqlFormat) {
119			f.push_str(match self {
120				Self::Get => "GET",
121				Self::Post => "POST",
122				Self::Put => "PUT",
123				Self::Patch => "PATCH",
124				Self::Delete => "DELETE",
125				Self::Trace => "TRACE",
126			});
127		}
128	}
129
130	#[derive(Debug, Clone, PartialEq)]
131	pub enum Permission {
132		None,
133		Full,
134		Specific(Box<crate::upstream::sql::expression::Expr>),
135	}
136
137	#[derive(Debug, Clone, PartialEq)]
138	pub struct Permissions {
139		pub select: Permission,
140		pub create: Permission,
141		pub update: Permission,
142		pub delete: Permission,
143	}
144
145	impl Default for Permissions {
146		fn default() -> Self {
147			Self {
148				select: Permission::Full,
149				create: Permission::Full,
150				update: Permission::Full,
151				delete: Permission::Full,
152			}
153		}
154	}
155
156	#[derive(Debug, Clone, PartialEq)]
157	pub enum Index {
158		Idx,
159		Uniq,
160		Count(Option<crate::upstream::sql::Cond>),
161		FullText(FullTextParams),
162		Hnsw(HnswParams),
163	}
164
165	// Conversion impls needed by upstream From<sql::Index> for catalog::Index
166	impl From<crate::upstream::sql::Cond> for crate::upstream::sql::expression::Expr {
167		fn from(c: crate::upstream::sql::Cond) -> Self {
168			c.0
169		}
170	}
171
172	impl From<crate::upstream::sql::expression::Expr> for crate::upstream::sql::Cond {
173		fn from(e: crate::upstream::sql::expression::Expr) -> Self {
174			crate::upstream::sql::Cond(e)
175		}
176	}
177
178	impl From<Box<crate::upstream::sql::expression::Expr>> for crate::upstream::sql::expression::Expr {
179		fn from(b: Box<crate::upstream::sql::expression::Expr>) -> Self {
180			*b
181		}
182	}
183
184	#[derive(Debug, Clone, PartialEq)]
185	pub struct FullTextParams {
186		pub analyzer: String,
187		pub highlight: bool,
188		pub scoring: Scoring,
189	}
190
191	#[derive(Debug, Clone, PartialEq)]
192	pub struct HnswParams {
193		pub dimension: u16,
194		pub distance: Distance,
195		pub vector_type: VectorType,
196		pub m: u8,
197		pub m0: u8,
198		pub ml: crate::compat::types::PublicNumber,
199		pub ef_construction: u16,
200		pub extend_candidates: bool,
201		pub keep_pruned_connections: bool,
202		pub use_hashed_vector: bool,
203	}
204
205	#[derive(Debug, Clone, Copy, PartialEq)]
206	pub enum Distance {
207		Chebyshev,
208		Cosine,
209		Euclidean,
210		Hamming,
211		Jaccard,
212		Manhattan,
213		Minkowski(crate::compat::types::PublicNumber),
214		Pearson,
215	}
216
217	#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
218	pub enum VectorType {
219		F32,
220		F64,
221		I16,
222		I32,
223		I64,
224	}
225
226	#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
227	pub enum Scoring {
228		Bm { k1: f32, b: f32 },
229		Vs,
230	}
231
232	#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
233	pub enum TableType {
234		Any,
235		Normal,
236		Relation(Relation),
237	}
238
239	#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
240	pub struct Relation {
241		pub from: Vec<String>,
242		pub to: Vec<String>,
243		pub enforced: bool,
244	}
245
246	#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
247	pub enum ModuleName {
248		Module(String),
249		Silo(String, String),
250	}
251
252	#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
253	pub struct GraphQLConfig {
254		pub tables: GraphQLTablesConfig,
255		pub functions: GraphQLFunctionsConfig,
256		pub introspection: GraphQLIntrospectionConfig,
257		pub depth_limit: Option<u32>,
258		pub complexity_limit: Option<u32>,
259	}
260
261	#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
262	pub enum GraphQLTablesConfig {
263		None,
264		Auto,
265		Include(Vec<String>),
266		Exclude(Vec<String>),
267	}
268
269	#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
270	pub enum GraphQLFunctionsConfig {
271		None,
272		Auto,
273		Include(Vec<String>),
274		Exclude(Vec<String>),
275	}
276
277	#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
278	pub enum GraphQLIntrospectionConfig {
279		None,
280		Auto,
281	}
282
283	/// EventDefinition used in DEFINE EVENT parsing
284	#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
285	pub struct EventDefinition {
286		pub kind: EventKind,
287	}
288
289	impl EventDefinition {
290		pub const DEFAULT_RETRY: u32 = 3;
291		pub const DEFAULT_MAX_DEPTH: u32 = 10;
292	}
293}
294
295// ─── engine stubs ───
296
297/// Minimal Capabilities stub (parser only needs feature flags).
298pub struct Capabilities {
299	files_enabled: bool,
300	surrealism_enabled: bool,
301}
302
303impl Capabilities {
304	pub fn all() -> Self {
305		Self {
306			files_enabled: true,
307			surrealism_enabled: true,
308		}
309	}
310
311	pub fn allows_experimental(&self, target: &ExperimentalTarget) -> bool {
312		match target {
313			ExperimentalTarget::Files => self.files_enabled,
314			ExperimentalTarget::Surrealism => self.surrealism_enabled,
315		}
316	}
317}
318
319pub mod capabilities {
320	pub enum ExperimentalTarget {
321		Files,
322		Surrealism,
323	}
324}
325pub use capabilities::ExperimentalTarget;
326
327/// Minimal error stub
328pub mod err {
329	#[derive(Debug, thiserror::Error)]
330	pub enum Error {
331		#[error("Query too large")]
332		QueryTooLarge,
333		#[error("Invalid query: {0}")]
334		InvalidQuery(crate::upstream::syn::error::RenderedError),
335		#[error("Access grant bearer invalid")]
336		AccessGrantBearerInvalid,
337	}
338}
339
340/// Stub for dbs types
341pub mod dbs {}
342
343/// Display impl for Param (needed because ToSql doesn't provide Display)
344impl std::fmt::Display for crate::upstream::sql::Param {
345	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
346		use surrealdb_types::{SqlFormat, ToSql};
347		let mut buf = String::new();
348		self.fmt_sql(&mut buf, SqlFormat::SingleLine);
349		f.write_str(&buf)
350	}
351}
352
353/// Free function replacement for Decimal::from_str_normalized (not in surrealdb-types 3.0.4)
354pub fn decimal_from_str_normalized(s: &str) -> Result<rust_decimal::Decimal, rust_decimal::Error> {
355	use std::str::FromStr;
356	let d = rust_decimal::Decimal::from_str(s)?;
357	Ok(d.normalize())
358}
359
360/// fmt helpers not yet in surrealdb-types 3.0 (added in 3.1)
361pub mod fmt {
362	pub const fn fmt_non_finite_f64(v: f64) -> Option<&'static str> {
363		match v {
364			f64::INFINITY => Some("Infinity"),
365			f64::NEG_INFINITY => Some("-Infinity"),
366			_ if v.is_nan() => Some("NaN"),
367			_ => None,
368		}
369	}
370}