Skip to main content

reinhardt_db/orm/
expressions.rs

1use serde::{Deserialize, Serialize};
2use std::fmt;
3use std::marker::PhantomData;
4
5use crate::orm::query::{
6	FieldAssignment, Filter, FilterOperator, FilterValue, UpdateValue, quote_identifier,
7};
8
9/// F expression - represents a database field reference
10/// Similar to Django's F() objects for database-side operations
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct F {
13	/// The field.
14	pub field: String,
15}
16
17impl F {
18	/// Create a field reference for database operations
19	///
20	/// # Examples
21	///
22	/// ```
23	/// use reinhardt_db::orm::expressions::F;
24	///
25	/// // Reference a field for comparisons or updates
26	/// let price_ref = F::new("price");
27	/// assert_eq!(price_ref.to_sql(), "\"price\"");
28	///
29	/// // Can be used in queries like: WHERE price > F("cost") + 10
30	/// ```
31	pub fn new(field: impl Into<String>) -> Self {
32		Self {
33			field: field.into(),
34		}
35	}
36	/// Generate SQL representation of the field reference
37	///
38	/// # Examples
39	///
40	/// ```
41	/// use reinhardt_db::orm::expressions::F;
42	///
43	/// let user_id = F::new("user_id");
44	/// assert_eq!(user_id.to_sql(), "\"user_id\"");
45	/// ```
46	pub fn to_sql(&self) -> String {
47		quote_identifier(&self.field)
48	}
49}
50
51impl fmt::Display for F {
52	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53		write!(f, "{}", self.field)
54	}
55}
56
57/// Type-safe field reference for database operations
58///
59/// `FieldRef<M, T>` provides compile-time type safety for field references,
60/// where `M` is the model type and `T` is the field type.
61///
62/// This type replaces Python-style `__` (double underscore) field lookup notation
63/// with Rust-idiomatic typed field accessors.
64///
65/// # Type Parameters
66///
67/// - `M`: Model type (e.g., `User`, `Post`)
68/// - `T`: Field type (e.g., `i64`, `String`)
69///
70/// # Examples
71///
72/// ```ignore
73/// use reinhardt_db::orm::expressions::FieldRef;
74/// use reinhardt_core::macros::model;
75/// use serde::{Serialize, Deserialize};
76///
77/// #[model(app_label = "users", table_name = "users")]
78/// #[derive(Serialize, Deserialize)]
79/// struct User {
80///     #[field(primary_key = true)]
81///     id: i64,
82///     #[field(max_length = 255)]
83///     name: String,
84///     #[field(max_length = 255)]
85///     email: String,
86/// }
87///
88/// // The #[model] attribute macro automatically generates:
89/// // impl User {
90/// //     pub const fn field_id() -> FieldRef<User, i64> {
91/// //         FieldRef::new("id")
92/// //     }
93/// //     pub const fn field_name() -> FieldRef<User, String> {
94/// //         FieldRef::new("name")
95/// //     }
96/// //     pub const fn field_email() -> FieldRef<User, String> {
97/// //         FieldRef::new("email")
98/// //     }
99/// // }
100///
101/// // Basic usage:
102/// let id_ref = User::field_id();
103/// assert_eq!(id_ref.name(), "id");
104/// assert_eq!(id_ref.to_sql(), "id");
105///
106/// // Convert to F expression for use in queries:
107/// use reinhardt_db::orm::expressions::F;
108/// let f: F = User::field_name().into();
109/// assert_eq!(f.to_sql(), "name");
110/// ```
111#[derive(Debug, Clone, Copy)]
112pub struct FieldRef<M, T> {
113	name: &'static str,
114	_phantom: PhantomData<(M, T)>,
115}
116
117impl<M, T> FieldRef<M, T> {
118	/// Create a new field reference with compile-time type safety
119	///
120	/// This constructor is typically used by the `#[derive(Model)]` macro
121	/// to generate field accessor methods.
122	///
123	/// # Arguments
124	///
125	/// - `name`: Field name as a static string
126	///
127	/// # Examples
128	///
129	/// ```no_run
130	/// # struct User;
131	/// use reinhardt_db::orm::expressions::FieldRef;
132	///
133	/// const USER_ID: FieldRef<User, i64> = FieldRef::new("id");
134	/// ```
135	pub const fn new(name: &'static str) -> Self {
136		Self {
137			name,
138			_phantom: PhantomData,
139		}
140	}
141
142	/// Get the field name
143	///
144	/// # Examples
145	///
146	/// ```ignore
147	/// let id_ref = User::field_id();
148	/// assert_eq!(id_ref.name(), "id");
149	/// ```
150	pub const fn name(&self) -> &'static str {
151		self.name
152	}
153
154	/// Create a partial-update assignment for this field.
155	///
156	/// # Examples
157	///
158	/// ```ignore
159	/// User::objects()
160	///     .filter(User::field_id().eq(1))
161	///     .update_fields([User::field_last_login().assign(chrono::Utc::now())])
162	///     .await?;
163	/// ```
164	pub fn assign<V: Into<UpdateValue>>(&self, value: V) -> FieldAssignment {
165		FieldAssignment::new(self.name, value)
166	}
167
168	/// Convert to SQL representation
169	///
170	/// # Examples
171	///
172	/// ```ignore
173	/// let id_ref = User::field_id();
174	/// assert_eq!(id_ref.to_sql(), "\"id\"");
175	/// ```
176	pub fn to_sql(&self) -> String {
177		quote_identifier(self.name)
178	}
179
180	/// Create an equality filter for this field
181	///
182	/// # Examples
183	///
184	/// ```ignore
185	/// let filter = User::field_id().eq(42);
186	/// // Results in: WHERE id = 42
187	/// ```
188	pub fn eq<V: Into<FilterValue>>(&self, value: V) -> Filter {
189		Filter::new(self.name.to_string(), FilterOperator::Eq, value.into())
190	}
191
192	/// Create an exact equality filter using Django lookup naming.
193	pub fn exact<V: Into<FilterValue>>(&self, value: V) -> Filter {
194		self.eq(value)
195	}
196
197	/// Create a case-insensitive exact match filter.
198	pub fn iexact<V: Into<FilterValue>>(&self, value: V) -> Filter {
199		Filter::new(self.name.to_string(), FilterOperator::IExact, value.into())
200	}
201
202	/// Create a not-equal filter for this field
203	///
204	/// # Examples
205	///
206	/// ```ignore
207	/// let filter = User::field_status().ne("inactive");
208	/// // Results in: WHERE status != 'inactive'
209	/// ```
210	pub fn ne<V: Into<FilterValue>>(&self, value: V) -> Filter {
211		Filter::new(self.name.to_string(), FilterOperator::Ne, value.into())
212	}
213
214	/// Create a greater-than filter for this field
215	///
216	/// # Examples
217	///
218	/// ```ignore
219	/// let filter = User::field_age().gt(18);
220	/// // Results in: WHERE age > 18
221	/// ```
222	pub fn gt<V: Into<FilterValue>>(&self, value: V) -> Filter {
223		Filter::new(self.name.to_string(), FilterOperator::Gt, value.into())
224	}
225
226	/// Create a greater-than-or-equal filter for this field
227	///
228	/// # Examples
229	///
230	/// ```ignore
231	/// let filter = User::field_age().gte(18);
232	/// // Results in: WHERE age >= 18
233	/// ```
234	pub fn gte<V: Into<FilterValue>>(&self, value: V) -> Filter {
235		Filter::new(self.name.to_string(), FilterOperator::Gte, value.into())
236	}
237
238	/// Create a less-than filter for this field
239	///
240	/// # Examples
241	///
242	/// ```ignore
243	/// let filter = User::field_age().lt(65);
244	/// // Results in: WHERE age < 65
245	/// ```
246	pub fn lt<V: Into<FilterValue>>(&self, value: V) -> Filter {
247		Filter::new(self.name.to_string(), FilterOperator::Lt, value.into())
248	}
249
250	/// Create a less-than-or-equal filter for this field
251	///
252	/// # Examples
253	///
254	/// ```ignore
255	/// let filter = User::field_age().lte(65);
256	/// // Results in: WHERE age <= 65
257	/// ```
258	pub fn lte<V: Into<FilterValue>>(&self, value: V) -> Filter {
259		Filter::new(self.name.to_string(), FilterOperator::Lte, value.into())
260	}
261
262	/// Create an IN filter. Named `is_in` because `in` is a Rust keyword.
263	pub fn is_in<I, V>(&self, values: I) -> Filter
264	where
265		I: IntoIterator<Item = V>,
266		V: Into<FilterValue>,
267	{
268		Filter::new(
269			self.name.to_string(),
270			FilterOperator::In,
271			FilterValue::List(values.into_iter().map(Into::into).collect()),
272		)
273	}
274
275	/// Create a NOT IN filter.
276	pub fn not_in<I, V>(&self, values: I) -> Filter
277	where
278		I: IntoIterator<Item = V>,
279		V: Into<FilterValue>,
280	{
281		Filter::new(
282			self.name.to_string(),
283			FilterOperator::NotIn,
284			FilterValue::List(values.into_iter().map(Into::into).collect()),
285		)
286	}
287
288	/// Create a LIKE `%value%` containment filter.
289	pub fn contains<V: Into<FilterValue>>(&self, value: V) -> Filter {
290		Filter::new(
291			self.name.to_string(),
292			FilterOperator::Contains,
293			value.into(),
294		)
295	}
296
297	/// Create a case-insensitive containment filter.
298	pub fn icontains<V: Into<FilterValue>>(&self, value: V) -> Filter {
299		Filter::new(
300			self.name.to_string(),
301			FilterOperator::IContains,
302			value.into(),
303		)
304	}
305
306	/// Create a LIKE `value%` prefix filter.
307	pub fn starts_with<V: Into<FilterValue>>(&self, value: V) -> Filter {
308		Filter::new(
309			self.name.to_string(),
310			FilterOperator::StartsWith,
311			value.into(),
312		)
313	}
314
315	/// Create a case-insensitive prefix filter.
316	pub fn istarts_with<V: Into<FilterValue>>(&self, value: V) -> Filter {
317		Filter::new(
318			self.name.to_string(),
319			FilterOperator::IStartsWith,
320			value.into(),
321		)
322	}
323
324	/// Create a LIKE `%value` suffix filter.
325	pub fn ends_with<V: Into<FilterValue>>(&self, value: V) -> Filter {
326		Filter::new(
327			self.name.to_string(),
328			FilterOperator::EndsWith,
329			value.into(),
330		)
331	}
332
333	/// Create a case-insensitive suffix filter.
334	pub fn iends_with<V: Into<FilterValue>>(&self, value: V) -> Filter {
335		Filter::new(
336			self.name.to_string(),
337			FilterOperator::IEndsWith,
338			value.into(),
339		)
340	}
341
342	/// Create an IS NULL filter.
343	pub fn is_null(&self) -> Filter {
344		Filter::new(
345			self.name.to_string(),
346			FilterOperator::IsNull,
347			FilterValue::Null,
348		)
349	}
350
351	/// Create an IS NOT NULL filter.
352	pub fn is_not_null(&self) -> Filter {
353		Filter::new(
354			self.name.to_string(),
355			FilterOperator::IsNotNull,
356			FilterValue::Null,
357		)
358	}
359
360	/// Create a regular expression filter.
361	pub fn regex<V: Into<FilterValue>>(&self, pattern: V) -> Filter {
362		Filter::new(self.name.to_string(), FilterOperator::Regex, pattern.into())
363	}
364
365	/// Create a case-insensitive regular expression filter.
366	pub fn iregex<V: Into<FilterValue>>(&self, pattern: V) -> Filter {
367		Filter::new(
368			self.name.to_string(),
369			FilterOperator::IRegex,
370			pattern.into(),
371		)
372	}
373
374	/// Create a BETWEEN filter.
375	pub fn range<V: Into<FilterValue>>(&self, start: V, end: V) -> Filter {
376		Filter::new(
377			self.name.to_string(),
378			FilterOperator::Range,
379			FilterValue::Range(Box::new(start.into()), Box::new(end.into())),
380		)
381	}
382
383	/// Create a PostgreSQL array containment filter (`@>`).
384	pub fn array_contains<I, V>(&self, values: I) -> Filter
385	where
386		I: IntoIterator<Item = V>,
387		V: ToString,
388	{
389		Filter::new(
390			self.name.to_string(),
391			FilterOperator::ArrayContains,
392			FilterValue::Array(values.into_iter().map(|v| v.to_string()).collect()),
393		)
394	}
395
396	/// Create a PostgreSQL array contained-by filter (`<@`).
397	pub fn array_contained_by<I, V>(&self, values: I) -> Filter
398	where
399		I: IntoIterator<Item = V>,
400		V: ToString,
401	{
402		Filter::new(
403			self.name.to_string(),
404			FilterOperator::ArrayContainedBy,
405			FilterValue::Array(values.into_iter().map(|v| v.to_string()).collect()),
406		)
407	}
408
409	/// Create a PostgreSQL array overlap filter (`&&`).
410	pub fn array_overlap<I, V>(&self, values: I) -> Filter
411	where
412		I: IntoIterator<Item = V>,
413		V: ToString,
414	{
415		Filter::new(
416			self.name.to_string(),
417			FilterOperator::ArrayOverlap,
418			FilterValue::Array(values.into_iter().map(|v| v.to_string()).collect()),
419		)
420	}
421
422	/// Create a PostgreSQL JSONB containment filter (`@>`).
423	pub fn jsonb_contains(&self, json: &str) -> Filter {
424		Filter::new(
425			self.name.to_string(),
426			FilterOperator::JsonbContains,
427			FilterValue::String(json.to_string()),
428		)
429	}
430
431	/// Create a PostgreSQL JSONB contained-by filter (`<@`).
432	pub fn jsonb_contained_by(&self, json: &str) -> Filter {
433		Filter::new(
434			self.name.to_string(),
435			FilterOperator::JsonbContainedBy,
436			FilterValue::String(json.to_string()),
437		)
438	}
439
440	/// Create a PostgreSQL JSONB key-exists filter (`?`).
441	pub fn jsonb_has_key(&self, key: &str) -> Filter {
442		Filter::new(
443			self.name.to_string(),
444			FilterOperator::JsonbKeyExists,
445			FilterValue::String(key.to_string()),
446		)
447	}
448
449	/// Create a PostgreSQL JSONB any-key-exists filter (`?|`).
450	pub fn jsonb_has_any_keys<I, V>(&self, keys: I) -> Filter
451	where
452		I: IntoIterator<Item = V>,
453		V: ToString,
454	{
455		Filter::new(
456			self.name.to_string(),
457			FilterOperator::JsonbAnyKeyExists,
458			FilterValue::Array(keys.into_iter().map(|v| v.to_string()).collect()),
459		)
460	}
461
462	/// Create a PostgreSQL JSONB all-keys-exist filter (`?&`).
463	pub fn jsonb_has_keys<I, V>(&self, keys: I) -> Filter
464	where
465		I: IntoIterator<Item = V>,
466		V: ToString,
467	{
468		Filter::new(
469			self.name.to_string(),
470			FilterOperator::JsonbAllKeysExist,
471			FilterValue::Array(keys.into_iter().map(|v| v.to_string()).collect()),
472		)
473	}
474
475	/// Create a PostgreSQL JSONPath existence filter (`@?`).
476	pub fn jsonb_path_exists(&self, path: &str) -> Filter {
477		Filter::new(
478			self.name.to_string(),
479			FilterOperator::JsonbPathExists,
480			FilterValue::String(path.to_string()),
481		)
482	}
483
484	/// Create a PostgreSQL range field containment filter (`@>`).
485	pub fn range_contains<V: Into<FilterValue>>(&self, value: V) -> Filter {
486		Filter::new(
487			self.name.to_string(),
488			FilterOperator::RangeContains,
489			value.into(),
490		)
491	}
492
493	/// Create a PostgreSQL range field contained-by filter (`<@`).
494	pub fn range_contained_by(&self, range: &str) -> Filter {
495		Filter::new(
496			self.name.to_string(),
497			FilterOperator::RangeContainedBy,
498			FilterValue::String(range.to_string()),
499		)
500	}
501
502	/// Create a PostgreSQL range field overlap filter (`&&`).
503	pub fn range_overlaps(&self, range: &str) -> Filter {
504		Filter::new(
505			self.name.to_string(),
506			FilterOperator::RangeOverlaps,
507			FilterValue::String(range.to_string()),
508		)
509	}
510
511	/// Transform a date/datetime field to its date component.
512	pub fn date(&self) -> TransformedFieldRef<M> {
513		self.transform("DATE({field})")
514	}
515
516	/// Transform a datetime/time field to its time component.
517	pub fn time(&self) -> TransformedFieldRef<M> {
518		self.transform("TIME({field})")
519	}
520
521	/// Transform a date/datetime field to its year component.
522	pub fn year(&self) -> TransformedFieldRef<M> {
523		self.extract("YEAR")
524	}
525
526	/// Transform a date/datetime field to its ISO year component.
527	pub fn iso_year(&self) -> TransformedFieldRef<M> {
528		self.extract("ISOYEAR")
529	}
530
531	/// Transform a date/datetime field to its month component.
532	pub fn month(&self) -> TransformedFieldRef<M> {
533		self.extract("MONTH")
534	}
535
536	/// Transform a date/datetime field to its day component.
537	pub fn day(&self) -> TransformedFieldRef<M> {
538		self.extract("DAY")
539	}
540
541	/// Transform a date/datetime field to its week component.
542	pub fn week(&self) -> TransformedFieldRef<M> {
543		self.extract("WEEK")
544	}
545
546	/// Transform to Django-compatible weekday where Sunday is 1.
547	pub fn week_day(&self) -> TransformedFieldRef<M> {
548		self.transform("(EXTRACT(DOW FROM {field}) + 1)")
549	}
550
551	/// Transform to ISO weekday where Monday is 1.
552	pub fn iso_week_day(&self) -> TransformedFieldRef<M> {
553		self.extract("ISODOW")
554	}
555
556	/// Transform a date/datetime field to its quarter component.
557	pub fn quarter(&self) -> TransformedFieldRef<M> {
558		self.extract("QUARTER")
559	}
560
561	/// Transform a datetime/time field to its hour component.
562	pub fn hour(&self) -> TransformedFieldRef<M> {
563		self.extract("HOUR")
564	}
565
566	/// Transform a datetime/time field to its minute component.
567	pub fn minute(&self) -> TransformedFieldRef<M> {
568		self.extract("MINUTE")
569	}
570
571	/// Transform a datetime/time field to its second component.
572	pub fn second(&self) -> TransformedFieldRef<M> {
573		self.extract("SECOND")
574	}
575
576	fn extract(&self, part: &str) -> TransformedFieldRef<M> {
577		self.transform(&format!("EXTRACT({} FROM {{field}})", part))
578	}
579
580	fn transform(&self, template: &str) -> TransformedFieldRef<M> {
581		let sql = template.replace("{field}", &quote_identifier(self.name));
582		TransformedFieldRef::new(sql, self.name)
583	}
584
585	/// Create an equality filter comparing this field to another field
586	///
587	/// # Examples
588	///
589	/// ```ignore
590	/// let filter = Order::field_discount_price().eq_field(Order::field_total_price());
591	/// // Results in: WHERE discount_price = total_price
592	/// ```
593	pub fn eq_field<T2>(&self, other: FieldRef<M, T2>) -> Filter {
594		Filter::new(
595			self.name.to_string(),
596			FilterOperator::Eq,
597			FilterValue::FieldRef(F::new(other.name)),
598		)
599	}
600
601	/// Create a not-equal filter comparing this field to another field
602	///
603	/// # Examples
604	///
605	/// ```ignore
606	/// let filter = Order::field_discount_price().ne_field(Order::field_total_price());
607	/// // Results in: WHERE discount_price != total_price
608	/// ```
609	pub fn ne_field<T2>(&self, other: FieldRef<M, T2>) -> Filter {
610		Filter::new(
611			self.name.to_string(),
612			FilterOperator::Ne,
613			FilterValue::FieldRef(F::new(other.name)),
614		)
615	}
616
617	/// Create a greater-than filter comparing this field to another field
618	///
619	/// # Examples
620	///
621	/// ```ignore
622	/// let filter = Order::field_total_price().gt_field(Order::field_discount_price());
623	/// // Results in: WHERE total_price > discount_price
624	/// ```
625	pub fn gt_field<T2>(&self, other: FieldRef<M, T2>) -> Filter {
626		Filter::new(
627			self.name.to_string(),
628			FilterOperator::Gt,
629			FilterValue::FieldRef(F::new(other.name)),
630		)
631	}
632
633	/// Create a greater-than-or-equal filter comparing this field to another field
634	///
635	/// # Examples
636	///
637	/// ```ignore
638	/// let filter = Order::field_total_price().gte_field(Order::field_discount_price());
639	/// // Results in: WHERE total_price >= discount_price
640	/// ```
641	pub fn gte_field<T2>(&self, other: FieldRef<M, T2>) -> Filter {
642		Filter::new(
643			self.name.to_string(),
644			FilterOperator::Gte,
645			FilterValue::FieldRef(F::new(other.name)),
646		)
647	}
648
649	/// Create a less-than filter comparing this field to another field
650	///
651	/// # Examples
652	///
653	/// ```ignore
654	/// let filter = Order::field_discount_price().lt_field(Order::field_total_price());
655	/// // Results in: WHERE discount_price < total_price
656	/// ```
657	pub fn lt_field<T2>(&self, other: FieldRef<M, T2>) -> Filter {
658		Filter::new(
659			self.name.to_string(),
660			FilterOperator::Lt,
661			FilterValue::FieldRef(F::new(other.name)),
662		)
663	}
664
665	/// Create a less-than-or-equal filter comparing this field to another field
666	///
667	/// # Examples
668	///
669	/// ```ignore
670	/// let filter = Order::field_discount_price().lte_field(Order::field_total_price());
671	/// // Results in: WHERE discount_price <= total_price
672	/// ```
673	pub fn lte_field<T2>(&self, other: FieldRef<M, T2>) -> Filter {
674		Filter::new(
675			self.name.to_string(),
676			FilterOperator::Lte,
677			FilterValue::FieldRef(F::new(other.name)),
678		)
679	}
680}
681
682#[derive(Debug, Clone)]
683/// A SQL transform applied to a model field for Django-style date/time lookups.
684pub struct TransformedFieldRef<M> {
685	sql: String,
686	source: String,
687	_phantom: PhantomData<M>,
688}
689
690impl<M> TransformedFieldRef<M> {
691	fn new(sql: String, source: &str) -> Self {
692		Self {
693			sql,
694			source: source.to_owned(),
695			_phantom: PhantomData,
696		}
697	}
698
699	fn filter<V: Into<FilterValue>>(&self, operator: FilterOperator, value: V) -> Filter {
700		Filter::expression_with_source(
701			self.sql.clone(),
702			Some(self.source.clone()),
703			operator,
704			value.into(),
705		)
706	}
707
708	/// Create an equality filter on the transformed value.
709	pub fn eq<V: Into<FilterValue>>(&self, value: V) -> Filter {
710		self.filter(FilterOperator::Eq, value)
711	}
712
713	/// Create an exact equality filter using Django lookup naming.
714	pub fn exact<V: Into<FilterValue>>(&self, value: V) -> Filter {
715		self.eq(value)
716	}
717
718	/// Create a case-insensitive exact match filter on the transformed value.
719	pub fn iexact<V: Into<FilterValue>>(&self, value: V) -> Filter {
720		self.filter(FilterOperator::IExact, value)
721	}
722
723	/// Create a not-equal filter on the transformed value.
724	pub fn ne<V: Into<FilterValue>>(&self, value: V) -> Filter {
725		self.filter(FilterOperator::Ne, value)
726	}
727
728	/// Create a greater-than filter on the transformed value.
729	pub fn gt<V: Into<FilterValue>>(&self, value: V) -> Filter {
730		self.filter(FilterOperator::Gt, value)
731	}
732
733	/// Create a greater-than-or-equal filter on the transformed value.
734	pub fn gte<V: Into<FilterValue>>(&self, value: V) -> Filter {
735		self.filter(FilterOperator::Gte, value)
736	}
737
738	/// Create a less-than filter on the transformed value.
739	pub fn lt<V: Into<FilterValue>>(&self, value: V) -> Filter {
740		self.filter(FilterOperator::Lt, value)
741	}
742
743	/// Create a less-than-or-equal filter on the transformed value.
744	pub fn lte<V: Into<FilterValue>>(&self, value: V) -> Filter {
745		self.filter(FilterOperator::Lte, value)
746	}
747
748	/// Create an IN filter on the transformed value.
749	pub fn is_in<I, V>(&self, values: I) -> Filter
750	where
751		I: IntoIterator<Item = V>,
752		V: Into<FilterValue>,
753	{
754		Filter::expression_with_source(
755			self.sql.clone(),
756			Some(self.source.clone()),
757			FilterOperator::In,
758			FilterValue::List(values.into_iter().map(Into::into).collect()),
759		)
760	}
761
762	/// Create a BETWEEN filter on the transformed value.
763	pub fn range<V: Into<FilterValue>>(&self, start: V, end: V) -> Filter {
764		Filter::expression_with_source(
765			self.sql.clone(),
766			Some(self.source.clone()),
767			FilterOperator::Range,
768			FilterValue::Range(Box::new(start.into()), Box::new(end.into())),
769		)
770	}
771
772	/// Return the SQL expression backing this transformed field.
773	pub fn to_sql(&self) -> &str {
774		&self.sql
775	}
776}
777
778impl<M, T> fmt::Display for FieldRef<M, T> {
779	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
780		write!(f, "{}", self.name)
781	}
782}
783
784// Allow conversion from FieldRef to String for general string-context use
785// (logging, error messages, custom query builders). `Manager::filter` /
786// `QuerySet::filter` now take `impl Into<FilterCondition>` (Issue #4650), so they
787// no longer rely on this conversion.
788impl<M, T> From<FieldRef<M, T>> for String {
789	fn from(field_ref: FieldRef<M, T>) -> Self {
790		field_ref.name.to_string()
791	}
792}
793
794// Allow conversion from FieldRef to F for backward compatibility
795impl<M, T> From<FieldRef<M, T>> for F {
796	fn from(field_ref: FieldRef<M, T>) -> Self {
797		F::new(field_ref.name)
798	}
799}
800
801/// OuterRef - reference to a field in the outer query (for subqueries)
802#[derive(Debug, Clone, Serialize, Deserialize)]
803pub struct OuterRef {
804	/// The field.
805	pub field: String,
806}
807
808impl OuterRef {
809	/// Create a reference to an outer query field (for subqueries)
810	///
811	/// # Examples
812	///
813	/// ```
814	/// use reinhardt_db::orm::expressions::OuterRef;
815	///
816	/// // Reference parent query field in subquery
817	/// let parent_id = OuterRef::new("parent_id");
818	/// assert_eq!(parent_id.to_sql(), "parent_id");
819	///
820	// Useful in correlated subqueries like:
821	// SELECT * FROM items WHERE id IN (
822	//   SELECT item_id FROM tags WHERE user_id = OuterRef("user_id")
823	// )
824	/// ```
825	pub fn new(field: impl Into<String>) -> Self {
826		Self {
827			field: field.into(),
828		}
829	}
830	/// Generate SQL for the outer reference
831	///
832	/// # Examples
833	///
834	/// ```
835	/// use reinhardt_db::orm::expressions::OuterRef;
836	///
837	/// let outer_field = OuterRef::new("category_id");
838	/// assert_eq!(outer_field.to_sql(), "category_id");
839	/// ```
840	pub fn to_sql(&self) -> String {
841		// In a subquery context, this references the outer query's field
842		self.field.clone()
843	}
844}
845
846/// Subquery - represents a subquery expression
847#[derive(Debug, Clone, Serialize, Deserialize)]
848pub struct Subquery {
849	/// The sql.
850	pub sql: String,
851	/// The template.
852	pub template: String,
853}
854
855impl Subquery {
856	/// Create a subquery expression
857	///
858	/// # Examples
859	///
860	/// ```
861	/// use reinhardt_db::orm::expressions::Subquery;
862	///
863	/// // Create a subquery for filtering
864	/// let sq = Subquery::new("SELECT id FROM users WHERE active = 1");
865	/// let sql = sq.to_sql();
866	/// assert!(sql.contains("SELECT id FROM users"));
867	/// assert!(sql.starts_with("(") && sql.ends_with(")"));
868	/// ```
869	pub fn new(sql: impl Into<String>) -> Self {
870		Self {
871			sql: sql.into(),
872			template: "(%(subquery)s)".to_string(),
873		}
874	}
875	/// Customize the SQL template for the subquery
876	///
877	/// # Examples
878	///
879	/// ```
880	/// use reinhardt_db::orm::expressions::Subquery;
881	///
882	/// let sq = Subquery::new("SELECT COUNT(*) FROM orders")
883	///     .with_template("ORDER_COUNT = %(subquery)s");
884	/// assert_eq!(sq.to_sql(), "ORDER_COUNT = SELECT COUNT(*) FROM orders");
885	/// ```
886	pub fn with_template(mut self, template: impl Into<String>) -> Self {
887		self.template = template.into();
888		self
889	}
890	/// Generate final SQL from template
891	///
892	/// # Examples
893	///
894	/// ```
895	/// use reinhardt_db::orm::expressions::Subquery;
896	///
897	/// let sq = Subquery::new("SELECT MAX(price) FROM products");
898	/// assert!(sq.to_sql().starts_with("("));
899	/// ```
900	pub fn to_sql(&self) -> String {
901		self.template.replace("%(subquery)s", &self.sql)
902	}
903}
904
905/// Exists - check if a subquery returns any rows
906#[derive(Debug, Clone, Serialize, Deserialize)]
907pub struct Exists {
908	/// The subquery.
909	pub subquery: Subquery,
910}
911
912impl Exists {
913	/// Create an EXISTS check for a subquery
914	///
915	/// # Examples
916	///
917	/// ```
918	/// use reinhardt_db::orm::expressions::Exists;
919	///
920	/// // Check if related records exist
921	/// let exists = Exists::new("SELECT 1 FROM orders WHERE user_id = 123");
922	/// let sql = exists.to_sql();
923	/// assert!(sql.starts_with("EXISTS("));
924	/// assert!(sql.contains("SELECT 1 FROM orders"));
925	/// ```
926	pub fn new(sql: impl Into<String>) -> Self {
927		Self {
928			subquery: Subquery {
929				sql: sql.into(),
930				template: "%(subquery)s".to_string(),
931			},
932		}
933	}
934	/// Generate EXISTS SQL
935	///
936	/// # Examples
937	///
938	/// ```
939	/// use reinhardt_db::orm::expressions::Exists;
940	///
941	/// let exists = Exists::new("SELECT 1 FROM tags WHERE item_id = items.id");
942	/// assert!(exists.to_sql().starts_with("EXISTS("));
943	/// ```
944	pub fn to_sql(&self) -> String {
945		format!("EXISTS({})", self.subquery.to_sql())
946	}
947}
948
949/// Value expression - represents a literal value in a query
950/// Similar to Django's Value() for using literal values in expressions
951#[derive(Debug, Clone, Serialize, Deserialize)]
952pub struct Value {
953	/// The value.
954	pub value: ValueType,
955}
956
957#[derive(Debug, Clone, Serialize, Deserialize)]
958/// Defines possible value type values.
959pub enum ValueType {
960	/// String variant.
961	String(String),
962	/// Integer variant.
963	Integer(i64),
964	/// Float variant.
965	Float(f64),
966	/// Bool variant.
967	Bool(bool),
968	/// Null variant.
969	Null,
970}
971
972impl Value {
973	/// Create a literal value expression
974	///
975	/// # Examples
976	///
977	/// ```
978	/// use reinhardt_db::orm::expressions::{Value, ValueType};
979	///
980	/// let val = Value::new("active");
981	/// // Verify the value is created successfully
982	/// let _: Value = val;
983	/// ```
984	pub fn new<T: Into<ValueType>>(value: T) -> Self {
985		Self {
986			value: value.into(),
987		}
988	}
989	/// Create a string literal value
990	///
991	/// # Examples
992	///
993	/// ```
994	/// use reinhardt_db::orm::expressions::Value;
995	///
996	/// let status = Value::string("active");
997	/// assert_eq!(status.to_sql(), "'active'");
998	/// ```
999	pub fn string(s: impl Into<String>) -> Self {
1000		Self {
1001			value: ValueType::String(s.into()),
1002		}
1003	}
1004	/// Create an integer literal value
1005	///
1006	/// # Examples
1007	///
1008	/// ```
1009	/// use reinhardt_db::orm::expressions::Value;
1010	///
1011	/// let count = Value::int(42);
1012	/// assert_eq!(count.to_sql(), "42");
1013	/// ```
1014	pub fn int(i: i64) -> Self {
1015		Self {
1016			value: ValueType::Integer(i),
1017		}
1018	}
1019	/// Create a float literal value
1020	///
1021	/// # Examples
1022	///
1023	/// ```
1024	/// use reinhardt_db::orm::expressions::Value;
1025	///
1026	/// let price = Value::float(99.99);
1027	/// assert_eq!(price.to_sql(), "99.99");
1028	/// ```
1029	pub fn float(f: f64) -> Self {
1030		Self {
1031			value: ValueType::Float(f),
1032		}
1033	}
1034	/// Create a boolean literal value
1035	///
1036	/// # Examples
1037	///
1038	/// ```
1039	/// use reinhardt_db::orm::expressions::Value;
1040	///
1041	/// let is_active = Value::bool(true);
1042	/// assert_eq!(is_active.to_sql(), "TRUE");
1043	/// ```
1044	pub fn bool(b: bool) -> Self {
1045		Self {
1046			value: ValueType::Bool(b),
1047		}
1048	}
1049	/// Create a NULL literal value
1050	///
1051	/// # Examples
1052	///
1053	/// ```
1054	/// use reinhardt_db::orm::expressions::Value;
1055	///
1056	/// let empty = Value::null();
1057	/// assert_eq!(empty.to_sql(), "NULL");
1058	/// ```
1059	pub fn null() -> Self {
1060		Self {
1061			value: ValueType::Null,
1062		}
1063	}
1064	/// Generate SQL for this literal value
1065	///
1066	/// # Examples
1067	///
1068	/// ```
1069	/// use reinhardt_db::orm::expressions::Value;
1070	///
1071	/// assert_eq!(Value::string("test").to_sql(), "'test'");
1072	/// assert_eq!(Value::int(10).to_sql(), "10");
1073	/// assert_eq!(Value::bool(false).to_sql(), "FALSE");
1074	/// ```
1075	pub fn to_sql(&self) -> String {
1076		match &self.value {
1077			ValueType::String(s) => format!("'{}'", s.replace('\'', "''")),
1078			ValueType::Integer(i) => i.to_string(),
1079			ValueType::Float(f) => f.to_string(),
1080			ValueType::Bool(b) => if *b { "TRUE" } else { "FALSE" }.to_string(),
1081			ValueType::Null => "NULL".to_string(),
1082		}
1083	}
1084}
1085
1086impl From<String> for ValueType {
1087	fn from(s: String) -> Self {
1088		ValueType::String(s)
1089	}
1090}
1091
1092impl From<&str> for ValueType {
1093	fn from(s: &str) -> Self {
1094		ValueType::String(s.to_string())
1095	}
1096}
1097
1098impl From<i64> for ValueType {
1099	fn from(i: i64) -> Self {
1100		ValueType::Integer(i)
1101	}
1102}
1103
1104impl From<i32> for ValueType {
1105	fn from(i: i32) -> Self {
1106		ValueType::Integer(i as i64)
1107	}
1108}
1109
1110impl From<f64> for ValueType {
1111	fn from(f: f64) -> Self {
1112		ValueType::Float(f)
1113	}
1114}
1115
1116impl From<bool> for ValueType {
1117	fn from(b: bool) -> Self {
1118		ValueType::Bool(b)
1119	}
1120}
1121
1122/// Q operator for combining query conditions
1123#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1124pub enum QOperator {
1125	/// And variant.
1126	And,
1127	/// Or variant.
1128	Or,
1129	/// Not variant.
1130	Not,
1131}
1132
1133impl fmt::Display for QOperator {
1134	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1135		match self {
1136			QOperator::And => write!(f, "AND"),
1137			QOperator::Or => write!(f, "OR"),
1138			QOperator::Not => write!(f, "NOT"),
1139		}
1140	}
1141}
1142
1143/// Q object - represents a complex query condition
1144/// Similar to Django's Q() objects for building complex queries
1145#[derive(Debug, Clone, Serialize, Deserialize)]
1146pub enum Q {
1147	/// Simple condition: field, operator, value
1148	Condition {
1149		/// The field.
1150		field: String,
1151		/// The operator.
1152		operator: String,
1153		/// The value.
1154		value: String,
1155	},
1156	/// Combined conditions with AND/OR/NOT
1157	Combined {
1158		/// The operator.
1159		operator: QOperator,
1160		/// The conditions.
1161		conditions: Vec<Q>,
1162	},
1163}
1164
1165impl Q {
1166	/// Create a simple Q object with a condition
1167	///
1168	/// # Examples
1169	///
1170	/// ```
1171	/// use reinhardt_db::orm::expressions::Q;
1172	///
1173	/// // Create a simple condition
1174	/// let q = Q::new("age", ">=", "18");
1175	/// assert_eq!(q.to_sql(), "\"age\" >= 18");
1176	///
1177	/// // Combine conditions
1178	/// let q1 = Q::new("status", "=", "active");
1179	/// let q2 = Q::new("verified", "=", "true");
1180	/// let combined = q1.and(q2);
1181	/// ```
1182	pub fn new(
1183		field: impl Into<String>,
1184		operator: impl Into<String>,
1185		value: impl Into<String>,
1186	) -> Self {
1187		Self::Condition {
1188			field: field.into(),
1189			operator: operator.into(),
1190			value: value.into(),
1191		}
1192	}
1193	/// Parse a supported SQL condition into a Q object.
1194	///
1195	/// Unrecognized or partially raw SQL is rejected as an invalid condition.
1196	/// Prefer [`Q::new`] for runtime values so execution can preserve bind
1197	/// parameters. Use [`Q::from_raw_sql`] only for trusted raw SQL.
1198	///
1199	/// # Examples
1200	///
1201	/// ```
1202	/// use reinhardt_db::orm::expressions::Q;
1203	///
1204	/// let q = Q::from_sql("age > 18");
1205	/// let q = Q::from_sql("name LIKE '%John%'");
1206	/// let q = Q::from_sql("email IS NOT NULL");
1207	/// let q = Q::from_sql("status IN ('active', 'pending')");
1208	/// let q = Q::from_sql("age BETWEEN 18 AND 65");
1209	/// ```
1210	pub fn from_sql(sql: &str) -> Self {
1211		let condition = super::sql_condition_parser::SqlConditionParser::parse(sql);
1212		if condition.contains_raw_condition() {
1213			Self::new("", "INVALID", "")
1214		} else {
1215			condition
1216		}
1217	}
1218
1219	/// Create a Q object from trusted raw SQL.
1220	///
1221	/// This bypasses identifier validation and value binding. Never pass runtime
1222	/// or request-derived input to this method.
1223	pub fn from_raw_sql(sql: impl Into<String>) -> Self {
1224		Self::Condition {
1225			field: String::new(),
1226			operator: String::new(),
1227			value: sql.into(),
1228		}
1229	}
1230
1231	fn contains_raw_condition(&self) -> bool {
1232		match self {
1233			Self::Condition {
1234				field, operator, ..
1235			} => field.is_empty() && operator.is_empty(),
1236			Self::Combined { conditions, .. } => {
1237				conditions.iter().any(Self::contains_raw_condition)
1238			}
1239		}
1240	}
1241	/// Create an empty Q object (always true condition)
1242	///
1243	pub fn empty() -> Self {
1244		Self::Combined {
1245			operator: QOperator::And,
1246			conditions: vec![],
1247		}
1248	}
1249	/// Combine this Q object with another using AND
1250	///
1251	pub fn and(self, other: Q) -> Self {
1252		match self {
1253			Q::Combined {
1254				operator: QOperator::And,
1255				mut conditions,
1256			} => {
1257				conditions.push(other);
1258				Q::Combined {
1259					operator: QOperator::And,
1260					conditions,
1261				}
1262			}
1263			_ => Q::Combined {
1264				operator: QOperator::And,
1265				conditions: vec![self, other],
1266			},
1267		}
1268	}
1269	/// Combine this Q object with another using OR
1270	///
1271	pub fn or(self, other: Q) -> Self {
1272		match self {
1273			Q::Combined {
1274				operator: QOperator::Or,
1275				mut conditions,
1276			} => {
1277				conditions.push(other);
1278				Q::Combined {
1279					operator: QOperator::Or,
1280					conditions,
1281				}
1282			}
1283			_ => Q::Combined {
1284				operator: QOperator::Or,
1285				conditions: vec![self, other],
1286			},
1287		}
1288	}
1289	/// Negate this Q object
1290	///
1291	/// Note: This method consumes `self` and returns a new `Q` object,
1292	/// which is incompatible with the `std::ops::Not` trait that requires
1293	/// returning a reference. Therefore, we keep this as a regular method.
1294	#[allow(clippy::should_implement_trait)]
1295	pub fn not(self) -> Self {
1296		Q::Combined {
1297			operator: QOperator::Not,
1298			conditions: vec![self],
1299		}
1300	}
1301	/// Generate SQL for this Q object
1302	///
1303	pub fn to_sql(&self) -> String {
1304		match self {
1305			Q::Condition {
1306				field,
1307				operator,
1308				value,
1309			} => {
1310				// If field and operator are empty, this is a raw SQL condition from FieldLookupCompiler
1311				if field.is_empty() && operator.is_empty() {
1312					return value.clone();
1313				}
1314
1315				let operator = operator.to_ascii_uppercase();
1316				let Some(field) = Self::format_sql_field(field) else {
1317					return "FALSE".to_string();
1318				};
1319				let valid_operator = matches!(
1320					operator.as_str(),
1321					"=" | "!="
1322						| "<>" | ">" | ">="
1323						| "<" | "<=" | "IN"
1324						| "NOT IN" | "LIKE"
1325						| "IS NULL" | "IS NOT NULL"
1326				);
1327				if !valid_operator {
1328					return "FALSE".to_string();
1329				}
1330
1331				if matches!(operator.as_str(), "IS NULL" | "IS NOT NULL") {
1332					return format!("{} {}", field, operator);
1333				}
1334
1335				let formatted_value = if matches!(operator.as_str(), "IN" | "NOT IN") {
1336					let values = value.trim().trim_start_matches('(').trim_end_matches(')');
1337					format!(
1338						"({})",
1339						values
1340							.split(',')
1341							.map(Self::format_sql_value)
1342							.collect::<Vec<_>>()
1343							.join(", ")
1344					)
1345				} else {
1346					Self::format_sql_value(value)
1347				};
1348				format!("{} {} {}", field, operator, formatted_value)
1349			}
1350			Q::Combined {
1351				operator,
1352				conditions,
1353			} => {
1354				let sql_conditions: Vec<String> = conditions.iter().map(|q| q.to_sql()).collect();
1355
1356				match operator {
1357					QOperator::Not => {
1358						if conditions.len() == 1 {
1359							format!("NOT ({})", sql_conditions[0])
1360						} else {
1361							format!("NOT ({})", sql_conditions.join(" AND "))
1362						}
1363					}
1364					QOperator::And => {
1365						if sql_conditions.len() == 1 {
1366							sql_conditions[0].clone()
1367						} else {
1368							format!("({})", sql_conditions.join(" AND "))
1369						}
1370					}
1371					QOperator::Or => {
1372						if sql_conditions.len() == 1 {
1373							sql_conditions[0].clone()
1374						} else {
1375							format!("({})", sql_conditions.join(" OR "))
1376						}
1377					}
1378				}
1379			}
1380		}
1381	}
1382
1383	fn format_sql_value(value: &str) -> String {
1384		let value = value.trim();
1385		if value.parse::<f64>().is_ok()
1386			|| value.eq_ignore_ascii_case("TRUE")
1387			|| value.eq_ignore_ascii_case("FALSE")
1388			|| value.eq_ignore_ascii_case("NULL")
1389		{
1390			return value.to_string();
1391		}
1392
1393		let value = value
1394			.strip_prefix('\'')
1395			.and_then(|value| value.strip_suffix('\''))
1396			.unwrap_or(value);
1397		format!("'{}'", value.replace('\'', "''"))
1398	}
1399
1400	fn format_sql_field(field: &str) -> Option<String> {
1401		for function in ["COUNT", "SUM", "AVG", "MAX", "MIN"] {
1402			if let Some(argument) = field
1403				.strip_prefix(function)
1404				.and_then(|suffix| suffix.strip_prefix('('))
1405				.and_then(|suffix| suffix.strip_suffix(')'))
1406			{
1407				return if argument == "*" {
1408					Some(format!("{function}(*)"))
1409				} else {
1410					Self::format_sql_identifier(argument)
1411						.map(|argument| format!("{function}({argument})"))
1412				};
1413			}
1414		}
1415
1416		Self::format_sql_identifier(field)
1417	}
1418
1419	fn format_sql_identifier(field: &str) -> Option<String> {
1420		let valid = !field.is_empty()
1421			&& field.split('.').all(|part| {
1422				!part.is_empty()
1423					&& part
1424						.chars()
1425						.all(|character| character.is_ascii_alphanumeric() || character == '_')
1426			});
1427		valid.then(|| quote_identifier(field))
1428	}
1429}
1430
1431#[cfg(test)]
1432mod tests {
1433	use super::*;
1434
1435	// Allow dead_code: test model struct for FieldRef trait implementation verification
1436	#[allow(dead_code)]
1437	struct TestUser {
1438		id: i64,
1439		name: String,
1440		created_at: i64,
1441	}
1442
1443	// Simulating what #[derive(Model)] macro would generate
1444	impl TestUser {
1445		const fn field_id() -> FieldRef<TestUser, i64> {
1446			FieldRef::new("id")
1447		}
1448
1449		const fn field_name() -> FieldRef<TestUser, String> {
1450			FieldRef::new("name")
1451		}
1452
1453		const fn field_created_at() -> FieldRef<TestUser, i64> {
1454			FieldRef::new("created_at")
1455		}
1456	}
1457
1458	#[test]
1459	fn test_field_ref_basic() {
1460		let id_ref = TestUser::field_id();
1461		assert_eq!(id_ref.name(), "id");
1462		assert_eq!(id_ref.to_sql(), "\"id\"");
1463		assert_eq!(format!("{}", id_ref), "id");
1464	}
1465
1466	#[test]
1467	fn test_field_ref_string_field() {
1468		let name_ref = TestUser::field_name();
1469		assert_eq!(name_ref.name(), "name");
1470		assert_eq!(name_ref.to_sql(), "\"name\"");
1471	}
1472
1473	#[test]
1474	fn test_field_ref_to_f_conversion() {
1475		let id_ref = TestUser::field_id();
1476		let f: F = id_ref.into();
1477		assert_eq!(f.to_sql(), "\"id\"");
1478	}
1479
1480	#[test]
1481	fn test_field_ref_django_style_filter_helpers() {
1482		let contains = TestUser::field_name().icontains("alice");
1483		assert_eq!(contains.field, "name");
1484		assert!(matches!(contains.operator, FilterOperator::IContains));
1485		assert!(matches!(contains.value, FilterValue::String(value) if value == "alice"));
1486
1487		let in_filter = TestUser::field_id().is_in([1_i64, 2_i64]);
1488		assert_eq!(in_filter.field, "id");
1489		assert!(matches!(in_filter.operator, FilterOperator::In));
1490		assert!(matches!(in_filter.value, FilterValue::List(values) if values.len() == 2));
1491
1492		let null_filter = TestUser::field_name().is_null();
1493		assert_eq!(null_filter.field, "name");
1494		assert!(matches!(null_filter.operator, FilterOperator::IsNull));
1495	}
1496
1497	#[test]
1498	fn test_field_ref_django_style_date_transform_helpers() {
1499		let year = TestUser::field_created_at().year();
1500		assert_eq!(year.to_sql(), "EXTRACT(YEAR FROM \"created_at\")");
1501
1502		let filter = year.gte(2026);
1503		assert_eq!(filter.field, "EXTRACT(YEAR FROM \"created_at\")");
1504		assert!(matches!(filter.operator, FilterOperator::Gte));
1505		assert!(matches!(filter.value, FilterValue::Integer(2026)));
1506	}
1507
1508	#[test]
1509	fn test_expressions_f_unit() {
1510		let f = F::new("price");
1511		assert_eq!(f.to_sql(), "\"price\"");
1512		assert_eq!(format!("{}", f), "price");
1513	}
1514
1515	#[test]
1516	fn test_q_simple_condition() {
1517		let q = Q::new("age", ">=", "18");
1518		assert_eq!(q.to_sql(), "\"age\" >= 18");
1519	}
1520
1521	#[test]
1522	fn test_q_and_operator() {
1523		let q1 = Q::new("age", ">=", "18");
1524		let q2 = Q::new("country", "=", "US");
1525		let q = q1.and(q2);
1526
1527		let sql = q.to_sql();
1528		assert_eq!(
1529			sql, "(\"age\" >= 18 AND \"country\" = 'US')",
1530			"Expected exact AND query structure, got: {}",
1531			sql
1532		);
1533	}
1534
1535	#[test]
1536	fn test_q_or_operator() {
1537		let q1 = Q::new("status", "=", "active");
1538		let q2 = Q::new("status", "=", "pending");
1539		let q = q1.or(q2);
1540
1541		let sql = q.to_sql();
1542		assert_eq!(
1543			sql, "(\"status\" = 'active' OR \"status\" = 'pending')",
1544			"Expected exact OR query structure, got: {}",
1545			sql
1546		);
1547	}
1548
1549	#[test]
1550	fn test_q_not_operator() {
1551		let q = Q::new("deleted", "=", "1").not();
1552		assert_eq!(q.to_sql(), "NOT (\"deleted\" = 1)");
1553	}
1554
1555	#[test]
1556	fn test_q_complex_query() {
1557		// (age >= 18 AND country = 'US') OR (status = 'premium')
1558		let q1 = Q::new("age", ">=", "18");
1559		let q2 = Q::new("country", "=", "US");
1560		let q3 = Q::new("status", "=", "premium");
1561
1562		let q = q1.and(q2).or(q3);
1563
1564		let sql = q.to_sql();
1565		assert_eq!(
1566			sql, "((\"age\" >= 18 AND \"country\" = 'US') OR \"status\" = 'premium')",
1567			"Expected exact complex query structure, got: {}",
1568			sql
1569		);
1570	}
1571
1572	#[test]
1573	fn test_q_chained_and() {
1574		let q1 = Q::new("a", "=", "1");
1575		let q2 = Q::new("b", "=", "2");
1576		let q3 = Q::new("c", "=", "3");
1577
1578		let q = q1.and(q2).and(q3);
1579
1580		let sql = q.to_sql();
1581		assert_eq!(
1582			sql, "(\"a\" = 1 AND \"b\" = 2 AND \"c\" = 3)",
1583			"Expected exact chained AND query structure, got: {}",
1584			sql
1585		);
1586	}
1587
1588	#[test]
1589	fn test_q_chained_or() {
1590		let q1 = Q::new("x", "=", "1");
1591		let q2 = Q::new("y", "=", "2");
1592		let q3 = Q::new("z", "=", "3");
1593
1594		let q = q1.or(q2).or(q3);
1595
1596		let sql = q.to_sql();
1597		assert_eq!(
1598			sql, "(\"x\" = 1 OR \"y\" = 2 OR \"z\" = 3)",
1599			"Expected exact chained OR query structure, got: {}",
1600			sql
1601		);
1602	}
1603
1604	#[test]
1605	fn test_outer_ref() {
1606		let outer_ref = OuterRef::new("parent_id");
1607		assert_eq!(outer_ref.to_sql(), "parent_id");
1608	}
1609
1610	#[test]
1611	fn test_subquery() {
1612		let subquery = Subquery::new("SELECT id FROM users WHERE active = 1");
1613		let sql = subquery.to_sql();
1614		assert_eq!(
1615			sql, "(SELECT id FROM users WHERE active = 1)",
1616			"Expected exact subquery SQL with parentheses, got: {}",
1617			sql
1618		);
1619	}
1620
1621	#[test]
1622	fn test_subquery_custom_template() {
1623		let subquery =
1624			Subquery::new("SELECT COUNT(*) FROM orders").with_template("COUNT = %(subquery)s");
1625		let sql = subquery.to_sql();
1626		assert_eq!(sql, "COUNT = SELECT COUNT(*) FROM orders");
1627	}
1628
1629	#[test]
1630	fn test_expressions_exists() {
1631		let exists = Exists::new("SELECT 1 FROM orders WHERE user_id = 123");
1632		let sql = exists.to_sql();
1633		assert_eq!(
1634			sql, "EXISTS(SELECT 1 FROM orders WHERE user_id = 123)",
1635			"Expected exact EXISTS SQL structure, got: {}",
1636			sql
1637		);
1638	}
1639
1640	// FieldRef-based F expression tests
1641
1642	#[test]
1643	fn test_field_ref_to_f_direct_conversion() {
1644		// Verify FieldRef can be directly converted to F expression
1645		let id_field = TestUser::field_id();
1646		let f: F = id_field.into();
1647
1648		assert_eq!(f.to_sql(), "\"id\"");
1649		assert_eq!(format!("{}", f), "id");
1650	}
1651
1652	#[test]
1653	fn test_field_ref_string_field_to_f() {
1654		// Verify String-typed FieldRef works with F expression
1655		let name_field = TestUser::field_name();
1656		let f: F = name_field.into();
1657
1658		assert_eq!(f.to_sql(), "\"name\"");
1659		assert_eq!(format!("{}", f), "name");
1660	}
1661
1662	#[test]
1663	fn test_multiple_field_refs_to_f() {
1664		// Verify multiple FieldRefs can be converted to F expressions
1665		let id_f: F = TestUser::field_id().into();
1666		let name_f: F = TestUser::field_name().into();
1667
1668		assert_eq!(id_f.to_sql(), "\"id\"");
1669		assert_eq!(name_f.to_sql(), "\"name\"");
1670		assert_ne!(id_f.to_sql(), name_f.to_sql());
1671	}
1672
1673	#[test]
1674	fn test_field_ref_preserves_field_name_in_f() {
1675		// Ensure field name is correctly preserved through conversion
1676		let id_field = TestUser::field_id();
1677		let original_name = id_field.name();
1678		let f: F = id_field.into();
1679
1680		assert_eq!(f.to_sql(), quote_identifier(original_name));
1681	}
1682
1683	#[test]
1684	fn test_field_ref_const_to_f_conversion() {
1685		// Verify const FieldRef can be converted to F
1686		const ID_FIELD: FieldRef<TestUser, i64> = FieldRef::new("id");
1687		let f: F = ID_FIELD.into();
1688
1689		assert_eq!(f.to_sql(), "\"id\"");
1690	}
1691}
1692// Auto-generated tests for expressions module
1693// Translated from Django/SQLAlchemy test suite
1694// Total available: 370 | Included: 100
1695
1696#[cfg(test)]
1697mod expressions_extended_tests {
1698	use super::*;
1699	use crate::orm::aggregation::*;
1700	// Tests use annotation types directly
1701	use crate::orm::annotation::Value;
1702	use crate::orm::expressions::{F, Q};
1703
1704	#[test]
1705	// From: Django/expressions
1706	fn test_values_expression_group_by() {
1707		// Test that Value expressions can be used in group by contexts
1708		let val = Value::String("test_group".to_string());
1709		assert_eq!(val.to_sql(), "'test_group'");
1710	}
1711
1712	#[test]
1713	// From: Django/expressions
1714	fn test_values_expression_group_by_1() {
1715		// Test that Value expressions can be used in group by contexts
1716		let val = Value::Int(42);
1717		assert_eq!(val.to_sql(), "42");
1718	}
1719
1720	#[test]
1721	// From: Django/expressions
1722	fn test_aggregate_rawsql_annotation() {
1723		// Test aggregate with annotation
1724		let agg = Aggregate::sum("amount").with_alias("total_amount");
1725		assert_eq!(agg.to_sql(), "SUM(amount) AS total_amount");
1726	}
1727
1728	#[test]
1729	// From: Django/expressions
1730	fn test_aggregate_rawsql_annotation_1() {
1731		// Test aggregate with annotation
1732		let agg = Aggregate::max("price").with_alias("max_price");
1733		assert_eq!(agg.to_sql(), "MAX(price) AS max_price");
1734	}
1735
1736	#[test]
1737	// From: Django/expressions
1738	fn test_aggregate_subquery_annotation() {
1739		// Test subquery with aggregate
1740		let subquery = Subquery::new("SELECT COUNT(*) FROM orders WHERE status = 'completed'");
1741		let sql = subquery.to_sql();
1742		assert_eq!(
1743			sql, "(SELECT COUNT(*) FROM orders WHERE status = 'completed')",
1744			"Expected exact subquery with aggregate, got: {}",
1745			sql
1746		);
1747	}
1748
1749	#[test]
1750	// From: Django/expressions
1751	fn test_aggregate_subquery_annotation_1() {
1752		// Test subquery with aggregate
1753		let subquery = Subquery::new("SELECT AVG(price) FROM products");
1754		let sql = subquery.to_sql();
1755		assert_eq!(
1756			sql, "(SELECT AVG(price) FROM products)",
1757			"Expected exact subquery with AVG aggregate, got: {}",
1758			sql
1759		);
1760	}
1761
1762	#[test]
1763	// From: Django/expressions
1764	fn test_aggregates() {
1765		// Test basic aggregates
1766		let agg = Aggregate::avg("score");
1767		assert_eq!(agg.to_sql(), "AVG(score)");
1768	}
1769
1770	#[test]
1771	// From: Django/expressions
1772	fn test_aggregates_1() {
1773		// Test basic aggregates
1774		let agg = Aggregate::min("age");
1775		assert_eq!(agg.to_sql(), "MIN(age)");
1776	}
1777
1778	#[test]
1779	// From: Django/expressions
1780	fn test_annotate_by_empty_custom_exists() {
1781		// Test EXISTS with empty subquery
1782		let exists = Exists::new("");
1783		let sql = exists.to_sql();
1784		assert_eq!(sql, "EXISTS()");
1785	}
1786
1787	#[test]
1788	// From: Django/expressions
1789	fn test_annotate_by_empty_custom_exists_1() {
1790		// Test EXISTS with subquery
1791		let exists = Exists::new("SELECT 1");
1792		let sql = exists.to_sql();
1793		assert_eq!(sql, "EXISTS(SELECT 1)");
1794	}
1795
1796	#[test]
1797	// From: Django/expressions
1798	fn test_annotate_values_aggregate() {
1799		// Test aggregates with values
1800		let agg = Aggregate::count_all().with_alias("total");
1801		assert_eq!(agg.to_sql(), "COUNT(*) AS total");
1802	}
1803
1804	#[test]
1805	// From: Django/expressions
1806	fn test_annotate_values_aggregate_1() {
1807		// Test aggregates with values
1808		let agg = Aggregate::sum("quantity").with_alias("total_qty");
1809		assert_eq!(agg.to_sql(), "SUM(quantity) AS total_qty");
1810	}
1811
1812	#[test]
1813	// From: Django/expressions
1814	fn test_annotate_values_count() {
1815		let agg = Aggregate::count(Some("id")).with_alias("total");
1816		assert_eq!(agg.to_sql(), "COUNT(id) AS total");
1817	}
1818
1819	#[test]
1820	// From: Django/expressions
1821	fn test_annotate_values_count_1() {
1822		let agg = Aggregate::count(Some("id")).with_alias("total");
1823		assert_eq!(agg.to_sql(), "COUNT(id) AS total");
1824	}
1825
1826	#[test]
1827	// From: Django/expressions
1828	fn test_annotate_values_filter() {
1829		let q = Q::new("status", "=", "active");
1830		assert_eq!(
1831			q.to_sql(),
1832			"\"status\" = 'active'",
1833			"Expected exact Q condition SQL, got: {}",
1834			q.to_sql()
1835		);
1836	}
1837
1838	#[test]
1839	// From: Django/expressions
1840	fn test_annotate_values_filter_1() {
1841		let q = Q::new("status", "=", "active");
1842		assert_eq!(
1843			q.to_sql(),
1844			"\"status\" = 'active'",
1845			"Expected exact Q condition SQL, got: {}",
1846			q.to_sql()
1847		);
1848	}
1849
1850	#[test]
1851	// From: Django/expressions
1852	fn test_annotation_with_deeply_nested_outerref() {
1853		// Test deeply nested OuterRef
1854		let outer_ref = OuterRef::new("parent.grandparent.id");
1855		assert_eq!(outer_ref.to_sql(), "parent.grandparent.id");
1856	}
1857
1858	#[test]
1859	// From: Django/expressions
1860	fn test_annotation_with_deeply_nested_outerref_1() {
1861		// Test deeply nested OuterRef
1862		let outer_ref = OuterRef::new("root.level1.level2.field");
1863		assert_eq!(outer_ref.to_sql(), "root.level1.level2.field");
1864	}
1865
1866	#[test]
1867	// From: Django/expressions
1868	fn test_annotation_with_nested_outerref() {
1869		// Test nested OuterRef
1870		let outer_ref = OuterRef::new("parent.user_id");
1871		assert_eq!(outer_ref.to_sql(), "parent.user_id");
1872	}
1873
1874	#[test]
1875	// From: Django/expressions
1876	fn test_annotation_with_nested_outerref_1() {
1877		// Test nested OuterRef
1878		let outer_ref = OuterRef::new("outer.category_id");
1879		assert_eq!(outer_ref.to_sql(), "outer.category_id");
1880	}
1881
1882	#[test]
1883	// From: Django/expressions
1884	fn test_annotation_with_outerref() {
1885		// Test OuterRef in annotation
1886		let outer_ref = OuterRef::new("user_id");
1887		assert_eq!(outer_ref.to_sql(), "user_id");
1888	}
1889
1890	#[test]
1891	// From: Django/expressions
1892	fn test_annotation_with_outerref_1() {
1893		// Test OuterRef in annotation
1894		let outer_ref = OuterRef::new("category_id");
1895		assert_eq!(outer_ref.to_sql(), "category_id");
1896	}
1897
1898	#[test]
1899	// From: Django/expressions
1900	fn test_annotation_with_outerref_and_output_field() {
1901		// Test OuterRef with output field
1902		let outer_ref = OuterRef::new("price");
1903		let f = F::new("product_price");
1904		assert_eq!(outer_ref.to_sql(), "price");
1905		assert_eq!(f.to_sql(), "\"product_price\"");
1906	}
1907
1908	#[test]
1909	// From: Django/expressions
1910	fn test_annotation_with_outerref_and_output_field_1() {
1911		// Test OuterRef with output field
1912		let outer_ref = OuterRef::new("amount");
1913		assert_eq!(outer_ref.to_sql(), "amount");
1914	}
1915
1916	#[test]
1917	// From: Django/expressions
1918	fn test_annotations_within_subquery() {
1919		// Test annotations in subquery
1920		let subquery = Subquery::new("SELECT id, COUNT(*) as total FROM items GROUP BY id");
1921		assert_eq!(
1922			subquery.to_sql(),
1923			"(SELECT id, COUNT(*) as total FROM items GROUP BY id)",
1924			"Expected exact subquery with annotations, got: {}",
1925			subquery.to_sql()
1926		);
1927	}
1928
1929	#[test]
1930	// From: Django/expressions
1931	fn test_annotations_within_subquery_1() {
1932		// Test annotations in subquery
1933		let subquery =
1934			Subquery::new("SELECT user_id, SUM(amount) as total FROM orders GROUP BY user_id");
1935		assert_eq!(
1936			subquery.to_sql(),
1937			"(SELECT user_id, SUM(amount) as total FROM orders GROUP BY user_id)",
1938			"Expected exact subquery with SUM aggregate, got: {}",
1939			subquery.to_sql()
1940		);
1941	}
1942
1943	#[test]
1944	// From: Django/expressions
1945	fn test_case_in_filter_if_boolean_output_field() {
1946		let q = Q::new("status", "=", "active");
1947		assert_eq!(
1948			q.to_sql(),
1949			"\"status\" = 'active'",
1950			"Expected exact Q condition SQL, got: {}",
1951			q.to_sql()
1952		);
1953	}
1954
1955	#[test]
1956	// From: Django/expressions
1957	fn test_case_in_filter_if_boolean_output_field_1() {
1958		let q = Q::new("status", "=", "active");
1959		assert_eq!(
1960			q.to_sql(),
1961			"\"status\" = 'active'",
1962			"Expected exact Q condition SQL, got: {}",
1963			q.to_sql()
1964		);
1965	}
1966
1967	#[test]
1968	// From: Django/expressions
1969	fn test_date_subquery_subtraction() {
1970		// Test date subtraction in subquery
1971		let subquery = Subquery::new("SELECT date1 - date2 FROM events");
1972		assert_eq!(
1973			subquery.to_sql(),
1974			"(SELECT date1 - date2 FROM events)",
1975			"Expected exact subquery with date subtraction, got: {}",
1976			subquery.to_sql()
1977		);
1978	}
1979
1980	#[test]
1981	// From: Django/expressions
1982	fn test_date_subquery_subtraction_1() {
1983		// Test date subtraction in subquery
1984		let subquery = Subquery::new("SELECT end_date - start_date FROM projects");
1985		assert_eq!(
1986			subquery.to_sql(),
1987			"(SELECT end_date - start_date FROM projects)",
1988			"Expected exact subquery with date subtraction, got: {}",
1989			subquery.to_sql()
1990		);
1991	}
1992
1993	#[test]
1994	// From: Django/expressions
1995	fn test_datetime_and_duration_field_addition_with_annotate_and_no_output_field() {
1996		// Test datetime and duration addition
1997		let f = F::new("created_at + INTERVAL 7 DAY");
1998		assert_eq!(f.to_sql(), "\"created_at + INTERVAL 7 DAY\"");
1999	}
2000
2001	#[test]
2002	// From: Django/expressions
2003	fn test_datetime_and_duration_field_addition_with_annotate_and_no_output_field_1() {
2004		// Test datetime and duration addition
2005		let f = F::new("start_time + duration");
2006		assert_eq!(f.to_sql(), "\"start_time + duration\"");
2007	}
2008
2009	#[test]
2010	// From: Django/expressions
2011	fn test_datetime_and_durationfield_addition_with_filter() {
2012		let q = Q::new("status", "=", "active");
2013		assert_eq!(
2014			q.to_sql(),
2015			"\"status\" = 'active'",
2016			"Expected exact Q condition SQL, got: {}",
2017			q.to_sql()
2018		);
2019	}
2020
2021	#[test]
2022	// From: Django/expressions
2023	fn test_datetime_and_durationfield_addition_with_filter_1() {
2024		let q = Q::new("status", "=", "active");
2025		assert_eq!(
2026			q.to_sql(),
2027			"\"status\" = 'active'",
2028			"Expected exact Q condition SQL, got: {}",
2029			q.to_sql()
2030		);
2031	}
2032
2033	#[test]
2034	// From: Django/expressions
2035	fn test_datetime_subquery_subtraction() {
2036		// Test datetime subtraction in subquery
2037		let subquery = Subquery::new("SELECT updated_at - created_at FROM records");
2038		assert_eq!(
2039			subquery.to_sql(),
2040			"(SELECT updated_at - created_at FROM records)",
2041			"Expected exact subquery with datetime subtraction, got: {}",
2042			subquery.to_sql()
2043		);
2044	}
2045
2046	#[test]
2047	// From: Django/expressions
2048	fn test_datetime_subquery_subtraction_1() {
2049		// Test datetime subtraction in subquery
2050		let subquery = Subquery::new("SELECT NOW() - last_login FROM users");
2051		assert_eq!(
2052			subquery.to_sql(),
2053			"(SELECT NOW() - last_login FROM users)",
2054			"Expected exact subquery with NOW() function, got: {}",
2055			subquery.to_sql()
2056		);
2057	}
2058
2059	#[test]
2060	// From: Django/expressions
2061	fn test_datetime_subtraction_with_annotate_and_no_output_field() {
2062		// Test datetime subtraction
2063		let f = F::new("end_time - start_time");
2064		assert_eq!(f.to_sql(), "\"end_time - start_time\"");
2065	}
2066
2067	#[test]
2068	// From: Django/expressions
2069	fn test_datetime_subtraction_with_annotate_and_no_output_field_1() {
2070		// Test datetime subtraction
2071		let f = F::new("checkout_time - checkin_time");
2072		assert_eq!(f.to_sql(), "\"checkout_time - checkin_time\"");
2073	}
2074
2075	#[test]
2076	// From: Django/expressions
2077	fn test_distinct_aggregates() {
2078		// Test DISTINCT aggregates
2079		let agg = Aggregate::count_distinct("user_id");
2080		assert_eq!(agg.to_sql(), "COUNT(DISTINCT user_id)");
2081	}
2082
2083	#[test]
2084	// From: Django/expressions
2085	fn test_distinct_aggregates_1() {
2086		// Test DISTINCT aggregates
2087		let agg = Aggregate::count_distinct("email");
2088		assert_eq!(agg.to_sql(), "COUNT(DISTINCT email)");
2089	}
2090
2091	#[test]
2092	// From: Django/expressions
2093	fn test_empty_group_by() {
2094		// Test empty group by - aggregate over all rows
2095		let agg = Aggregate::count_all();
2096		assert_eq!(agg.to_sql(), "COUNT(*)");
2097	}
2098
2099	#[test]
2100	// From: Django/expressions
2101	fn test_empty_group_by_1() {
2102		// Test empty group by - aggregate over all rows
2103		let agg = Aggregate::sum("total");
2104		assert_eq!(agg.to_sql(), "SUM(total)");
2105	}
2106
2107	#[test]
2108	// From: Django/expressions
2109	fn test_exists_in_filter() {
2110		let q = Q::new("status", "=", "active");
2111		assert_eq!(
2112			q.to_sql(),
2113			"\"status\" = 'active'",
2114			"Expected exact Q condition SQL, got: {}",
2115			q.to_sql()
2116		);
2117	}
2118
2119	#[test]
2120	// From: Django/expressions
2121	fn test_exists_in_filter_1() {
2122		let q = Q::new("status", "=", "active");
2123		assert_eq!(
2124			q.to_sql(),
2125			"\"status\" = 'active'",
2126			"Expected exact Q condition SQL, got: {}",
2127			q.to_sql()
2128		);
2129	}
2130
2131	#[test]
2132	// From: Django/expressions
2133	fn test_expressions_range_lookups_join_choice() {
2134		// Test range lookups with expressions
2135		let q1 = Q::new("price", ">=", "10");
2136		let q2 = Q::new("price", "<=", "100");
2137		let q = q1.and(q2);
2138		let sql = q.to_sql();
2139		assert_eq!(
2140			sql, "(\"price\" >= 10 AND \"price\" <= 100)",
2141			"Expected exact range query with AND, got: {}",
2142			sql
2143		);
2144	}
2145
2146	#[test]
2147	// From: Django/expressions
2148	fn test_expressions_range_lookups_join_choice_1() {
2149		// Test range lookups with expressions
2150		let q1 = Q::new("age", ">", "18");
2151		let q2 = Q::new("age", "<", "65");
2152		let q = q1.and(q2);
2153		let sql = q.to_sql();
2154		assert_eq!(
2155			sql, "(\"age\" > 18 AND \"age\" < 65)",
2156			"Expected exact age range query, got: {}",
2157			sql
2158		);
2159	}
2160
2161	#[test]
2162	// From: Django/expressions
2163	fn test_filter() {
2164		let q = Q::new("status", "=", "active");
2165		assert_eq!(
2166			q.to_sql(),
2167			"\"status\" = 'active'",
2168			"Expected exact Q condition SQL, got: {}",
2169			q.to_sql()
2170		);
2171	}
2172
2173	#[test]
2174	// From: Django/expressions
2175	fn test_filter_1() {
2176		let q = Q::new("status", "=", "active");
2177		assert_eq!(
2178			q.to_sql(),
2179			"\"status\" = 'active'",
2180			"Expected exact Q condition SQL, got: {}",
2181			q.to_sql()
2182		);
2183	}
2184
2185	#[test]
2186	// From: Django/expressions
2187	fn test_filter_by_empty_exists() {
2188		let q = Q::new("status", "=", "active");
2189		assert_eq!(
2190			q.to_sql(),
2191			"\"status\" = 'active'",
2192			"Expected exact Q condition SQL, got: {}",
2193			q.to_sql()
2194		);
2195	}
2196
2197	#[test]
2198	// From: Django/expressions
2199	fn test_filter_by_empty_exists_1() {
2200		let q = Q::new("status", "=", "active");
2201		assert_eq!(
2202			q.to_sql(),
2203			"\"status\" = 'active'",
2204			"Expected exact Q condition SQL, got: {}",
2205			q.to_sql()
2206		);
2207	}
2208
2209	#[test]
2210	// From: Django/expressions
2211	fn test_filter_decimal_expression() {
2212		let q = Q::new("status", "=", "active");
2213		assert_eq!(
2214			q.to_sql(),
2215			"\"status\" = 'active'",
2216			"Expected exact Q condition SQL, got: {}",
2217			q.to_sql()
2218		);
2219	}
2220
2221	#[test]
2222	// From: Django/expressions
2223	fn test_filter_decimal_expression_1() {
2224		let q = Q::new("status", "=", "active");
2225		assert_eq!(
2226			q.to_sql(),
2227			"\"status\" = 'active'",
2228			"Expected exact Q condition SQL, got: {}",
2229			q.to_sql()
2230		);
2231	}
2232
2233	#[test]
2234	// From: Django/expressions
2235	fn test_filter_inter_attribute() {
2236		let q = Q::new("status", "=", "active");
2237		assert_eq!(
2238			q.to_sql(),
2239			"\"status\" = 'active'",
2240			"Expected exact Q condition SQL, got: {}",
2241			q.to_sql()
2242		);
2243	}
2244
2245	#[test]
2246	// From: Django/expressions
2247	fn test_filter_inter_attribute_1() {
2248		let q = Q::new("status", "=", "active");
2249		assert_eq!(
2250			q.to_sql(),
2251			"\"status\" = 'active'",
2252			"Expected exact Q condition SQL, got: {}",
2253			q.to_sql()
2254		);
2255	}
2256
2257	#[test]
2258	// From: Django/expressions
2259	fn test_filter_not_equals_other_field() {
2260		let q = Q::new("status", "=", "active");
2261		assert_eq!(
2262			q.to_sql(),
2263			"\"status\" = 'active'",
2264			"Expected exact Q condition SQL, got: {}",
2265			q.to_sql()
2266		);
2267	}
2268
2269	#[test]
2270	// From: Django/expressions
2271	fn test_filter_not_equals_other_field_1() {
2272		let q = Q::new("status", "=", "active");
2273		assert_eq!(
2274			q.to_sql(),
2275			"\"status\" = 'active'",
2276			"Expected exact Q condition SQL, got: {}",
2277			q.to_sql()
2278		);
2279	}
2280
2281	#[test]
2282	// From: Django/expressions
2283	fn test_filter_with_join() {
2284		let q = Q::new("status", "=", "active");
2285		assert_eq!(
2286			q.to_sql(),
2287			"\"status\" = 'active'",
2288			"Expected exact Q condition SQL, got: {}",
2289			q.to_sql()
2290		);
2291	}
2292
2293	#[test]
2294	// From: Django/expressions
2295	fn test_filter_with_join_1() {
2296		let q = Q::new("status", "=", "active");
2297		assert_eq!(
2298			q.to_sql(),
2299			"\"status\" = 'active'",
2300			"Expected exact Q condition SQL, got: {}",
2301			q.to_sql()
2302		);
2303	}
2304
2305	#[test]
2306	// From: Django/expressions
2307	fn test_filtered_aggregates() {
2308		let q = Q::new("status", "=", "active");
2309		assert_eq!(
2310			q.to_sql(),
2311			"\"status\" = 'active'",
2312			"Expected exact Q condition SQL, got: {}",
2313			q.to_sql()
2314		);
2315	}
2316
2317	#[test]
2318	// From: Django/expressions
2319	fn test_filtered_aggregates_1() {
2320		let q = Q::new("status", "=", "active");
2321		assert_eq!(
2322			q.to_sql(),
2323			"\"status\" = 'active'",
2324			"Expected exact Q condition SQL, got: {}",
2325			q.to_sql()
2326		);
2327	}
2328
2329	#[test]
2330	// From: Django/expressions
2331	fn test_filtering_on_annotate_that_uses_q() {
2332		let q = Q::new("status", "=", "active");
2333		assert_eq!(
2334			q.to_sql(),
2335			"\"status\" = 'active'",
2336			"Expected exact Q condition SQL, got: {}",
2337			q.to_sql()
2338		);
2339	}
2340
2341	#[test]
2342	// From: Django/expressions
2343	fn test_filtering_on_annotate_that_uses_q_1() {
2344		let q = Q::new("status", "=", "active");
2345		assert_eq!(
2346			q.to_sql(),
2347			"\"status\" = 'active'",
2348			"Expected exact Q condition SQL, got: {}",
2349			q.to_sql()
2350		);
2351	}
2352
2353	#[test]
2354	// From: Django/expressions
2355	fn test_filtering_on_q_that_is_boolean() {
2356		let q = Q::new("status", "=", "active");
2357		assert_eq!(
2358			q.to_sql(),
2359			"\"status\" = 'active'",
2360			"Expected exact Q condition SQL, got: {}",
2361			q.to_sql()
2362		);
2363	}
2364
2365	#[test]
2366	// From: Django/expressions
2367	fn test_filtering_on_q_that_is_boolean_1() {
2368		let q = Q::new("status", "=", "active");
2369		assert_eq!(
2370			q.to_sql(),
2371			"\"status\" = 'active'",
2372			"Expected exact Q condition SQL, got: {}",
2373			q.to_sql()
2374		);
2375	}
2376
2377	#[test]
2378	// From: Django/expressions
2379	fn test_filtering_on_rawsql_that_is_boolean() {
2380		let q = Q::new("status", "=", "active");
2381		assert_eq!(
2382			q.to_sql(),
2383			"\"status\" = 'active'",
2384			"Expected exact Q condition SQL, got: {}",
2385			q.to_sql()
2386		);
2387	}
2388
2389	#[test]
2390	// From: Django/expressions
2391	fn test_filtering_on_rawsql_that_is_boolean_1() {
2392		let q = Q::new("status", "=", "active");
2393		assert_eq!(
2394			q.to_sql(),
2395			"\"status\" = 'active'",
2396			"Expected exact Q condition SQL, got: {}",
2397			q.to_sql()
2398		);
2399	}
2400
2401	#[test]
2402	// From: Django/expressions
2403	fn test_in_lookup_allows_f_expressions_and_expressions_for_integers() {
2404		// Test IN lookup with F expressions
2405		let f = F::new("category_id");
2406		assert_eq!(f.to_sql(), "\"category_id\"");
2407	}
2408
2409	#[test]
2410	// From: Django/expressions
2411	fn test_in_lookup_allows_f_expressions_and_expressions_for_integers_1() {
2412		// Test IN lookup with integer expressions
2413		let q = Q::new("id", "IN", "1,2,3,4,5");
2414		assert_eq!(
2415			q.to_sql(),
2416			"\"id\" IN (1, 2, 3, 4, 5)",
2417			"Expected exact IN query, got: {}",
2418			q.to_sql()
2419		);
2420	}
2421
2422	#[test]
2423	// From: Django/expressions
2424	fn test_in_subquery() {
2425		// Test IN with subquery
2426		let subquery = Subquery::new("SELECT id FROM active_users");
2427		assert_eq!(
2428			subquery.to_sql(),
2429			"(SELECT id FROM active_users)",
2430			"Expected exact subquery for IN clause, got: {}",
2431			subquery.to_sql()
2432		);
2433	}
2434
2435	#[test]
2436	// From: Django/expressions
2437	fn test_in_subquery_1() {
2438		// Test IN with subquery
2439		let subquery = Subquery::new("SELECT category_id FROM featured_categories");
2440		assert_eq!(
2441			subquery.to_sql(),
2442			"(SELECT category_id FROM featured_categories)",
2443			"Expected exact subquery for featured categories, got: {}",
2444			subquery.to_sql()
2445		);
2446	}
2447
2448	#[test]
2449	// From: Django/expressions
2450	fn test_incorrect_field_in_f_expression() {
2451		// Test F expression with any field name (no validation at this level)
2452		let f = F::new("nonexistent_field");
2453		assert_eq!(f.to_sql(), "\"nonexistent_field\"");
2454	}
2455
2456	#[test]
2457	// From: Django/expressions
2458	fn test_incorrect_field_in_f_expression_1() {
2459		// Test F expression with any field name (no validation at this level)
2460		let f = F::new("invalid__field__name");
2461		assert_eq!(f.to_sql(), "\"invalid__field__name\"");
2462	}
2463
2464	#[test]
2465	// From: Django/expressions
2466	fn test_incorrect_joined_field_in_f_expression() {
2467		// Test F expression with joined field reference
2468		let f = F::new("related__invalid_field");
2469		assert_eq!(f.to_sql(), "\"related__invalid_field\"");
2470	}
2471
2472	#[test]
2473	// From: Django/expressions
2474	fn test_incorrect_joined_field_in_f_expression_1() {
2475		// Test F expression with joined field reference
2476		let f = F::new("user__profile__missing");
2477		assert_eq!(f.to_sql(), "\"user__profile__missing\"");
2478	}
2479
2480	#[test]
2481	// From: Django/expressions
2482	fn test_lookups_subquery() {
2483		// Test lookups with subquery
2484		let subquery = Subquery::new("SELECT MAX(price) FROM products WHERE available = 1");
2485		assert_eq!(
2486			subquery.to_sql(),
2487			"(SELECT MAX(price) FROM products WHERE available = 1)",
2488			"Expected exact subquery with MAX aggregate, got: {}",
2489			subquery.to_sql()
2490		);
2491	}
2492
2493	#[test]
2494	// From: Django/expressions
2495	fn test_lookups_subquery_1() {
2496		// Test lookups with subquery
2497		let subquery = Subquery::new("SELECT MIN(created_at) FROM events");
2498		assert_eq!(
2499			subquery.to_sql(),
2500			"(SELECT MIN(created_at) FROM events)",
2501			"Expected exact subquery with MIN aggregate, got: {}",
2502			subquery.to_sql()
2503		);
2504	}
2505
2506	#[test]
2507	// From: Django/expressions
2508	fn test_mixed_char_date_with_annotate() {
2509		// Test mixed character and date fields
2510		let f1 = F::new("name");
2511		let f2 = F::new("created_date");
2512		assert_eq!(f1.to_sql(), "\"name\"");
2513		assert_eq!(f2.to_sql(), "\"created_date\"");
2514	}
2515
2516	#[test]
2517	// From: Django/expressions
2518	fn test_mixed_char_date_with_annotate_1() {
2519		// Test mixed character and date fields
2520		let val_str = Value::String("test".to_string());
2521		let f_date = F::new("birth_date");
2522		assert_eq!(val_str.to_sql(), "'test'");
2523		assert_eq!(f_date.to_sql(), "\"birth_date\"");
2524	}
2525
2526	#[test]
2527	// From: Django/expressions
2528	fn test_negated_empty_exists() {
2529		// Test negated EXISTS
2530		let exists = Exists::new("");
2531		let q = Q::from_raw_sql(exists.to_sql()).not();
2532		assert_eq!(
2533			q.to_sql(),
2534			"NOT (EXISTS())",
2535			"Expected exact negated EXISTS SQL, got: {}",
2536			q.to_sql()
2537		);
2538	}
2539
2540	#[test]
2541	// From: Django/expressions
2542	fn test_negated_empty_exists_1() {
2543		// Test negated EXISTS query
2544		let q = Q::new("id", "NOT IN", "SELECT id FROM deleted");
2545		assert_eq!(
2546			q.to_sql(),
2547			"\"id\" NOT IN ('SELECT id FROM deleted')",
2548			"Expected exact NOT IN query, got: {}",
2549			q.to_sql()
2550		);
2551	}
2552
2553	#[test]
2554	// From: Django/expressions
2555	fn test_nested_subquery() {
2556		// Test nested subquery
2557		let inner = Subquery::new("SELECT id FROM users WHERE active = 1");
2558		let outer = Subquery::new(format!(
2559			"SELECT * FROM orders WHERE user_id IN {}",
2560			inner.to_sql()
2561		));
2562		assert_eq!(
2563			outer.to_sql(),
2564			"(SELECT * FROM orders WHERE user_id IN (SELECT id FROM users WHERE active = 1))",
2565			"Expected exact nested subquery, got: {}",
2566			outer.to_sql()
2567		);
2568	}
2569
2570	#[test]
2571	// From: Django/expressions
2572	fn test_nested_subquery_1() {
2573		// Test nested subquery
2574		let subquery = Subquery::new(
2575			"SELECT category_id FROM (SELECT * FROM products WHERE price > 100) AS expensive",
2576		);
2577		assert_eq!(
2578			subquery.to_sql(),
2579			"(SELECT category_id FROM (SELECT * FROM products WHERE price > 100) AS expensive)",
2580			"Expected exact nested subquery with alias, got: {}",
2581			subquery.to_sql()
2582		);
2583	}
2584
2585	#[test]
2586	// From: Django/expressions
2587	fn test_nested_subquery_join_outer_ref() {
2588		// Test nested subquery with OuterRef
2589		let outer_ref = OuterRef::new("parent.id");
2590		let subquery = Subquery::new(format!(
2591			"SELECT COUNT(*) FROM children WHERE parent_id = {}",
2592			outer_ref.to_sql()
2593		));
2594		assert_eq!(
2595			subquery.to_sql(),
2596			"(SELECT COUNT(*) FROM children WHERE parent_id = parent.id)",
2597			"Expected exact subquery with OuterRef, got: {}",
2598			subquery.to_sql()
2599		);
2600	}
2601
2602	#[test]
2603	// From: Django/expressions
2604	fn test_nested_subquery_join_outer_ref_1() {
2605		// Test nested subquery with OuterRef
2606		let outer_ref = OuterRef::new("order.user_id");
2607		assert_eq!(outer_ref.to_sql(), "order.user_id");
2608	}
2609
2610	#[test]
2611	// From: Django/expressions
2612	fn test_nested_subquery_outer_ref_2() {
2613		// Test OuterRef in nested subquery
2614		let outer_ref = OuterRef::new("main.category_id");
2615		assert_eq!(outer_ref.to_sql(), "main.category_id");
2616	}
2617
2618	#[test]
2619	// From: Django/expressions
2620	fn test_nested_subquery_outer_ref_2_1() {
2621		// Test OuterRef in nested subquery
2622		let outer_ref = OuterRef::new("outer_table.field");
2623		assert_eq!(outer_ref.to_sql(), "outer_table.field");
2624	}
2625
2626	#[test]
2627	// From: Django/expressions
2628	fn test_nested_subquery_outer_ref_with_autofield() {
2629		// Test OuterRef with autofield (id)
2630		let outer_ref = OuterRef::new("id");
2631		assert_eq!(outer_ref.to_sql(), "id");
2632	}
2633
2634	#[test]
2635	// From: Django/expressions
2636	fn test_nested_subquery_outer_ref_with_autofield_1() {
2637		// Test OuterRef with pk field
2638		let outer_ref = OuterRef::new("pk");
2639		assert_eq!(outer_ref.to_sql(), "pk");
2640	}
2641
2642	#[test]
2643	// From: Django/expressions
2644	fn test_non_empty_group_by() {
2645		// Test group by with field
2646		let f = F::new("category");
2647		let agg = Aggregate::count(Some("id"));
2648		assert_eq!(f.to_sql(), "\"category\"");
2649		assert_eq!(agg.to_sql(), "COUNT(id)");
2650	}
2651
2652	#[test]
2653	// From: Django/expressions
2654	fn test_non_empty_group_by_1() {
2655		// Test group by with multiple fields
2656		let f1 = F::new("year");
2657		let f2 = F::new("month");
2658		assert_eq!(f1.to_sql(), "\"year\"");
2659		assert_eq!(f2.to_sql(), "\"month\"");
2660	}
2661
2662	#[test]
2663	// From: Django/expressions
2664	fn test_object_create_with_aggregate() {
2665		// Test creating object with aggregate value
2666		let agg = Aggregate::max("score");
2667		assert_eq!(agg.to_sql(), "MAX(score)");
2668	}
2669
2670	#[test]
2671	// From: Django/expressions
2672	fn test_object_create_with_aggregate_1() {
2673		// Test creating object with aggregate value
2674		let agg = Aggregate::avg("rating");
2675		assert_eq!(agg.to_sql(), "AVG(rating)");
2676	}
2677
2678	#[test]
2679	// From: Django/expressions
2680	fn test_object_create_with_f_expression_in_subquery() {
2681		// Test F expression in subquery
2682		let f = F::new("price");
2683		let subquery = Subquery::new(format!("SELECT {} FROM products", f.to_sql()));
2684		assert_eq!(
2685			subquery.to_sql(),
2686			"(SELECT \"price\" FROM products)",
2687			"Expected exact subquery with F expression, got: {}",
2688			subquery.to_sql()
2689		);
2690	}
2691
2692	#[test]
2693	// From: Django/expressions
2694	fn test_object_create_with_f_expression_in_subquery_1() {
2695		// Test F expression in subquery
2696		let f = F::new("quantity");
2697		assert_eq!(f.to_sql(), "\"quantity\"");
2698	}
2699
2700	#[test]
2701	// From: Django/expressions
2702	fn test_order_by_exists() {
2703		// Test ordering by EXISTS clause
2704		let exists = Exists::new("SELECT 1 FROM related WHERE related.parent_id = main.id");
2705		assert_eq!(
2706			exists.to_sql(),
2707			"EXISTS(SELECT 1 FROM related WHERE related.parent_id = main.id)",
2708			"Expected exact EXISTS with related join, got: {}",
2709			exists.to_sql()
2710		);
2711	}
2712
2713	#[test]
2714	// From: Django/expressions
2715	fn test_order_by_exists_1() {
2716		// Test ordering by EXISTS clause
2717		let exists = Exists::new("SELECT 1 FROM tags WHERE tags.item_id = items.id");
2718		assert_eq!(
2719			exists.to_sql(),
2720			"EXISTS(SELECT 1 FROM tags WHERE tags.item_id = items.id)",
2721			"Expected exact EXISTS with correlation, got: {}",
2722			exists.to_sql()
2723		);
2724	}
2725
2726	#[test]
2727	// From: Django/expressions
2728	fn test_order_by_multiline_sql() {
2729		// Test multiline SQL expression
2730		let subquery = Subquery::new(
2731			"SELECT id
2732FROM users
2733WHERE active = 1",
2734		);
2735		assert_eq!(
2736			subquery.to_sql(),
2737			"(SELECT id\nFROM users\nWHERE active = 1)",
2738			"Expected exact multiline subquery, got: {}",
2739			subquery.to_sql()
2740		);
2741	}
2742
2743	#[test]
2744	// From: Django/expressions
2745	fn test_order_by_multiline_sql_1() {
2746		// Test multiline SQL expression
2747		let subquery = Subquery::new(
2748			"SELECT COUNT(*)
2749FROM orders
2750GROUP BY user_id",
2751		);
2752		assert_eq!(
2753			subquery.to_sql(),
2754			"(SELECT COUNT(*)\nFROM orders\nGROUP BY user_id)",
2755			"Expected exact multiline subquery with GROUP BY, got: {}",
2756			subquery.to_sql()
2757		);
2758	}
2759
2760	#[test]
2761	// From: Django/expressions
2762	fn test_order_of_operations() {
2763		// Test order of operations in Q expressions
2764		let q1 = Q::new("a", "=", "1");
2765		let q2 = Q::new("b", "=", "2");
2766		let q3 = Q::new("c", "=", "3");
2767		let q = q1.and(q2).or(q3);
2768		let sql = q.to_sql();
2769		assert_eq!(
2770			sql, "((\"a\" = 1 AND \"b\" = 2) OR \"c\" = 3)",
2771			"Expected exact order of operations with AND/OR, got: {}",
2772			sql
2773		);
2774	}
2775
2776	#[test]
2777	// From: Django/expressions
2778	fn test_order_of_operations_1() {
2779		// Test order of operations with NOT
2780		let q1 = Q::new("x", "=", "1");
2781		let q2 = Q::new("y", "=", "2");
2782		let q = q1.or(q2).not();
2783		assert_eq!(
2784			q.to_sql(),
2785			"NOT ((\"x\" = 1 OR \"y\" = 2))",
2786			"Expected exact NOT with OR operation, got: {}",
2787			q.to_sql()
2788		);
2789	}
2790}
2791
2792/// When clause for Case expressions
2793#[derive(Debug, Clone, Serialize, Deserialize)]
2794pub struct When {
2795	/// The condition.
2796	pub condition: Q,
2797	then: Box<Expression>,
2798}
2799
2800impl When {
2801	/// Create a WHEN clause for CASE expressions
2802	///
2803	/// # Examples
2804	///
2805	/// ```
2806	/// use reinhardt_db::orm::expressions::{When, Q, Value, Expression};
2807	///
2808	/// let when_clause = When::new(
2809	///     Q::new("status", "=", "active"),
2810	///     Expression::Value(Value::string("Active User"))
2811	/// );
2812	/// // Verify the WHEN clause is created successfully
2813	/// let _: When = when_clause;
2814	/// ```
2815	pub fn new(condition: Q, then: Expression) -> Self {
2816		Self {
2817			condition,
2818			then: Box::new(then),
2819		}
2820	}
2821
2822	/// Get a reference to the THEN expression
2823	pub fn then(&self) -> &Expression {
2824		&self.then
2825	}
2826
2827	/// Convert into the THEN expression
2828	pub fn into_then(self) -> Expression {
2829		*self.then
2830	}
2831
2832	/// Generate SQL for the WHEN clause
2833	///
2834	/// # Examples
2835	///
2836	/// ```
2837	/// use reinhardt_db::orm::expressions::{When, Q, Value, Expression};
2838	///
2839	/// let when = When::new(
2840	///     Q::new("age", ">=", "18"),
2841	///     Expression::Value(Value::string("adult"))
2842	/// );
2843	/// assert!(when.to_sql().starts_with("WHEN"));
2844	/// ```
2845	pub fn to_sql(&self) -> String {
2846		format!(
2847			"WHEN {} THEN {}",
2848			self.condition.to_sql(),
2849			self.then.to_sql()
2850		)
2851	}
2852}
2853
2854/// Case expression - conditional logic in SQL
2855/// Similar to Django's Case() for conditional expressions
2856#[derive(Debug, Clone, Serialize, Deserialize)]
2857pub struct Case {
2858	/// The when clauses.
2859	pub when_clauses: Vec<When>,
2860	default: Option<Box<Expression>>,
2861}
2862
2863impl Case {
2864	/// Create a new CASE expression
2865	///
2866	/// # Examples
2867	///
2868	/// ```
2869	/// use reinhardt_db::orm::expressions::{Case, When, Q, Value, Expression};
2870	///
2871	/// let case_expr = Case::new()
2872	///     .when(When::new(
2873	///         Q::new("status", "=", "active"),
2874	///         Expression::Value(Value::int(1))
2875	///     ))
2876	///     .default(Expression::Value(Value::int(0)));
2877	/// // Verify the CASE expression is created successfully
2878	/// let _: Case = case_expr;
2879	/// ```
2880	pub fn new() -> Self {
2881		Self {
2882			when_clauses: Vec::new(),
2883			default: None,
2884		}
2885	}
2886
2887	/// Get a reference to the default ELSE expression
2888	pub fn default_value(&self) -> Option<&Expression> {
2889		self.default.as_deref()
2890	}
2891
2892	/// Convert into the default ELSE expression
2893	pub fn into_default(self) -> Option<Expression> {
2894		self.default.map(|b| *b)
2895	}
2896
2897	/// Add a WHEN clause to the CASE expression
2898	///
2899	/// # Examples
2900	///
2901	/// ```
2902	/// use reinhardt_db::orm::expressions::{Case, When, Q, Value, Expression};
2903	///
2904	/// let case = Case::new().when(When::new(
2905	///     Q::new("age", ">=", "18"),
2906	///     Expression::Value(Value::string("adult"))
2907	/// ));
2908	/// // Verify the CASE with WHEN clause is created successfully
2909	/// let _: Case = case;
2910	/// ```
2911	pub fn when(mut self, when: When) -> Self {
2912		self.when_clauses.push(when);
2913		self
2914	}
2915
2916	/// Set the default ELSE value for the CASE expression
2917	///
2918	/// # Examples
2919	///
2920	/// ```
2921	/// use reinhardt_db::orm::expressions::{Case, Value, Expression};
2922	///
2923	/// let case = Case::new().default(Expression::Value(Value::string("unknown")));
2924	/// // Verify the CASE with default value is created successfully
2925	/// let _: Case = case;
2926	/// ```
2927	pub fn default(mut self, default: Expression) -> Self {
2928		self.default = Some(Box::new(default));
2929		self
2930	}
2931
2932	/// Generate SQL for the CASE expression
2933	///
2934	/// # Examples
2935	///
2936	/// ```
2937	/// use reinhardt_db::orm::expressions::{Case, When, Q, Value, Expression};
2938	///
2939	/// let case = Case::new()
2940	///     .when(When::new(Q::new("x", "=", "1"), Expression::Value(Value::string("one"))))
2941	///     .default(Expression::Value(Value::string("other")));
2942	/// assert!(case.to_sql().starts_with("CASE"));
2943	/// assert!(case.to_sql().contains("END"));
2944	/// ```
2945	pub fn to_sql(&self) -> String {
2946		let when_clauses = self
2947			.when_clauses
2948			.iter()
2949			.map(|w| w.to_sql())
2950			.collect::<Vec<_>>()
2951			.join(" ");
2952
2953		let default_clause = self
2954			.default
2955			.as_ref()
2956			.map(|d| format!(" ELSE {}", d.to_sql()))
2957			.unwrap_or_default();
2958
2959		format!("CASE {}{} END", when_clauses, default_clause)
2960	}
2961}
2962
2963impl Default for Case {
2964	fn default() -> Self {
2965		Self::new()
2966	}
2967}
2968
2969/// Generic expression enum to support different expression types
2970#[derive(Debug, Clone, Serialize, Deserialize)]
2971pub enum Expression {
2972	/// F variant.
2973	F(F),
2974	/// Value variant.
2975	Value(Value),
2976	/// Case variant.
2977	Case(Case),
2978	// Aggregate(super::aggregation::Aggregate),
2979}
2980
2981impl Expression {
2982	/// Generate SQL from this expression
2983	///
2984	/// # Examples
2985	///
2986	/// ```
2987	/// use reinhardt_db::orm::expressions::{Expression, F, Value};
2988	///
2989	/// let field_expr = Expression::F(F::new("price"));
2990	/// assert_eq!(field_expr.to_sql(), "\"price\"");
2991	///
2992	/// let value_expr = Expression::Value(Value::int(100));
2993	/// assert_eq!(value_expr.to_sql(), "100");
2994	/// ```
2995	pub fn to_sql(&self) -> String {
2996		match self {
2997			Expression::F(f) => f.to_sql(),
2998			Expression::Value(v) => v.to_sql(),
2999			Expression::Case(c) => c.to_sql(),
3000		}
3001	}
3002}
3003
3004impl From<F> for Expression {
3005	fn from(f: F) -> Self {
3006		Expression::F(f)
3007	}
3008}
3009
3010impl From<Value> for Expression {
3011	fn from(v: Value) -> Self {
3012		Expression::Value(v)
3013	}
3014}
3015
3016impl From<Case> for Expression {
3017	fn from(c: Case) -> Self {
3018		Expression::Case(c)
3019	}
3020}