Skip to main content

reinhardt_db/orm/
query.rs

1//! Unified query interface facade
2//!
3//! This module provides a unified entry point for querying functionality.
4//! By default, it exports the expression-based query API (SQLAlchemy-style).
5
6use super::FieldSelector;
7use crate::naming::to_snake_case;
8use crate::orm::query_fields::GroupByFields;
9use crate::orm::query_fields::aggregate::{AggregateExpr, ComparisonExpr};
10use crate::orm::query_fields::comparison::FieldComparison;
11use crate::orm::query_fields::compiler::QueryFieldCompiler;
12use reinhardt_query::prelude::{
13	Alias, BinOper, ColumnRef, Condition, Expr, ExprTrait, Func, JoinType as SeaJoinType,
14	MySqlQueryBuilder, Order, PostgresQueryBuilder, Query, QueryBuilder, QueryStatementBuilder,
15	SelectStatement, SimpleExpr, SqliteQueryBuilder, UpdateStatement,
16};
17use reinhardt_query::types::PgBinOper;
18use serde::{Deserialize, Serialize};
19use smallvec::SmallVec;
20use std::collections::HashMap;
21use std::time::Instant;
22use uuid::Uuid;
23
24// Django QuerySet API types
25#[derive(Debug, Clone, Serialize, Deserialize)]
26/// Defines possible filter operator values.
27pub enum FilterOperator {
28	/// Eq variant.
29	Eq,
30	/// Case-insensitive exact match.
31	IExact,
32	/// Ne variant.
33	Ne,
34	/// Gt variant.
35	Gt,
36	/// Gte variant.
37	Gte,
38	/// Lt variant.
39	Lt,
40	/// Lte variant.
41	Lte,
42	/// In variant.
43	In,
44	/// NotIn variant.
45	NotIn,
46	/// Contains variant.
47	Contains,
48	/// Case-insensitive contains variant.
49	IContains,
50	/// StartsWith variant.
51	StartsWith,
52	/// Case-insensitive starts-with variant.
53	IStartsWith,
54	/// EndsWith variant.
55	EndsWith,
56	/// Case-insensitive ends-with variant.
57	IEndsWith,
58	/// Regular expression match.
59	Regex,
60	/// Case-insensitive regular expression match.
61	IRegex,
62	/// BETWEEN range lookup.
63	Range,
64	// PostgreSQL array operators
65	/// Array contains all elements (@>)
66	ArrayContains,
67	/// Array is contained by (<@)
68	ArrayContainedBy,
69	/// Arrays overlap (&&) - at least one common element
70	ArrayOverlap,
71	// PostgreSQL full-text search
72	/// Full-text search match (@@)
73	FullTextMatch,
74	// PostgreSQL JSONB operators
75	/// JSONB contains (@>)
76	JsonbContains,
77	/// JSONB is contained by (<@)
78	JsonbContainedBy,
79	/// JSONB key exists (?)
80	JsonbKeyExists,
81	/// JSONB any key exists (?|)
82	JsonbAnyKeyExists,
83	/// JSONB all keys exist (?&)
84	JsonbAllKeysExist,
85	/// JSONB path exists (@?)
86	JsonbPathExists,
87	// Other operators
88	/// Is null check
89	IsNull,
90	/// Is not null check
91	IsNotNull,
92	/// Range contains value (@>)
93	RangeContains,
94	/// Value is within range (<@)
95	RangeContainedBy,
96	/// Range overlaps (&&)
97	RangeOverlaps,
98}
99
100#[derive(Debug, Clone, Serialize, Deserialize)]
101/// Defines possible filter value values.
102pub enum FilterValue {
103	/// String variant.
104	String(String),
105	/// Integer variant.
106	Integer(i64),
107	/// Alias for Integer (for compatibility with test code)
108	Int(i64),
109	/// Float variant.
110	Float(f64),
111	/// Boolean variant.
112	Boolean(bool),
113	/// Alias for Boolean (for compatibility with test code)
114	Bool(bool),
115	/// Null variant.
116	Null,
117	/// Array variant.
118	Array(Vec<String>),
119	/// Typed list variant for IN and NOT IN lookups.
120	List(Vec<FilterValue>),
121	/// Two-value range for BETWEEN lookups.
122	Range(Box<FilterValue>, Box<FilterValue>),
123	/// Field reference for field-to-field comparisons (e.g., WHERE discount_price < total_price)
124	FieldRef(super::expressions::F),
125	/// Arithmetic expression (e.g., WHERE total != unit_price * quantity)
126	Expression(super::annotation::Expression),
127	/// Outer query reference for correlated subqueries (e.g., WHERE books.author_id = OuterRef("authors.id"))
128	OuterRef(super::expressions::OuterRef),
129}
130
131#[derive(Debug, Clone)]
132enum FilterField {
133	Column,
134	Expression(String),
135}
136
137#[derive(Debug, Clone)]
138/// Represents a filter.
139pub struct Filter {
140	/// The field.
141	pub field: String,
142	field_source: FilterField,
143	/// The operator.
144	pub operator: FilterOperator,
145	/// The value.
146	pub value: FilterValue,
147}
148
149impl Filter {
150	/// Creates a new instance.
151	pub fn new(field: impl Into<String>, operator: FilterOperator, value: FilterValue) -> Self {
152		let field = field.into();
153		Self {
154			field,
155			field_source: FilterField::Column,
156			operator,
157			value,
158		}
159	}
160
161	/// Returns the SQL expression used on the left side of this filter.
162	pub fn lhs_expr(&self) -> Expr {
163		filter_lhs_expr(self)
164	}
165
166	/// Returns the SQL text used on the left side of this filter.
167	pub fn lhs_sql(&self) -> String {
168		filter_lhs_sql(self)
169	}
170
171	/// Combine this filter with another condition using AND.
172	pub fn and(self, other: impl Into<FilterCondition>) -> FilterCondition {
173		FilterCondition::And(vec![FilterCondition::from(self), other.into()])
174	}
175
176	/// Combine this filter with another condition using OR.
177	pub fn or(self, other: impl Into<FilterCondition>) -> FilterCondition {
178		FilterCondition::Or(vec![FilterCondition::from(self), other.into()])
179	}
180
181	/// Negate this filter.
182	// This method mirrors Django-style query combinators and returns FilterCondition,
183	// so implementing std::ops::Not would not provide the same fluent API.
184	#[allow(clippy::should_implement_trait)]
185	pub fn not(self) -> FilterCondition {
186		FilterCondition::not(self)
187	}
188
189	pub(crate) fn expression(
190		sql: impl Into<String>,
191		operator: FilterOperator,
192		value: FilterValue,
193	) -> Self {
194		let sql = sql.into();
195		Self {
196			field: sql.clone(),
197			field_source: FilterField::Expression(sql),
198			operator,
199			value,
200		}
201	}
202}
203
204/// Values that can be used in UPDATE statements
205#[derive(Debug, Clone)]
206pub enum UpdateValue {
207	/// String variant.
208	String(String),
209	/// Integer variant.
210	Integer(i64),
211	/// Float variant.
212	Float(f64),
213	/// Boolean variant.
214	Boolean(bool),
215	/// Null variant.
216	Null,
217	/// Timestamp variant.
218	Timestamp(chrono::DateTime<chrono::Utc>),
219	/// UUID variant.
220	Uuid(Uuid),
221	/// Field reference for field-to-field updates (e.g., SET discount_price = total_price)
222	FieldRef(super::expressions::F),
223	/// Arithmetic expression (e.g., SET total = unit_price * quantity)
224	Expression(super::annotation::Expression),
225}
226
227impl From<String> for UpdateValue {
228	fn from(value: String) -> Self {
229		Self::String(value)
230	}
231}
232
233impl From<&str> for UpdateValue {
234	fn from(value: &str) -> Self {
235		Self::String(value.to_string())
236	}
237}
238
239impl From<i64> for UpdateValue {
240	fn from(value: i64) -> Self {
241		Self::Integer(value)
242	}
243}
244
245impl From<i32> for UpdateValue {
246	fn from(value: i32) -> Self {
247		Self::Integer(value as i64)
248	}
249}
250
251impl From<f64> for UpdateValue {
252	fn from(value: f64) -> Self {
253		Self::Float(value)
254	}
255}
256
257impl From<f32> for UpdateValue {
258	fn from(value: f32) -> Self {
259		Self::Float(value as f64)
260	}
261}
262
263impl From<bool> for UpdateValue {
264	fn from(value: bool) -> Self {
265		Self::Boolean(value)
266	}
267}
268
269impl From<chrono::DateTime<chrono::Utc>> for UpdateValue {
270	fn from(value: chrono::DateTime<chrono::Utc>) -> Self {
271		Self::Timestamp(value)
272	}
273}
274
275impl From<Uuid> for UpdateValue {
276	fn from(value: Uuid) -> Self {
277		Self::Uuid(value)
278	}
279}
280
281impl<T> From<Option<T>> for UpdateValue
282where
283	T: Into<UpdateValue>,
284{
285	fn from(value: Option<T>) -> Self {
286		value.map_or(Self::Null, Into::into)
287	}
288}
289
290/// One field assignment for a partial `QuerySet` update.
291#[derive(Debug, Clone)]
292pub struct FieldAssignment {
293	field: String,
294	value: UpdateValue,
295}
296
297impl FieldAssignment {
298	/// Creates a new field assignment.
299	pub fn new(field: impl Into<String>, value: impl Into<UpdateValue>) -> Self {
300		Self {
301			field: field.into(),
302			value: value.into(),
303		}
304	}
305
306	/// Returns the assigned field name.
307	pub fn field(&self) -> &str {
308		&self.field
309	}
310
311	/// Returns the assigned value.
312	pub fn value(&self) -> &UpdateValue {
313		&self.value
314	}
315}
316
317impl<M, T, V> From<(super::expressions::FieldRef<M, T>, V)> for FieldAssignment
318where
319	V: Into<UpdateValue>,
320{
321	fn from((field, value): (super::expressions::FieldRef<M, T>, V)) -> Self {
322		Self::new(field.name(), value)
323	}
324}
325
326impl<V> From<(&str, V)> for FieldAssignment
327where
328	V: Into<UpdateValue>,
329{
330	fn from((field, value): (&str, V)) -> Self {
331		Self::new(field, value)
332	}
333}
334
335impl<V> From<(String, V)> for FieldAssignment
336where
337	V: Into<UpdateValue>,
338{
339	fn from((field, value): (String, V)) -> Self {
340		Self::new(field, value)
341	}
342}
343
344/// Composite filter condition supporting AND/OR logic
345///
346/// This enum allows building complex filter expressions with nested AND/OR conditions.
347/// It's particularly useful for search functionality that needs to match across
348/// multiple fields using OR logic.
349///
350/// # Examples
351///
352/// ```
353/// use reinhardt_db::orm::{Filter, FilterCondition, FilterOperator, FilterValue};
354///
355/// // Simple single filter
356/// let single = FilterCondition::Single(Filter::new(
357///     "name".to_string(),
358///     FilterOperator::Eq,
359///     FilterValue::String("Alice".to_string()),
360/// ));
361///
362/// // OR condition across multiple fields (useful for search)
363/// let search = FilterCondition::Or(vec![
364///     FilterCondition::Single(Filter::new(
365///         "name".to_string(),
366///         FilterOperator::Contains,
367///         FilterValue::String("alice".to_string()),
368///     )),
369///     FilterCondition::Single(Filter::new(
370///         "email".to_string(),
371///         FilterOperator::Contains,
372///         FilterValue::String("alice".to_string()),
373///     )),
374/// ]);
375///
376/// // Complex nested condition: (status = 'active') AND (name LIKE '%alice%' OR email LIKE '%alice%')
377/// let complex = Filter::new(
378///     "status".to_string(),
379///     FilterOperator::Eq,
380///     FilterValue::String("active".to_string()),
381/// ).and(search);
382/// ```
383#[derive(Debug, Clone)]
384pub enum FilterCondition {
385	/// A single filter expression
386	Single(Filter),
387	/// All conditions must match (AND logic)
388	And(Vec<FilterCondition>),
389	/// Any condition must match (OR logic)
390	Or(Vec<FilterCondition>),
391	/// Negates the inner condition (NOT logic)
392	Not(Box<FilterCondition>),
393}
394
395impl FilterCondition {
396	/// Create a single filter condition
397	pub fn single(filter: Filter) -> Self {
398		Self::Single(filter)
399	}
400
401	/// Create an AND condition from multiple conditions
402	pub fn and(conditions: Vec<FilterCondition>) -> Self {
403		Self::And(conditions)
404	}
405
406	/// Create an OR condition from multiple conditions
407	pub fn or(conditions: Vec<FilterCondition>) -> Self {
408		Self::Or(conditions)
409	}
410
411	/// Create a NOT condition that negates the given condition
412	///
413	/// # Examples
414	///
415	/// ```
416	/// use reinhardt_db::orm::{Filter, FilterCondition, FilterOperator, FilterValue};
417	///
418	/// let condition = Filter::new(
419	///     "is_active".to_string(),
420	///     FilterOperator::Eq,
421	///     FilterValue::Boolean(true),
422	/// ).not();
423	/// ```
424	// This method is intentionally named `not` for API consistency with Django's Q object.
425	// It does not implement std::ops::Not because it constructs a FilterCondition variant,
426	// not a boolean negation.
427	#[allow(clippy::should_implement_trait)]
428	pub fn not(condition: impl Into<FilterCondition>) -> Self {
429		Self::Not(Box::new(condition.into()))
430	}
431
432	/// Create an AND condition from multiple conditions.
433	pub fn all(conditions: Vec<FilterCondition>) -> Self {
434		Self::and(conditions)
435	}
436
437	/// Create an OR condition from multiple conditions.
438	pub fn any(conditions: Vec<FilterCondition>) -> Self {
439		Self::or(conditions)
440	}
441
442	/// Create a NOT condition that negates the given condition.
443	pub fn negate(condition: impl Into<FilterCondition>) -> Self {
444		Self::not(condition)
445	}
446
447	/// Create an OR condition from multiple filters (convenience method for search)
448	///
449	/// This is particularly useful for implementing search across multiple fields.
450	///
451	/// # Examples
452	///
453	/// ```
454	/// use reinhardt_db::orm::{Filter, FilterCondition, FilterOperator, FilterValue};
455	///
456	/// let search_filters = vec![
457	///     Filter::new("name".to_string(), FilterOperator::Contains, FilterValue::String("test".to_string())),
458	///     Filter::new("email".to_string(), FilterOperator::Contains, FilterValue::String("test".to_string())),
459	/// ];
460	/// let or_condition = FilterCondition::or_filters(search_filters);
461	/// ```
462	pub fn or_filters(filters: Vec<Filter>) -> Self {
463		Self::Or(filters.into_iter().map(FilterCondition::Single).collect())
464	}
465
466	/// Create an AND condition from multiple filters
467	pub fn and_filters(filters: Vec<Filter>) -> Self {
468		Self::And(filters.into_iter().map(FilterCondition::Single).collect())
469	}
470
471	/// Check if this condition is empty (no actual filters)
472	pub fn is_empty(&self) -> bool {
473		match self {
474			FilterCondition::Single(_) => false,
475			FilterCondition::And(conditions) | FilterCondition::Or(conditions) => {
476				conditions.is_empty() || conditions.iter().all(|c| c.is_empty())
477			}
478			FilterCondition::Not(condition) => condition.is_empty(),
479		}
480	}
481}
482
483impl From<Filter> for FilterCondition {
484	fn from(filter: Filter) -> Self {
485		Self::Single(filter)
486	}
487}
488
489// From implementations for FilterValue
490impl From<String> for FilterValue {
491	fn from(s: String) -> Self {
492		FilterValue::String(s)
493	}
494}
495
496impl From<&str> for FilterValue {
497	fn from(s: &str) -> Self {
498		FilterValue::String(s.to_string())
499	}
500}
501
502impl From<i64> for FilterValue {
503	fn from(i: i64) -> Self {
504		FilterValue::Integer(i)
505	}
506}
507
508impl From<i32> for FilterValue {
509	fn from(i: i32) -> Self {
510		FilterValue::Integer(i as i64)
511	}
512}
513
514impl From<f64> for FilterValue {
515	fn from(f: f64) -> Self {
516		FilterValue::Float(f)
517	}
518}
519
520impl From<bool> for FilterValue {
521	fn from(b: bool) -> Self {
522		FilterValue::Boolean(b)
523	}
524}
525
526impl From<uuid::Uuid> for FilterValue {
527	fn from(u: uuid::Uuid) -> Self {
528		FilterValue::String(u.to_string())
529	}
530}
531
532#[derive(Debug, Clone)]
533/// Represents a orm query.
534pub struct OrmQuery {
535	filters: Vec<Filter>,
536}
537
538impl OrmQuery {
539	/// Creates a new instance.
540	pub fn new() -> Self {
541		Self {
542			filters: Vec::new(),
543		}
544	}
545
546	/// Performs the filter operation.
547	pub fn filter(mut self, filter: Filter) -> Self {
548		self.filters.push(filter);
549		self
550	}
551}
552
553impl Default for OrmQuery {
554	fn default() -> Self {
555		Self::new()
556	}
557}
558
559/// JOIN clause specification for QuerySet
560#[derive(Clone, Debug)]
561struct JoinClause {
562	/// The type of JOIN (INNER, LEFT, RIGHT, CROSS)
563	join_type: super::sqlalchemy_query::JoinType,
564	/// The name of the table to join
565	target_table: String,
566	/// Optional alias for the target table (for self-joins)
567	target_alias: Option<String>,
568	/// The ON condition as a SQL expression string
569	/// Format: "left_table.left_field = right_table.right_field"
570	/// Can include table aliases for self-joins (e.g., "u1.id < u2.id")
571	on_condition: String,
572}
573
574/// Aggregate function types for HAVING clauses
575#[derive(Clone, Debug)]
576enum AggregateFunc {
577	Avg,
578	Count,
579	Sum,
580	Min,
581	Max,
582}
583
584/// Comparison operators for HAVING clauses
585#[derive(Clone, Debug)]
586pub enum ComparisonOp {
587	/// Eq variant.
588	Eq,
589	/// Ne variant.
590	Ne,
591	/// Gt variant.
592	Gt,
593	/// Gte variant.
594	Gte,
595	/// Lt variant.
596	Lt,
597	/// Lte variant.
598	Lte,
599}
600
601/// Value types for aggregate comparisons in HAVING clauses
602#[derive(Clone, Debug)]
603enum AggregateValue {
604	Int(i64),
605	Float(f64),
606}
607
608/// HAVING clause condition specification
609#[derive(Clone, Debug)]
610enum HavingCondition {
611	/// Compare an aggregate function result with a value
612	/// Example: HAVING AVG(price) > 1500.0
613	AggregateCompare {
614		func: AggregateFunc,
615		field: String,
616		operator: ComparisonOp,
617		value: AggregateValue,
618	},
619}
620
621/// Subquery condition specification for WHERE clause
622#[derive(Clone, Debug)]
623enum SubqueryCondition {
624	/// WHERE field IN (subquery)
625	/// Example: WHERE author_id IN (SELECT id FROM authors WHERE name = 'John')
626	In { field: String, subquery: String },
627	/// WHERE field NOT IN (subquery)
628	NotIn { field: String, subquery: String },
629	/// WHERE EXISTS (subquery)
630	/// Example: WHERE EXISTS (SELECT 1 FROM books WHERE author_id = authors.id)
631	Exists { subquery: String },
632	/// WHERE NOT EXISTS (subquery)
633	NotExists { subquery: String },
634}
635
636const MAX_FILTER_CONDITION_DEPTH: usize = 64;
637
638#[derive(Clone)]
639/// Represents a query set.
640pub struct QuerySet<T>
641where
642	T: super::Model,
643{
644	_phantom: std::marker::PhantomData<T>,
645	filters: SmallVec<[Filter; 10]>,
646	filter_conditions: SmallVec<[FilterCondition; 4]>,
647	select_related_fields: Vec<String>,
648	prefetch_related_fields: Vec<String>,
649	order_by_fields: Vec<String>,
650	distinct_enabled: bool,
651	selected_fields: Option<Vec<String>>,
652	deferred_fields: Vec<String>,
653	annotations: Vec<super::annotation::Annotation>,
654	manager: Option<std::sync::Arc<super::manager::Manager<T>>>,
655	limit: Option<usize>,
656	offset: Option<usize>,
657	ctes: super::cte::CTECollection,
658	lateral_joins: super::lateral_join::LateralJoins,
659	joins: Vec<JoinClause>,
660	group_by_fields: Vec<String>,
661	having_conditions: Vec<HavingCondition>,
662	subquery_conditions: Vec<SubqueryCondition>,
663	from_alias: Option<String>,
664	/// Subquery SQL for FROM clause (derived table)
665	/// When set, the FROM clause will use this subquery instead of the model's table
666	from_subquery_sql: Option<String>,
667}
668
669impl<T> QuerySet<T>
670where
671	T: super::Model,
672{
673	/// Creates a new instance.
674	pub fn new() -> Self {
675		Self {
676			_phantom: std::marker::PhantomData,
677			filters: SmallVec::new(),
678			filter_conditions: SmallVec::new(),
679			select_related_fields: Vec::new(),
680			prefetch_related_fields: Vec::new(),
681			order_by_fields: Vec::new(),
682			distinct_enabled: false,
683			selected_fields: None,
684			deferred_fields: Vec::new(),
685			annotations: Vec::new(),
686			manager: None,
687			limit: None,
688			offset: None,
689			ctes: super::cte::CTECollection::new(),
690			lateral_joins: super::lateral_join::LateralJoins::new(),
691			joins: Vec::new(),
692			group_by_fields: Vec::new(),
693			having_conditions: Vec::new(),
694			subquery_conditions: Vec::new(),
695			from_alias: None,
696			from_subquery_sql: None,
697		}
698	}
699
700	/// Sets the manager and returns self for chaining.
701	pub fn with_manager(manager: std::sync::Arc<super::manager::Manager<T>>) -> Self {
702		Self {
703			_phantom: std::marker::PhantomData,
704			filters: SmallVec::new(),
705			filter_conditions: SmallVec::new(),
706			select_related_fields: Vec::new(),
707			prefetch_related_fields: Vec::new(),
708			order_by_fields: Vec::new(),
709			distinct_enabled: false,
710			selected_fields: None,
711			deferred_fields: Vec::new(),
712			annotations: Vec::new(),
713			manager: Some(manager),
714			limit: None,
715			offset: None,
716			ctes: super::cte::CTECollection::new(),
717			lateral_joins: super::lateral_join::LateralJoins::new(),
718			joins: Vec::new(),
719			group_by_fields: Vec::new(),
720			having_conditions: Vec::new(),
721			subquery_conditions: Vec::new(),
722			from_alias: None,
723			from_subquery_sql: None,
724		}
725	}
726
727	/// Appends a filter expression to this `QuerySet`.
728	///
729	/// Accepts any value convertible into [`FilterCondition`] — typically a
730	/// [`Filter`] from `FieldRef::eq()` / `.gt()` / ... or a composite condition
731	/// built with [`Filter::and`], [`Filter::or`], and [`Filter::not`].
732	pub fn filter(mut self, filter: impl Into<FilterCondition>) -> Self {
733		match filter.into() {
734			FilterCondition::Single(filter) => self.filters.push(filter),
735			condition => self.filter_conditions.push(condition),
736		}
737		self
738	}
739
740	/// Returns the filters that have been applied to this `QuerySet`.
741	///
742	/// Useful for inspection in tests and for custom managers that need to
743	/// observe or assert on the active filter chain (Issue #3980).
744	pub fn filters(&self) -> &[Filter] {
745		&self.filters
746	}
747
748	/// Returns composite filter conditions applied to this `QuerySet`.
749	pub fn filter_conditions(&self) -> &[FilterCondition] {
750		&self.filter_conditions
751	}
752
753	fn has_where_predicates(&self) -> bool {
754		!(self.filters.is_empty()
755			&& self.filter_conditions.is_empty()
756			&& self.subquery_conditions.is_empty())
757	}
758
759	/// Create a QuerySet from a subquery (FROM clause subquery / derived table)
760	///
761	/// This method creates a new QuerySet that uses a subquery as its data source
762	/// instead of a regular table. The subquery becomes a derived table in the FROM clause.
763	///
764	/// # Type Parameters
765	///
766	/// * `M` - The model type for the subquery
767	/// * `F` - A closure that builds the subquery
768	///
769	/// # Parameters
770	///
771	/// * `builder` - A closure that receives a fresh `QuerySet<M>` and returns a configured QuerySet
772	/// * `alias` - The alias for the derived table (required for FROM subqueries)
773	///
774	/// # Examples
775	///
776	/// ```
777	/// # use reinhardt_db::orm::{Model, QuerySet};
778	/// # use reinhardt_db::orm::annotation::{Annotation, AnnotationValue};
779	/// # use reinhardt_db::orm::aggregation::Aggregate;
780	/// # use reinhardt_db::orm::{Filter, FilterOperator, FilterValue};
781	/// # use reinhardt_db::orm::GroupByFields;
782	/// # use serde::{Serialize, Deserialize};
783	/// # #[derive(Clone, Serialize, Deserialize)]
784	/// # struct Book { id: Option<i64>, author_id: Option<i64> }
785	/// # #[derive(Clone)]
786	/// # struct BookFields;
787	/// # impl reinhardt_db::orm::model::FieldSelector for BookFields {
788	/// #     fn with_alias(self, _alias: &str) -> Self { self }
789	/// # }
790	/// # impl Model for Book {
791	/// #     type PrimaryKey = i64;
792	/// #     type Fields = BookFields;
793	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
794	/// #     fn table_name() -> &'static str { "books" }
795	/// #     fn new_fields() -> Self::Fields { BookFields }
796	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
797	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
798	/// # }
799	/// // Query from a derived table showing author book counts
800	/// let results = QuerySet::<Book>::from_subquery(
801	///     |subq: QuerySet<Book>| {
802	///         subq.values(&["author_id"])
803	///             .annotate(Annotation::new("book_count", AnnotationValue::Aggregate(Aggregate::count_all())))
804	///     },
805	///     "book_stats"
806	/// )
807	/// .filter(Filter::new("book_count", FilterOperator::Gt, FilterValue::Int(1)))
808	/// .to_sql();
809	/// // Generates: SELECT * FROM (SELECT author_id, COUNT(*) AS book_count FROM books GROUP BY author_id) AS book_stats WHERE book_count > 1
810	/// ```
811	pub fn from_subquery<M, F>(builder: F, alias: &str) -> Self
812	where
813		M: super::Model + 'static,
814		F: FnOnce(QuerySet<M>) -> QuerySet<M>,
815	{
816		// Create a fresh QuerySet for the subquery model
817		let subquery_qs = QuerySet::<M>::new();
818		// Apply the builder to configure the subquery
819		let configured_subquery = builder(subquery_qs);
820		// Generate SQL for the subquery (wrapped in parentheses)
821		let subquery_sql = configured_subquery.as_subquery();
822
823		// Create a new QuerySet with the subquery as FROM source
824		Self {
825			_phantom: std::marker::PhantomData,
826			filters: SmallVec::new(),
827			filter_conditions: SmallVec::new(),
828			select_related_fields: Vec::new(),
829			prefetch_related_fields: Vec::new(),
830			order_by_fields: Vec::new(),
831			distinct_enabled: false,
832			selected_fields: None,
833			deferred_fields: Vec::new(),
834			annotations: Vec::new(),
835			manager: None,
836			limit: None,
837			offset: None,
838			ctes: super::cte::CTECollection::new(),
839			lateral_joins: super::lateral_join::LateralJoins::new(),
840			joins: Vec::new(),
841			group_by_fields: Vec::new(),
842			having_conditions: Vec::new(),
843			subquery_conditions: Vec::new(),
844			from_alias: Some(alias.to_string()),
845			from_subquery_sql: Some(subquery_sql),
846		}
847	}
848
849	/// Add an INNER JOIN to the query
850	///
851	/// Performs an INNER JOIN between the current model (T) and another model (R).
852	/// Only rows with matching values in both tables are included in the result.
853	///
854	/// # Type Parameters
855	///
856	/// * `R` - The model type to join with (must implement `Model` trait)
857	///
858	/// # Parameters
859	///
860	/// * `left_field` - The field name from the left table (current model T)
861	/// * `right_field` - The field name from the right table (model R)
862	///
863	/// # Examples
864	///
865	/// ```no_run
866	/// # use reinhardt_db::orm::Model;
867	/// # use serde::{Serialize, Deserialize};
868	/// # #[derive(Clone, Serialize, Deserialize)]
869	/// # struct User { id: Option<i64> }
870	/// # #[derive(Clone)]
871	/// # struct UserFields;
872	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
873	/// #     fn with_alias(self, _alias: &str) -> Self { self }
874	/// # }
875	/// # impl Model for User {
876	/// #     type PrimaryKey = i64;
877	/// #     type Fields = UserFields;
878	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
879	/// #     fn table_name() -> &'static str { "users" }
880	/// #     fn new_fields() -> Self::Fields { UserFields }
881	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
882	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
883	/// # }
884	/// # #[derive(Clone, Serialize, Deserialize)]
885	/// # struct Post { id: Option<i64>, user_id: Option<i64> }
886	/// # #[derive(Clone)]
887	/// # struct PostFields;
888	/// # impl reinhardt_db::orm::model::FieldSelector for PostFields {
889	/// #     fn with_alias(self, _alias: &str) -> Self { self }
890	/// # }
891	/// # impl Model for Post {
892	/// #     type PrimaryKey = i64;
893	/// #     type Fields = PostFields;
894	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
895	/// #     fn table_name() -> &'static str { "posts" }
896	/// #     fn new_fields() -> Self::Fields { PostFields }
897	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
898	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
899	/// # }
900	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
901	/// // Join User and Post on user.id = post.user_id
902	/// let sql = User::objects()
903	///     .all()
904	///     .inner_join::<Post>("id", "user_id")
905	///     .to_sql();
906	/// # Ok(())
907	/// # }
908	/// ```
909	pub fn inner_join<R: super::Model>(mut self, left_field: &str, right_field: &str) -> Self {
910		let condition = format!(
911			"{}.{} = {}.{}",
912			T::table_name(),
913			left_field,
914			R::table_name(),
915			right_field
916		);
917
918		self.joins.push(JoinClause {
919			join_type: super::sqlalchemy_query::JoinType::Inner,
920			target_table: R::table_name().to_string(),
921			target_alias: None,
922			on_condition: condition,
923		});
924
925		self
926	}
927
928	/// Add a LEFT OUTER JOIN to the query
929	///
930	/// Performs a LEFT OUTER JOIN between the current model (T) and another model (R).
931	/// All rows from the left table are included, with matching rows from the right table
932	/// or NULL values if no match is found.
933	///
934	/// # Examples
935	///
936	/// ```no_run
937	/// # use reinhardt_db::orm::Model;
938	/// # use serde::{Serialize, Deserialize};
939	/// # #[derive(Clone, Serialize, Deserialize)]
940	/// # struct User { id: Option<i64> }
941	/// # #[derive(Clone)]
942	/// # struct UserFields;
943	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
944	/// #     fn with_alias(self, _alias: &str) -> Self { self }
945	/// # }
946	/// # impl Model for User {
947	/// #     type PrimaryKey = i64;
948	/// #     type Fields = UserFields;
949	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
950	/// #     fn table_name() -> &'static str { "users" }
951	/// #     fn new_fields() -> Self::Fields { UserFields }
952	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
953	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
954	/// # }
955	/// # #[derive(Clone, Serialize, Deserialize)]
956	/// # struct Post { id: Option<i64>, user_id: Option<i64> }
957	/// # #[derive(Clone)]
958	/// # struct PostFields;
959	/// # impl reinhardt_db::orm::model::FieldSelector for PostFields {
960	/// #     fn with_alias(self, _alias: &str) -> Self { self }
961	/// # }
962	/// # impl Model for Post {
963	/// #     type PrimaryKey = i64;
964	/// #     type Fields = PostFields;
965	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
966	/// #     fn table_name() -> &'static str { "posts" }
967	/// #     fn new_fields() -> Self::Fields { PostFields }
968	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
969	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
970	/// # }
971	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
972	/// // Left join User and Post
973	/// let sql = User::objects()
974	///     .all()
975	///     .left_join::<Post>("id", "user_id")
976	///     .to_sql();
977	/// # Ok(())
978	/// # }
979	/// ```
980	pub fn left_join<R: super::Model>(mut self, left_field: &str, right_field: &str) -> Self {
981		let condition = format!(
982			"{}.{} = {}.{}",
983			T::table_name(),
984			left_field,
985			R::table_name(),
986			right_field
987		);
988
989		self.joins.push(JoinClause {
990			join_type: super::sqlalchemy_query::JoinType::Left,
991			target_table: R::table_name().to_string(),
992			target_alias: None,
993			on_condition: condition,
994		});
995
996		self
997	}
998
999	/// Add a RIGHT OUTER JOIN to the query
1000	///
1001	/// Performs a RIGHT OUTER JOIN between the current model (T) and another model (R).
1002	/// All rows from the right table are included, with matching rows from the left table
1003	/// or NULL values if no match is found.
1004	///
1005	/// # Examples
1006	///
1007	/// ```no_run
1008	/// # use reinhardt_db::orm::Model;
1009	/// # use serde::{Serialize, Deserialize};
1010	/// # #[derive(Clone, Serialize, Deserialize)]
1011	/// # struct User { id: Option<i64> }
1012	/// # #[derive(Clone)]
1013	/// # struct UserFields;
1014	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
1015	/// #     fn with_alias(self, _alias: &str) -> Self { self }
1016	/// # }
1017	/// # impl Model for User {
1018	/// #     type PrimaryKey = i64;
1019	/// #     type Fields = UserFields;
1020	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1021	/// #     fn table_name() -> &'static str { "users" }
1022	/// #     fn new_fields() -> Self::Fields { UserFields }
1023	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1024	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1025	/// # }
1026	/// # #[derive(Clone, Serialize, Deserialize)]
1027	/// # struct Post { id: Option<i64>, user_id: Option<i64> }
1028	/// # #[derive(Clone)]
1029	/// # struct PostFields;
1030	/// # impl reinhardt_db::orm::model::FieldSelector for PostFields {
1031	/// #     fn with_alias(self, _alias: &str) -> Self { self }
1032	/// # }
1033	/// # impl Model for Post {
1034	/// #     type PrimaryKey = i64;
1035	/// #     type Fields = PostFields;
1036	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1037	/// #     fn table_name() -> &'static str { "posts" }
1038	/// #     fn new_fields() -> Self::Fields { PostFields }
1039	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1040	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1041	/// # }
1042	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
1043	/// // Right join User and Post
1044	/// let sql = User::objects()
1045	///     .all()
1046	///     .right_join::<Post>("id", "user_id")
1047	///     .to_sql();
1048	/// # Ok(())
1049	/// # }
1050	/// ```
1051	pub fn right_join<R: super::Model>(mut self, left_field: &str, right_field: &str) -> Self {
1052		let condition = format!(
1053			"{}.{} = {}.{}",
1054			T::table_name(),
1055			left_field,
1056			R::table_name(),
1057			right_field
1058		);
1059
1060		self.joins.push(JoinClause {
1061			join_type: super::sqlalchemy_query::JoinType::Right,
1062			target_table: R::table_name().to_string(),
1063			target_alias: None,
1064			on_condition: condition,
1065		});
1066
1067		self
1068	}
1069
1070	/// Add a CROSS JOIN to the query
1071	///
1072	/// Performs a CROSS JOIN between the current model (T) and another model (R).
1073	/// Produces the Cartesian product of both tables (all possible combinations).
1074	/// No ON condition is needed for CROSS JOIN.
1075	///
1076	/// # Examples
1077	///
1078	/// ```no_run
1079	/// # use reinhardt_db::orm::Model;
1080	/// # use serde::{Serialize, Deserialize};
1081	/// # #[derive(Clone, Serialize, Deserialize)]
1082	/// # struct User { id: Option<i64> }
1083	/// # #[derive(Clone)]
1084	/// # struct UserFields;
1085	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
1086	/// #     fn with_alias(self, _alias: &str) -> Self { self }
1087	/// # }
1088	/// # impl Model for User {
1089	/// #     type PrimaryKey = i64;
1090	/// #     type Fields = UserFields;
1091	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1092	/// #     fn table_name() -> &'static str { "users" }
1093	/// #     fn new_fields() -> Self::Fields { UserFields }
1094	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1095	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1096	/// # }
1097	/// # #[derive(Clone, Serialize, Deserialize)]
1098	/// # struct Category { id: Option<i64> }
1099	/// # #[derive(Clone)]
1100	/// # struct CategoryFields;
1101	/// # impl reinhardt_db::orm::model::FieldSelector for CategoryFields {
1102	/// #     fn with_alias(self, _alias: &str) -> Self { self }
1103	/// # }
1104	/// # impl Model for Category {
1105	/// #     type PrimaryKey = i64;
1106	/// #     type Fields = CategoryFields;
1107	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1108	/// #     fn table_name() -> &'static str { "categories" }
1109	/// #     fn new_fields() -> Self::Fields { CategoryFields }
1110	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1111	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1112	/// # }
1113	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
1114	/// // Cross join User and Category
1115	/// let sql = User::objects()
1116	///     .all()
1117	///     .cross_join::<Category>()
1118	///     .to_sql();
1119	/// # Ok(())
1120	/// # }
1121	/// ```
1122	pub fn cross_join<R: super::Model>(mut self) -> Self {
1123		self.joins.push(JoinClause {
1124			join_type: super::sqlalchemy_query::JoinType::Inner, // CROSS JOIN uses Inner with empty condition
1125			target_table: R::table_name().to_string(),
1126			target_alias: None,
1127			on_condition: String::new(), // Empty condition for CROSS JOIN
1128		});
1129
1130		self
1131	}
1132
1133	/// Set an alias for the base table (FROM clause)
1134	///
1135	/// This is useful for self-joins where you need to reference the same table multiple times.
1136	///
1137	/// # Parameters
1138	///
1139	/// * `alias` - The alias name for the base table
1140	///
1141	/// # Examples
1142	///
1143	/// ```
1144	/// # use reinhardt_db::orm::Model;
1145	/// # use reinhardt_db::orm::query_fields::Field;
1146	/// # use reinhardt_db::orm::FieldSelector;
1147	/// # use serde::{Serialize, Deserialize};
1148	/// # #[derive(Clone, Serialize, Deserialize)]
1149	/// # struct User { id: Option<i64> }
1150	/// #
1151	/// # #[derive(Clone)]
1152	/// # struct UserFields {
1153	/// #     pub id: Field<User, i64>,
1154	/// # }
1155	/// # impl UserFields {
1156	/// #     pub fn new() -> Self {
1157	/// #         Self { id: Field::new(vec!["id"]) }
1158	/// #     }
1159	/// # }
1160	/// # impl FieldSelector for UserFields {
1161	/// #     fn with_alias(mut self, alias: &str) -> Self {
1162	/// #         self.id = self.id.with_alias(alias);
1163	/// #         self
1164	/// #     }
1165	/// # }
1166	/// # impl Model for User {
1167	/// #     type PrimaryKey = i64;
1168	/// #     type Fields = UserFields;
1169	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1170	/// #     fn table_name() -> &'static str { "users" }
1171	/// #     fn new_fields() -> Self::Fields { UserFields::new() }
1172	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1173	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1174	/// # }
1175	/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
1176	/// // Self-join: find user pairs
1177	/// let sql = User::objects()
1178	///     .all()
1179	///     .from_as("u1")
1180	///     .inner_join_as::<User, _>("u1", "u2", |left, right| left.id.field_lt(right.id))
1181	///     .to_sql();
1182	/// # Ok(())
1183	/// # }
1184	/// ```
1185	pub fn from_as(mut self, alias: &str) -> Self {
1186		self.from_alias = Some(alias.to_string());
1187		self
1188	}
1189
1190	/// Add an INNER JOIN with custom condition
1191	///
1192	/// Performs an INNER JOIN with a custom ON condition expression.
1193	/// Use this when you need complex join conditions beyond simple equality.
1194	///
1195	/// # Type Parameters
1196	///
1197	/// * `R` - The model type to join with (must implement `Model` trait)
1198	///
1199	/// # Parameters
1200	///
1201	/// * `condition` - Custom SQL condition for the JOIN (e.g., "users.id = posts.user_id AND posts.status = 'published'")
1202	///
1203	/// # Examples
1204	///
1205	/// ```no_run
1206	/// # use reinhardt_db::orm::Model;
1207	/// # use serde::{Serialize, Deserialize};
1208	/// # #[derive(Clone, Serialize, Deserialize)]
1209	/// # struct User { id: Option<i64> }
1210	/// # #[derive(Clone)]
1211	/// # struct UserFields;
1212	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
1213	/// #     fn with_alias(self, _alias: &str) -> Self { self }
1214	/// # }
1215	/// # impl Model for User {
1216	/// #     type PrimaryKey = i64;
1217	/// #     type Fields = UserFields;
1218	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1219	/// #     fn table_name() -> &'static str { "users" }
1220	/// #     fn new_fields() -> Self::Fields { UserFields }
1221	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1222	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1223	/// # }
1224	/// # #[derive(Clone, Serialize, Deserialize)]
1225	/// # struct Post { id: Option<i64>, user_id: Option<i64> }
1226	/// # #[derive(Clone)]
1227	/// # struct PostFields;
1228	/// # impl reinhardt_db::orm::model::FieldSelector for PostFields {
1229	/// #     fn with_alias(self, _alias: &str) -> Self { self }
1230	/// # }
1231	/// # impl Model for Post {
1232	/// #     type PrimaryKey = i64;
1233	/// #     type Fields = PostFields;
1234	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1235	/// #     fn table_name() -> &'static str { "posts" }
1236	/// #     fn new_fields() -> Self::Fields { PostFields }
1237	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1238	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1239	/// # }
1240	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
1241	/// // Join with complex condition
1242	/// let sql = User::objects()
1243	///     .all()
1244	///     .inner_join_on::<Post>("users.id = posts.user_id AND posts.title LIKE 'First%'")
1245	///     .to_sql();
1246	/// # Ok(())
1247	/// # }
1248	/// ```
1249	pub fn inner_join_on<R: super::Model>(mut self, condition: &str) -> Self {
1250		self.joins.push(JoinClause {
1251			join_type: super::sqlalchemy_query::JoinType::Inner,
1252			target_table: R::table_name().to_string(),
1253			target_alias: None,
1254			on_condition: condition.to_string(),
1255		});
1256
1257		self
1258	}
1259
1260	/// Add a LEFT OUTER JOIN with custom condition
1261	///
1262	/// Similar to `inner_join_on()` but performs a LEFT OUTER JOIN.
1263	///
1264	/// # Type Parameters
1265	///
1266	/// * `R` - The model type to join with (must implement `Model` trait)
1267	///
1268	/// # Parameters
1269	///
1270	/// * `condition` - Custom SQL condition for the JOIN
1271	///
1272	/// # Examples
1273	///
1274	/// ```no_run
1275	/// # use reinhardt_db::orm::Model;
1276	/// # use serde::{Serialize, Deserialize};
1277	/// # #[derive(Clone, Serialize, Deserialize)]
1278	/// # struct User { id: Option<i64> }
1279	/// # #[derive(Clone)]
1280	/// # struct UserFields;
1281	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
1282	/// #     fn with_alias(self, _alias: &str) -> Self { self }
1283	/// # }
1284	/// # impl Model for User {
1285	/// #     type PrimaryKey = i64;
1286	/// #     type Fields = UserFields;
1287	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1288	/// #     fn table_name() -> &'static str { "users" }
1289	/// #     fn new_fields() -> Self::Fields { UserFields }
1290	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1291	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1292	/// # }
1293	/// # #[derive(Clone, Serialize, Deserialize)]
1294	/// # struct Post { id: Option<i64>, user_id: Option<i64> }
1295	/// # #[derive(Clone)]
1296	/// # struct PostFields;
1297	/// # impl reinhardt_db::orm::model::FieldSelector for PostFields {
1298	/// #     fn with_alias(self, _alias: &str) -> Self { self }
1299	/// # }
1300	/// # impl Model for Post {
1301	/// #     type PrimaryKey = i64;
1302	/// #     type Fields = PostFields;
1303	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1304	/// #     fn table_name() -> &'static str { "posts" }
1305	/// #     fn new_fields() -> Self::Fields { PostFields }
1306	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1307	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1308	/// # }
1309	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
1310	/// let sql = User::objects()
1311	///     .all()
1312	///     .left_join_on::<Post>("users.id = posts.user_id AND posts.published = true")
1313	///     .to_sql();
1314	/// # Ok(())
1315	/// # }
1316	/// ```
1317	pub fn left_join_on<R: super::Model>(mut self, condition: &str) -> Self {
1318		self.joins.push(JoinClause {
1319			join_type: super::sqlalchemy_query::JoinType::Left,
1320			target_table: R::table_name().to_string(),
1321			target_alias: None,
1322			on_condition: condition.to_string(),
1323		});
1324
1325		self
1326	}
1327
1328	/// Add a RIGHT OUTER JOIN with custom condition
1329	///
1330	/// Similar to `inner_join_on()` but performs a RIGHT OUTER JOIN.
1331	///
1332	/// # Type Parameters
1333	///
1334	/// * `R` - The model type to join with (must implement `Model` trait)
1335	///
1336	/// # Parameters
1337	///
1338	/// * `condition` - Custom SQL condition for the JOIN
1339	///
1340	/// # Examples
1341	///
1342	/// ```no_run
1343	/// # use reinhardt_db::orm::Model;
1344	/// # use serde::{Serialize, Deserialize};
1345	/// # #[derive(Clone, Serialize, Deserialize)]
1346	/// # struct User { id: Option<i64> }
1347	/// # #[derive(Clone)]
1348	/// # struct UserFields;
1349	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
1350	/// #     fn with_alias(self, _alias: &str) -> Self { self }
1351	/// # }
1352	/// # impl Model for User {
1353	/// #     type PrimaryKey = i64;
1354	/// #     type Fields = UserFields;
1355	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1356	/// #     fn table_name() -> &'static str { "users" }
1357	/// #     fn new_fields() -> Self::Fields { UserFields }
1358	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1359	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1360	/// # }
1361	/// # #[derive(Clone, Serialize, Deserialize)]
1362	/// # struct Post { id: Option<i64>, user_id: Option<i64> }
1363	/// # #[derive(Clone)]
1364	/// # struct PostFields;
1365	/// # impl reinhardt_db::orm::model::FieldSelector for PostFields {
1366	/// #     fn with_alias(self, _alias: &str) -> Self { self }
1367	/// # }
1368	/// # impl Model for Post {
1369	/// #     type PrimaryKey = i64;
1370	/// #     type Fields = PostFields;
1371	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1372	/// #     fn table_name() -> &'static str { "posts" }
1373	/// #     fn new_fields() -> Self::Fields { PostFields }
1374	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1375	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1376	/// # }
1377	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
1378	/// let sql = User::objects()
1379	///     .all()
1380	///     .right_join_on::<Post>("users.id = posts.user_id AND users.active = true")
1381	///     .to_sql();
1382	/// # Ok(())
1383	/// # }
1384	/// ```
1385	pub fn right_join_on<R: super::Model>(mut self, condition: &str) -> Self {
1386		self.joins.push(JoinClause {
1387			join_type: super::sqlalchemy_query::JoinType::Right,
1388			target_table: R::table_name().to_string(),
1389			target_alias: None,
1390			on_condition: condition.to_string(),
1391		});
1392
1393		self
1394	}
1395
1396	/// Add an INNER JOIN with table alias
1397	///
1398	/// Performs an INNER JOIN with an alias for the target table.
1399	/// Useful for self-joins or when you need to reference the same table multiple times.
1400	///
1401	/// # Type Parameters
1402	///
1403	/// * `R` - The model type to join with (must implement `Model` trait)
1404	/// * `F` - Closure that builds the JOIN ON condition
1405	///
1406	/// # Parameters
1407	///
1408	/// * `alias` - Alias name for the target table
1409	/// * `condition_fn` - Closure that receives a `JoinOnBuilder` and returns it with the condition set
1410	///
1411	/// # Examples
1412	///
1413	/// ```
1414	/// # use reinhardt_db::orm::Model;
1415	/// # use reinhardt_db::orm::query_fields::Field;
1416	/// # use reinhardt_db::orm::FieldSelector;
1417	/// # use serde::{Serialize, Deserialize};
1418	/// # #[derive(Clone, Serialize, Deserialize)]
1419	/// # struct User { id: Option<i64> }
1420	/// #
1421	/// # #[derive(Clone)]
1422	/// # struct UserFields {
1423	/// #     pub id: Field<User, i64>,
1424	/// # }
1425	/// # impl UserFields {
1426	/// #     pub fn new() -> Self {
1427	/// #         Self { id: Field::new(vec!["id"]) }
1428	/// #     }
1429	/// # }
1430	/// # impl FieldSelector for UserFields {
1431	/// #     fn with_alias(mut self, alias: &str) -> Self {
1432	/// #         self.id = self.id.with_alias(alias);
1433	/// #         self
1434	/// #     }
1435	/// # }
1436	/// # impl Model for User {
1437	/// #     type PrimaryKey = i64;
1438	/// #     type Fields = UserFields;
1439	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1440	/// #     fn table_name() -> &'static str { "users" }
1441	/// #     fn new_fields() -> Self::Fields { UserFields::new() }
1442	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1443	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1444	/// # }
1445	/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
1446	/// // Self-join: find user pairs where user1.id < user2.id
1447	/// let sql = User::objects()
1448	///     .all()
1449	///     .inner_join_as::<User, _>("u1", "u2", |u1, u2| u1.id.field_lt(u2.id))
1450	///     .to_sql();
1451	/// # Ok(())
1452	/// # }
1453	/// ```
1454	/// # Breaking Change
1455	///
1456	/// The signature of this method has been changed from string-based JOIN conditions
1457	/// to type-safe field comparisons.
1458	pub fn inner_join_as<R: super::Model, F>(
1459		mut self,
1460		left_alias: &str,
1461		right_alias: &str,
1462		condition_fn: F,
1463	) -> Self
1464	where
1465		F: FnOnce(T::Fields, R::Fields) -> FieldComparison,
1466	{
1467		// Set base table alias
1468		if self.from_alias.is_none() {
1469			self.from_alias = Some(left_alias.to_string());
1470		}
1471
1472		// Create field selectors and set aliases
1473		let left_fields = T::new_fields().with_alias(left_alias);
1474		let right_fields = R::new_fields().with_alias(right_alias);
1475
1476		// Get comparison expression from closure
1477		let comparison = condition_fn(left_fields, right_fields);
1478
1479		// Convert to SQL
1480		let condition = QueryFieldCompiler::compile_field_comparison(&comparison);
1481
1482		// Add to JoinClause
1483		self.joins.push(JoinClause {
1484			join_type: super::sqlalchemy_query::JoinType::Inner,
1485			target_table: R::table_name().to_string(),
1486			target_alias: Some(right_alias.to_string()),
1487			on_condition: condition,
1488		});
1489
1490		self
1491	}
1492
1493	/// Add a LEFT OUTER JOIN with table alias
1494	///
1495	/// Similar to `inner_join_as()` but performs a LEFT OUTER JOIN.
1496	///
1497	/// # Type Parameters
1498	///
1499	/// * `R` - The model type to join with (must implement `Model` trait)
1500	/// * `F` - Closure that builds the JOIN ON condition
1501	///
1502	/// # Parameters
1503	///
1504	/// * `alias` - Alias name for the target table
1505	/// * `condition_fn` - Closure that receives a `JoinOnBuilder` and returns it with the condition set
1506	///
1507	/// # Examples
1508	///
1509	/// ```
1510	/// # use reinhardt_db::orm::Model;
1511	/// # use reinhardt_db::orm::query_fields::Field;
1512	/// # use reinhardt_db::orm::FieldSelector;
1513	/// # use serde::{Serialize, Deserialize};
1514	/// # #[derive(Clone, Serialize, Deserialize)]
1515	/// # struct User { id: Option<i64> }
1516	/// #
1517	/// # #[derive(Clone)]
1518	/// # struct UserFields {
1519	/// #     pub id: Field<User, i64>,
1520	/// #     pub manager_id: Field<User, i64>,
1521	/// # }
1522	/// # impl UserFields {
1523	/// #     pub fn new() -> Self {
1524	/// #         Self {
1525	/// #             id: Field::new(vec!["id"]),
1526	/// #             manager_id: Field::new(vec!["manager_id"]),
1527	/// #         }
1528	/// #     }
1529	/// # }
1530	/// # impl FieldSelector for UserFields {
1531	/// #     fn with_alias(mut self, alias: &str) -> Self {
1532	/// #         self.id = self.id.with_alias(alias);
1533	/// #         self.manager_id = self.manager_id.with_alias(alias);
1534	/// #         self
1535	/// #     }
1536	/// # }
1537	/// # impl Model for User {
1538	/// #     type PrimaryKey = i64;
1539	/// #     type Fields = UserFields;
1540	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1541	/// #     fn table_name() -> &'static str { "users" }
1542	/// #     fn new_fields() -> Self::Fields { UserFields::new() }
1543	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1544	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1545	/// # }
1546	/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
1547	/// // Self-join with LEFT JOIN: find employees and their managers
1548	/// let sql = User::objects()
1549	///     .all()
1550	///     .left_join_as::<User, _>("u1", "u2", |u1, u2| u2.id.field_eq(u1.manager_id))
1551	///     .to_sql();
1552	/// # Ok(())
1553	/// # }
1554	/// ```
1555	/// # Breaking Change
1556	///
1557	/// This method signature has been changed from string-based JOIN conditions
1558	/// to type-safe field comparisons.
1559	pub fn left_join_as<R: super::Model, F>(
1560		mut self,
1561		left_alias: &str,
1562		right_alias: &str,
1563		condition_fn: F,
1564	) -> Self
1565	where
1566		F: FnOnce(T::Fields, R::Fields) -> FieldComparison,
1567	{
1568		// Set base table alias
1569		if self.from_alias.is_none() {
1570			self.from_alias = Some(left_alias.to_string());
1571		}
1572
1573		// Create field selectors with aliases
1574		let left_fields = T::new_fields().with_alias(left_alias);
1575		let right_fields = R::new_fields().with_alias(right_alias);
1576
1577		// Get comparison from closure
1578		let comparison = condition_fn(left_fields, right_fields);
1579
1580		// Convert to SQL
1581		let condition = QueryFieldCompiler::compile_field_comparison(&comparison);
1582
1583		// Add to JoinClause
1584		self.joins.push(JoinClause {
1585			join_type: super::sqlalchemy_query::JoinType::Left,
1586			target_table: R::table_name().to_string(),
1587			target_alias: Some(right_alias.to_string()),
1588			on_condition: condition,
1589		});
1590
1591		self
1592	}
1593
1594	/// Add a RIGHT OUTER JOIN with table alias
1595	///
1596	/// Similar to `inner_join_as()` but performs a RIGHT OUTER JOIN.
1597	///
1598	/// # Type Parameters
1599	///
1600	/// * `R` - The model type to join with (must implement `Model` trait)
1601	/// * `F` - Closure that builds the JOIN ON condition
1602	///
1603	/// # Parameters
1604	///
1605	/// * `alias` - Alias name for the target table
1606	/// * `condition_fn` - Closure that receives a `JoinOnBuilder` and returns it with the condition set
1607	///
1608	/// # Examples
1609	///
1610	/// ```
1611	/// # use reinhardt_db::orm::Model;
1612	/// # use reinhardt_db::orm::query_fields::Field;
1613	/// # use reinhardt_db::orm::FieldSelector;
1614	/// # use serde::{Serialize, Deserialize};
1615	/// # #[derive(Clone, Serialize, Deserialize)]
1616	/// # struct User { id: Option<i64> }
1617	/// #
1618	/// # #[derive(Clone)]
1619	/// # struct UserFields {
1620	/// #     pub id: Field<User, i64>,
1621	/// #     pub department_id: Field<User, i64>,
1622	/// # }
1623	/// # impl UserFields {
1624	/// #     pub fn new() -> Self {
1625	/// #         Self {
1626	/// #             id: Field::new(vec!["id"]),
1627	/// #             department_id: Field::new(vec!["department_id"]),
1628	/// #         }
1629	/// #     }
1630	/// # }
1631	/// # impl FieldSelector for UserFields {
1632	/// #     fn with_alias(mut self, alias: &str) -> Self {
1633	/// #         self.id = self.id.with_alias(alias);
1634	/// #         self.department_id = self.department_id.with_alias(alias);
1635	/// #         self
1636	/// #     }
1637	/// # }
1638	/// # impl Model for User {
1639	/// #     type PrimaryKey = i64;
1640	/// #     type Fields = UserFields;
1641	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1642	/// #     fn table_name() -> &'static str { "users" }
1643	/// #     fn new_fields() -> Self::Fields { UserFields::new() }
1644	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1645	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1646	/// # }
1647	/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
1648	/// // RIGHT JOIN: find all departments even if no users belong to them
1649	/// let sql = User::objects()
1650	///     .all()
1651	///     .right_join_as::<User, _>("u1", "u2", |u1, u2| u2.id.field_eq(u1.department_id))
1652	///     .to_sql();
1653	/// # Ok(())
1654	/// # }
1655	/// ```
1656	/// # Breaking Change
1657	///
1658	/// This method signature has been changed from string-based JOIN conditions
1659	/// to type-safe field comparisons.
1660	pub fn right_join_as<R: super::Model, F>(
1661		mut self,
1662		left_alias: &str,
1663		right_alias: &str,
1664		condition_fn: F,
1665	) -> Self
1666	where
1667		F: FnOnce(T::Fields, R::Fields) -> FieldComparison,
1668	{
1669		// Set base table alias
1670		if self.from_alias.is_none() {
1671			self.from_alias = Some(left_alias.to_string());
1672		}
1673
1674		// Create field selectors with aliases
1675		let left_fields = T::new_fields().with_alias(left_alias);
1676		let right_fields = R::new_fields().with_alias(right_alias);
1677
1678		// Get comparison from closure
1679		let comparison = condition_fn(left_fields, right_fields);
1680
1681		// Convert to SQL
1682		let condition = QueryFieldCompiler::compile_field_comparison(&comparison);
1683
1684		// Add to JoinClause
1685		self.joins.push(JoinClause {
1686			join_type: super::sqlalchemy_query::JoinType::Right,
1687			target_table: R::table_name().to_string(),
1688			target_alias: Some(right_alias.to_string()),
1689			on_condition: condition,
1690		});
1691
1692		self
1693	}
1694
1695	/// Add GROUP BY clause to the query
1696	///
1697	/// Groups rows that have the same values in specified columns into summary rows.
1698	/// Typically used with aggregate functions (COUNT, MAX, MIN, SUM, AVG).
1699	///
1700	/// # Type Parameters
1701	///
1702	/// * `F` - Closure that builds the GROUP BY field list
1703	///
1704	/// # Parameters
1705	///
1706	/// * `builder_fn` - Closure that receives a `GroupByBuilder` and returns it with fields set
1707	///
1708	/// # Examples
1709	///
1710	/// ```
1711	/// # use reinhardt_db::orm::{Model, query_fields::{Field, GroupByFields}, FieldSelector};
1712	/// # use serde::{Serialize, Deserialize};
1713	/// # #[derive(Clone, Serialize, Deserialize)]
1714	/// # struct Book { id: Option<i64> }
1715	/// #
1716	/// # #[derive(Clone)]
1717	/// # struct BookFields {
1718	/// #     pub author_id: Field<Book, i64>,
1719	/// # }
1720	/// # impl BookFields {
1721	/// #     pub fn new() -> Self {
1722	/// #         Self { author_id: Field::new(vec!["author_id"]) }
1723	/// #     }
1724	/// # }
1725	/// # impl FieldSelector for BookFields {
1726	/// #     fn with_alias(mut self, alias: &str) -> Self {
1727	/// #         self.author_id = self.author_id.with_alias(alias);
1728	/// #         self
1729	/// #     }
1730	/// # }
1731	/// # impl Model for Book {
1732	/// #     type PrimaryKey = i64;
1733	/// #     type Fields = BookFields;
1734	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1735	/// #     fn table_name() -> &'static str { "books" }
1736	/// #     fn new_fields() -> Self::Fields { BookFields::new() }
1737	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1738	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1739	/// # }
1740	/// # #[derive(Clone, Serialize, Deserialize)]
1741	/// # struct Sale { id: Option<i64> }
1742	/// #
1743	/// # #[derive(Clone)]
1744	/// # struct SaleFields {
1745	/// #     pub region: Field<Sale, String>,
1746	/// #     pub product_category: Field<Sale, String>,
1747	/// # }
1748	/// # impl SaleFields {
1749	/// #     pub fn new() -> Self {
1750	/// #         Self {
1751	/// #             region: Field::new(vec!["region"]),
1752	/// #             product_category: Field::new(vec!["product_category"]),
1753	/// #         }
1754	/// #     }
1755	/// # }
1756	/// # impl FieldSelector for SaleFields {
1757	/// #     fn with_alias(mut self, alias: &str) -> Self {
1758	/// #         self.region = self.region.with_alias(alias);
1759	/// #         self.product_category = self.product_category.with_alias(alias);
1760	/// #         self
1761	/// #     }
1762	/// # }
1763	/// # impl Model for Sale {
1764	/// #     type PrimaryKey = i64;
1765	/// #     type Fields = SaleFields;
1766	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1767	/// #     fn table_name() -> &'static str { "sales" }
1768	/// #     fn new_fields() -> Self::Fields { SaleFields::new() }
1769	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1770	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1771	/// # }
1772	/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
1773	/// // Group by single field
1774	/// let sql1 = Book::objects()
1775	///     .all()
1776	///     .group_by(|fields| GroupByFields::new().add(&fields.author_id))
1777	///     .to_sql();
1778	///
1779	/// // Group by multiple fields (chain .add())
1780	/// let sql2 = Sale::objects()
1781	///     .all()
1782	///     .group_by(|fields| GroupByFields::new().add(&fields.region).add(&fields.product_category))
1783	///     .to_sql();
1784	/// # Ok(())
1785	/// # }
1786	/// ```
1787	/// # Breaking Change
1788	///
1789	/// This method signature has been changed from string-based field selection
1790	/// to type-safe field selectors.
1791	pub fn group_by<F>(mut self, selector_fn: F) -> Self
1792	where
1793		F: FnOnce(T::Fields) -> GroupByFields,
1794	{
1795		let fields = T::new_fields();
1796		let group_by_fields = selector_fn(fields);
1797		self.group_by_fields = group_by_fields.build();
1798		self
1799	}
1800
1801	/// Add HAVING clause for AVG aggregate
1802	///
1803	/// Filters grouped rows based on the average value of a field.
1804	///
1805	/// # Type Parameters
1806	///
1807	/// * `F` - Closure that selects the field
1808	///
1809	/// # Parameters
1810	///
1811	/// * `field_fn` - Closure that receives a `HavingFieldSelector` and returns it with the field set
1812	/// * `operator` - Comparison operator (Eq, Ne, Gt, Gte, Lt, Lte)
1813	/// * `value` - Value to compare against
1814	///
1815	/// # Examples
1816	///
1817	/// ```
1818	/// # use reinhardt_db::orm::{Model, query_fields::{Field, GroupByFields}, FieldSelector};
1819	/// # use serde::{Serialize, Deserialize};
1820	/// # #[derive(Clone, Serialize, Deserialize)]
1821	/// # struct Author { id: Option<i64> }
1822	/// #
1823	/// # #[derive(Clone)]
1824	/// # struct AuthorFields {
1825	/// #     pub author_id: Field<Author, i64>,
1826	/// #     pub price: Field<Author, f64>,
1827	/// # }
1828	/// # impl AuthorFields {
1829	/// #     pub fn new() -> Self {
1830	/// #         Self {
1831	/// #             author_id: Field::new(vec!["author_id"]),
1832	/// #             price: Field::new(vec!["price"]),
1833	/// #         }
1834	/// #     }
1835	/// # }
1836	/// # impl FieldSelector for AuthorFields {
1837	/// #     fn with_alias(mut self, alias: &str) -> Self {
1838	/// #         self.author_id = self.author_id.with_alias(alias);
1839	/// #         self.price = self.price.with_alias(alias);
1840	/// #         self
1841	/// #     }
1842	/// # }
1843	/// # impl Model for Author {
1844	/// #     type PrimaryKey = i64;
1845	/// #     type Fields = AuthorFields;
1846	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1847	/// #     fn table_name() -> &'static str { "authors" }
1848	/// #     fn new_fields() -> Self::Fields { AuthorFields::new() }
1849	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1850	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1851	/// # }
1852	/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
1853	/// // Find authors with average book price > 1500
1854	/// let sql = Author::objects()
1855	///     .all()
1856	///     .group_by(|fields| GroupByFields::new().add(&fields.author_id))
1857	///     .having_avg(|fields| &fields.price, |avg| avg.gt(1500.0))
1858	///     .to_sql();
1859	/// # Ok(())
1860	/// # }
1861	/// ```
1862	/// # Breaking Change
1863	///
1864	/// This method signature has been changed to use type-safe field selectors
1865	/// and aggregate expressions.
1866	pub fn having_avg<FS, FE, NT>(mut self, field_selector: FS, expr_fn: FE) -> Self
1867	where
1868		FS: FnOnce(&T::Fields) -> &super::query_fields::Field<T, NT>,
1869		NT: super::query_fields::NumericType,
1870		FE: FnOnce(AggregateExpr) -> ComparisonExpr,
1871	{
1872		let fields = T::new_fields();
1873		let field = field_selector(&fields);
1874		let field_path = field.path().join(".");
1875
1876		let avg_expr = AggregateExpr::avg(&field_path);
1877		let comparison = expr_fn(avg_expr);
1878
1879		// Extract components for HavingCondition
1880		let operator = match comparison.op {
1881			super::query_fields::comparison::ComparisonOperator::Eq => ComparisonOp::Eq,
1882			super::query_fields::comparison::ComparisonOperator::Ne => ComparisonOp::Ne,
1883			super::query_fields::comparison::ComparisonOperator::Gt => ComparisonOp::Gt,
1884			super::query_fields::comparison::ComparisonOperator::Gte => ComparisonOp::Gte,
1885			super::query_fields::comparison::ComparisonOperator::Lt => ComparisonOp::Lt,
1886			super::query_fields::comparison::ComparisonOperator::Lte => ComparisonOp::Lte,
1887		};
1888
1889		let value = match comparison.value {
1890			super::query_fields::aggregate::ComparisonValue::Int(i) => {
1891				AggregateValue::Float(i as f64)
1892			}
1893			super::query_fields::aggregate::ComparisonValue::Float(f) => AggregateValue::Float(f),
1894		};
1895
1896		self.having_conditions
1897			.push(HavingCondition::AggregateCompare {
1898				func: AggregateFunc::Avg,
1899				field: comparison.aggregate.field().to_string(),
1900				operator,
1901				value,
1902			});
1903		self
1904	}
1905
1906	/// Add HAVING clause for COUNT aggregate
1907	///
1908	/// Filters grouped rows based on the count of rows in each group.
1909	///
1910	/// # Type Parameters
1911	///
1912	/// * `F` - Closure that selects the field
1913	///
1914	/// # Parameters
1915	///
1916	/// * `field_fn` - Closure that receives a `HavingFieldSelector` and returns it with the field set
1917	/// * `operator` - Comparison operator (Eq, Ne, Gt, Gte, Lt, Lte)
1918	/// * `value` - Value to compare against
1919	///
1920	/// # Examples
1921	///
1922	/// ```
1923	/// # use reinhardt_db::orm::{Model, query_fields::{Field, GroupByFields}, FieldSelector};
1924	/// # use serde::{Serialize, Deserialize};
1925	/// # #[derive(Clone, Serialize, Deserialize)]
1926	/// # struct Author { id: Option<i64> }
1927	/// #
1928	/// # #[derive(Clone)]
1929	/// # struct AuthorFields {
1930	/// #     pub author_id: Field<Author, i64>,
1931	/// # }
1932	/// # impl AuthorFields {
1933	/// #     pub fn new() -> Self {
1934	/// #         Self { author_id: Field::new(vec!["author_id"]) }
1935	/// #     }
1936	/// # }
1937	/// # impl FieldSelector for AuthorFields {
1938	/// #     fn with_alias(mut self, alias: &str) -> Self {
1939	/// #         self.author_id = self.author_id.with_alias(alias);
1940	/// #         self
1941	/// #     }
1942	/// # }
1943	/// # impl Model for Author {
1944	/// #     type PrimaryKey = i64;
1945	/// #     type Fields = AuthorFields;
1946	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
1947	/// #     fn table_name() -> &'static str { "authors" }
1948	/// #     fn new_fields() -> Self::Fields { AuthorFields::new() }
1949	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
1950	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
1951	/// # }
1952	/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
1953	/// // Find authors with more than 5 books
1954	/// let sql = Author::objects()
1955	///     .all()
1956	///     .group_by(|fields| GroupByFields::new().add(&fields.author_id))
1957	///     .having_count(|count| count.gt(5))
1958	///     .to_sql();
1959	/// # Ok(())
1960	/// # }
1961	/// ```
1962	/// # Breaking Change
1963	///
1964	/// This method signature has been changed to use type-safe aggregate expressions.
1965	pub fn having_count<F>(mut self, expr_fn: F) -> Self
1966	where
1967		F: FnOnce(AggregateExpr) -> ComparisonExpr,
1968	{
1969		let count_expr = AggregateExpr::count("*");
1970		let comparison = expr_fn(count_expr);
1971
1972		// Extract components for HavingCondition
1973		let operator = match comparison.op {
1974			super::query_fields::comparison::ComparisonOperator::Eq => ComparisonOp::Eq,
1975			super::query_fields::comparison::ComparisonOperator::Ne => ComparisonOp::Ne,
1976			super::query_fields::comparison::ComparisonOperator::Gt => ComparisonOp::Gt,
1977			super::query_fields::comparison::ComparisonOperator::Gte => ComparisonOp::Gte,
1978			super::query_fields::comparison::ComparisonOperator::Lt => ComparisonOp::Lt,
1979			super::query_fields::comparison::ComparisonOperator::Lte => ComparisonOp::Lte,
1980		};
1981
1982		let value = match comparison.value {
1983			super::query_fields::aggregate::ComparisonValue::Int(i) => AggregateValue::Int(i),
1984			super::query_fields::aggregate::ComparisonValue::Float(f) => AggregateValue::Float(f),
1985		};
1986
1987		self.having_conditions
1988			.push(HavingCondition::AggregateCompare {
1989				func: AggregateFunc::Count,
1990				field: comparison.aggregate.field().to_string(),
1991				operator,
1992				value,
1993			});
1994		self
1995	}
1996
1997	/// Add HAVING clause for SUM aggregate
1998	///
1999	/// Filters grouped rows based on the sum of values in a field.
2000	///
2001	/// # Type Parameters
2002	///
2003	/// * `F` - Closure that selects the field
2004	///
2005	/// # Parameters
2006	///
2007	/// * `field_fn` - Closure that receives a `HavingFieldSelector` and returns it with the field set
2008	/// * `operator` - Comparison operator (Eq, Ne, Gt, Gte, Lt, Lte)
2009	/// * `value` - Value to compare against
2010	///
2011	/// # Examples
2012	///
2013	/// ```
2014	/// # use reinhardt_db::orm::{Model, query_fields::{Field, GroupByFields}, FieldSelector};
2015	/// # use serde::{Serialize, Deserialize};
2016	/// # #[derive(Clone, Serialize, Deserialize)]
2017	/// # struct Product { id: Option<i64> }
2018	/// #
2019	/// # #[derive(Clone)]
2020	/// # struct ProductFields {
2021	/// #     pub category: Field<Product, String>,
2022	/// #     pub sales_amount: Field<Product, f64>,
2023	/// # }
2024	/// # impl ProductFields {
2025	/// #     pub fn new() -> Self {
2026	/// #         Self {
2027	/// #             category: Field::new(vec!["category"]),
2028	/// #             sales_amount: Field::new(vec!["sales_amount"]),
2029	/// #         }
2030	/// #     }
2031	/// # }
2032	/// # impl FieldSelector for ProductFields {
2033	/// #     fn with_alias(mut self, alias: &str) -> Self {
2034	/// #         self.category = self.category.with_alias(alias);
2035	/// #         self.sales_amount = self.sales_amount.with_alias(alias);
2036	/// #         self
2037	/// #     }
2038	/// # }
2039	/// # impl Model for Product {
2040	/// #     type PrimaryKey = i64;
2041	/// #     type Fields = ProductFields;
2042	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
2043	/// #     fn table_name() -> &'static str { "products" }
2044	/// #     fn new_fields() -> Self::Fields { ProductFields::new() }
2045	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
2046	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
2047	/// # }
2048	/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
2049	/// // Find categories with total sales > 10000
2050	/// let sql = Product::objects()
2051	///     .all()
2052	///     .group_by(|fields| GroupByFields::new().add(&fields.category))
2053	///     .having_sum(|fields| &fields.sales_amount, |sum| sum.gt(10000.0))
2054	///     .to_sql();
2055	/// # Ok(())
2056	/// # }
2057	/// ```
2058	/// # Breaking Change
2059	///
2060	/// This method signature has been changed to use type-safe field selectors.
2061	pub fn having_sum<FS, FE, NT>(mut self, field_selector: FS, expr_fn: FE) -> Self
2062	where
2063		FS: FnOnce(&T::Fields) -> &super::query_fields::Field<T, NT>,
2064		NT: super::query_fields::NumericType,
2065		FE: FnOnce(AggregateExpr) -> ComparisonExpr,
2066	{
2067		let fields = T::new_fields();
2068		let field = field_selector(&fields);
2069		let field_path = field.path().join(".");
2070
2071		let sum_expr = AggregateExpr::sum(&field_path);
2072		let comparison = expr_fn(sum_expr);
2073
2074		let operator = match comparison.op {
2075			super::query_fields::comparison::ComparisonOperator::Eq => ComparisonOp::Eq,
2076			super::query_fields::comparison::ComparisonOperator::Ne => ComparisonOp::Ne,
2077			super::query_fields::comparison::ComparisonOperator::Gt => ComparisonOp::Gt,
2078			super::query_fields::comparison::ComparisonOperator::Gte => ComparisonOp::Gte,
2079			super::query_fields::comparison::ComparisonOperator::Lt => ComparisonOp::Lt,
2080			super::query_fields::comparison::ComparisonOperator::Lte => ComparisonOp::Lte,
2081		};
2082
2083		let value = match comparison.value {
2084			super::query_fields::aggregate::ComparisonValue::Int(i) => AggregateValue::Int(i),
2085			super::query_fields::aggregate::ComparisonValue::Float(f) => AggregateValue::Float(f),
2086		};
2087
2088		self.having_conditions
2089			.push(HavingCondition::AggregateCompare {
2090				func: AggregateFunc::Sum,
2091				field: comparison.aggregate.field().to_string(),
2092				operator,
2093				value,
2094			});
2095		self
2096	}
2097
2098	/// Add HAVING clause for MIN aggregate
2099	///
2100	/// Filters grouped rows based on the minimum value in a field.
2101	///
2102	/// # Breaking Change
2103	///
2104	/// This method signature has been changed to use type-safe field selectors.
2105	///
2106	/// # Type Parameters
2107	///
2108	/// * `FS` - Field selector closure that returns a reference to a numeric field
2109	/// * `FE` - Expression closure that builds the comparison expression
2110	///
2111	/// # Parameters
2112	///
2113	/// * `field_selector` - Closure that selects the field from the model
2114	/// * `expr_fn` - Closure that builds the comparison expression using method chaining
2115	///
2116	/// # Examples
2117	///
2118	/// ```
2119	/// # use reinhardt_db::orm::{Model, query_fields::{Field, GroupByFields}, FieldSelector};
2120	/// # use serde::{Serialize, Deserialize};
2121	/// # #[derive(Clone, Serialize, Deserialize)]
2122	/// # struct Author { id: Option<i64> }
2123	/// #
2124	/// # #[derive(Clone)]
2125	/// # struct AuthorFields {
2126	/// #     pub author_id: Field<Author, i64>,
2127	/// #     pub price: Field<Author, f64>,
2128	/// # }
2129	/// # impl AuthorFields {
2130	/// #     pub fn new() -> Self {
2131	/// #         Self {
2132	/// #             author_id: Field::new(vec!["author_id"]),
2133	/// #             price: Field::new(vec!["price"]),
2134	/// #         }
2135	/// #     }
2136	/// # }
2137	/// # impl FieldSelector for AuthorFields {
2138	/// #     fn with_alias(mut self, alias: &str) -> Self {
2139	/// #         self.author_id = self.author_id.with_alias(alias);
2140	/// #         self.price = self.price.with_alias(alias);
2141	/// #         self
2142	/// #     }
2143	/// # }
2144	/// # impl Model for Author {
2145	/// #     type PrimaryKey = i64;
2146	/// #     type Fields = AuthorFields;
2147	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
2148	/// #     fn table_name() -> &'static str { "authors" }
2149	/// #     fn new_fields() -> Self::Fields { AuthorFields::new() }
2150	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
2151	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
2152	/// # }
2153	/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
2154	/// // Find authors where minimum book price > 1000
2155	/// let sql = Author::objects()
2156	///     .all()
2157	///     .group_by(|fields| GroupByFields::new().add(&fields.author_id))
2158	///     .having_min(|fields| &fields.price, |min| min.gt(1000.0))
2159	///     .to_sql();
2160	/// # Ok(())
2161	/// # }
2162	/// ```
2163	pub fn having_min<FS, FE, NT>(mut self, field_selector: FS, expr_fn: FE) -> Self
2164	where
2165		FS: FnOnce(&T::Fields) -> &super::query_fields::Field<T, NT>,
2166		NT: super::query_fields::NumericType,
2167		FE: FnOnce(AggregateExpr) -> ComparisonExpr,
2168	{
2169		let fields = T::new_fields();
2170		let field = field_selector(&fields);
2171		let field_path = field.path().join(".");
2172
2173		let min_expr = AggregateExpr::min(&field_path);
2174		let comparison = expr_fn(min_expr);
2175
2176		let operator = match comparison.op {
2177			super::query_fields::comparison::ComparisonOperator::Eq => ComparisonOp::Eq,
2178			super::query_fields::comparison::ComparisonOperator::Ne => ComparisonOp::Ne,
2179			super::query_fields::comparison::ComparisonOperator::Gt => ComparisonOp::Gt,
2180			super::query_fields::comparison::ComparisonOperator::Gte => ComparisonOp::Gte,
2181			super::query_fields::comparison::ComparisonOperator::Lt => ComparisonOp::Lt,
2182			super::query_fields::comparison::ComparisonOperator::Lte => ComparisonOp::Lte,
2183		};
2184
2185		let value = match comparison.value {
2186			super::query_fields::aggregate::ComparisonValue::Int(i) => AggregateValue::Int(i),
2187			super::query_fields::aggregate::ComparisonValue::Float(f) => AggregateValue::Float(f),
2188		};
2189
2190		self.having_conditions
2191			.push(HavingCondition::AggregateCompare {
2192				func: AggregateFunc::Min,
2193				field: comparison.aggregate.field().to_string(),
2194				operator,
2195				value,
2196			});
2197		self
2198	}
2199
2200	/// Add HAVING clause for MAX aggregate
2201	///
2202	/// Filters grouped rows based on the maximum value in a field.
2203	///
2204	/// # Breaking Change
2205	///
2206	/// This method signature has been changed to use type-safe field selectors.
2207	///
2208	/// # Type Parameters
2209	///
2210	/// * `FS` - Field selector closure that returns a reference to a numeric field
2211	/// * `FE` - Expression closure that builds the comparison expression
2212	///
2213	/// # Parameters
2214	///
2215	/// * `field_selector` - Closure that selects the field from the model
2216	/// * `expr_fn` - Closure that builds the comparison expression using method chaining
2217	///
2218	/// # Examples
2219	///
2220	/// ```
2221	/// # use reinhardt_db::orm::{Model, query_fields::{Field, GroupByFields}, FieldSelector};
2222	/// # use serde::{Serialize, Deserialize};
2223	/// # #[derive(Clone, Serialize, Deserialize)]
2224	/// # struct Author { id: Option<i64> }
2225	/// #
2226	/// # #[derive(Clone)]
2227	/// # struct AuthorFields {
2228	/// #     pub author_id: Field<Author, i64>,
2229	/// #     pub price: Field<Author, f64>,
2230	/// # }
2231	/// # impl AuthorFields {
2232	/// #     pub fn new() -> Self {
2233	/// #         Self {
2234	/// #             author_id: Field::new(vec!["author_id"]),
2235	/// #             price: Field::new(vec!["price"]),
2236	/// #         }
2237	/// #     }
2238	/// # }
2239	/// # impl FieldSelector for AuthorFields {
2240	/// #     fn with_alias(mut self, alias: &str) -> Self {
2241	/// #         self.author_id = self.author_id.with_alias(alias);
2242	/// #         self.price = self.price.with_alias(alias);
2243	/// #         self
2244	/// #     }
2245	/// # }
2246	/// # impl Model for Author {
2247	/// #     type PrimaryKey = i64;
2248	/// #     type Fields = AuthorFields;
2249	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
2250	/// #     fn table_name() -> &'static str { "authors" }
2251	/// #     fn new_fields() -> Self::Fields { AuthorFields::new() }
2252	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
2253	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
2254	/// # }
2255	/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
2256	/// // Find authors where maximum book price < 5000
2257	/// let sql = Author::objects()
2258	///     .all()
2259	///     .group_by(|fields| GroupByFields::new().add(&fields.author_id))
2260	///     .having_max(|fields| &fields.price, |max| max.lt(5000.0))
2261	///     .to_sql();
2262	/// # Ok(())
2263	/// # }
2264	/// ```
2265	pub fn having_max<FS, FE, NT>(mut self, field_selector: FS, expr_fn: FE) -> Self
2266	where
2267		FS: FnOnce(&T::Fields) -> &super::query_fields::Field<T, NT>,
2268		NT: super::query_fields::NumericType,
2269		FE: FnOnce(AggregateExpr) -> ComparisonExpr,
2270	{
2271		let fields = T::new_fields();
2272		let field = field_selector(&fields);
2273		let field_path = field.path().join(".");
2274
2275		let max_expr = AggregateExpr::max(&field_path);
2276		let comparison = expr_fn(max_expr);
2277
2278		let operator = match comparison.op {
2279			super::query_fields::comparison::ComparisonOperator::Eq => ComparisonOp::Eq,
2280			super::query_fields::comparison::ComparisonOperator::Ne => ComparisonOp::Ne,
2281			super::query_fields::comparison::ComparisonOperator::Gt => ComparisonOp::Gt,
2282			super::query_fields::comparison::ComparisonOperator::Gte => ComparisonOp::Gte,
2283			super::query_fields::comparison::ComparisonOperator::Lt => ComparisonOp::Lt,
2284			super::query_fields::comparison::ComparisonOperator::Lte => ComparisonOp::Lte,
2285		};
2286
2287		let value = match comparison.value {
2288			super::query_fields::aggregate::ComparisonValue::Int(i) => AggregateValue::Int(i),
2289			super::query_fields::aggregate::ComparisonValue::Float(f) => AggregateValue::Float(f),
2290		};
2291
2292		self.having_conditions
2293			.push(HavingCondition::AggregateCompare {
2294				func: AggregateFunc::Max,
2295				field: comparison.aggregate.field().to_string(),
2296				operator,
2297				value,
2298			});
2299		self
2300	}
2301
2302	/// Add WHERE IN (subquery) condition
2303	///
2304	/// Filters rows where the specified field's value is in the result set of a subquery.
2305	///
2306	/// # Type Parameters
2307	///
2308	/// * `R` - The model type used in the subquery (must implement `Model` trait)
2309	/// * `F` - Function that builds the subquery QuerySet
2310	///
2311	/// # Examples
2312	///
2313	/// ```no_run
2314	/// # use reinhardt_db::orm::Model;
2315	/// # use reinhardt_db::orm::{QuerySet, Filter, FilterOperator, FilterValue};
2316	/// # use serde::{Serialize, Deserialize};
2317	/// # #[derive(Clone, Serialize, Deserialize)]
2318	/// # struct Author { id: Option<i64> }
2319	/// # #[derive(Clone)]
2320	/// # struct AuthorFields;
2321	/// # impl reinhardt_db::orm::model::FieldSelector for AuthorFields {
2322	/// #     fn with_alias(self, _alias: &str) -> Self { self }
2323	/// # }
2324	/// # impl Model for Author {
2325	/// #     type PrimaryKey = i64;
2326	/// #     type Fields = AuthorFields;
2327	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
2328	/// #     fn table_name() -> &'static str { "authors" }
2329	/// #     fn new_fields() -> Self::Fields { AuthorFields }
2330	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
2331	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
2332	/// # }
2333	/// # #[derive(Clone, Serialize, Deserialize)]
2334	/// # struct Book { id: Option<i64> }
2335	/// # #[derive(Clone)]
2336	/// # struct BookFields;
2337	/// # impl reinhardt_db::orm::model::FieldSelector for BookFields {
2338	/// #     fn with_alias(self, _alias: &str) -> Self { self }
2339	/// # }
2340	/// # impl Model for Book {
2341	/// #     type PrimaryKey = i64;
2342	/// #     type Fields = BookFields;
2343	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
2344	/// #     fn table_name() -> &'static str { "books" }
2345	/// #     fn new_fields() -> Self::Fields { BookFields }
2346	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
2347	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
2348	/// # }
2349	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
2350	/// // Find authors who have books priced over 1500
2351	/// let authors = Author::objects()
2352	///     .filter_in_subquery("id", |subq: QuerySet<Book>| {
2353	///         subq.filter(Filter::new("price", FilterOperator::Gt, FilterValue::Int(1500)))
2354	///             .values(&["author_id"])
2355	///     })
2356	///     .all()
2357	///     .await?;
2358	/// # Ok(())
2359	/// # }
2360	/// ```
2361	pub fn filter_in_subquery<R: super::Model, F>(mut self, field: &str, subquery_fn: F) -> Self
2362	where
2363		F: FnOnce(QuerySet<R>) -> QuerySet<R>,
2364	{
2365		let subquery_qs = subquery_fn(QuerySet::<R>::new());
2366		let subquery_sql = subquery_qs.as_subquery();
2367
2368		self.subquery_conditions.push(SubqueryCondition::In {
2369			field: field.to_string(),
2370			subquery: subquery_sql,
2371		});
2372
2373		self
2374	}
2375
2376	/// Add WHERE NOT IN (subquery) condition
2377	///
2378	/// Filters rows where the specified field's value is NOT in the result set of a subquery.
2379	///
2380	/// # Examples
2381	///
2382	/// ```no_run
2383	/// # use reinhardt_db::orm::Model;
2384	/// # use reinhardt_db::orm::{QuerySet, Filter, FilterOperator, FilterValue};
2385	/// # use serde::{Serialize, Deserialize};
2386	/// # #[derive(Clone, Serialize, Deserialize)]
2387	/// # struct Author { id: Option<i64> }
2388	/// # #[derive(Clone)]
2389	/// # struct AuthorFields;
2390	/// # impl reinhardt_db::orm::model::FieldSelector for AuthorFields {
2391	/// #     fn with_alias(self, _alias: &str) -> Self { self }
2392	/// # }
2393	/// # impl Model for Author {
2394	/// #     type PrimaryKey = i64;
2395	/// #     type Fields = AuthorFields;
2396	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
2397	/// #     fn table_name() -> &'static str { "authors" }
2398	/// #     fn new_fields() -> Self::Fields { AuthorFields }
2399	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
2400	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
2401	/// # }
2402	/// # #[derive(Clone, Serialize, Deserialize)]
2403	/// # struct Book { id: Option<i64> }
2404	/// # #[derive(Clone)]
2405	/// # struct BookFields;
2406	/// # impl reinhardt_db::orm::model::FieldSelector for BookFields {
2407	/// #     fn with_alias(self, _alias: &str) -> Self { self }
2408	/// # }
2409	/// # impl Model for Book {
2410	/// #     type PrimaryKey = i64;
2411	/// #     type Fields = BookFields;
2412	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
2413	/// #     fn table_name() -> &'static str { "books" }
2414	/// #     fn new_fields() -> Self::Fields { BookFields }
2415	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
2416	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
2417	/// # }
2418	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
2419	/// // Find authors who have NO books priced over 1500
2420	/// let authors = Author::objects()
2421	///     .filter_not_in_subquery("id", |subq: QuerySet<Book>| {
2422	///         subq.filter(Filter::new("price", FilterOperator::Gt, FilterValue::Int(1500)))
2423	///             .values(&["author_id"])
2424	///     })
2425	///     .all()
2426	///     .await?;
2427	/// # Ok(())
2428	/// # }
2429	/// ```
2430	pub fn filter_not_in_subquery<R: super::Model, F>(mut self, field: &str, subquery_fn: F) -> Self
2431	where
2432		F: FnOnce(QuerySet<R>) -> QuerySet<R>,
2433	{
2434		let subquery_qs = subquery_fn(QuerySet::<R>::new());
2435		let subquery_sql = subquery_qs.as_subquery();
2436
2437		self.subquery_conditions.push(SubqueryCondition::NotIn {
2438			field: field.to_string(),
2439			subquery: subquery_sql,
2440		});
2441
2442		self
2443	}
2444
2445	/// Add WHERE EXISTS (subquery) condition
2446	///
2447	/// Filters rows where the subquery returns at least one row.
2448	/// Typically used with correlated subqueries.
2449	///
2450	/// # Examples
2451	///
2452	/// ```no_run
2453	/// # use reinhardt_db::orm::Model;
2454	/// # use reinhardt_db::orm::{QuerySet, Filter, FilterOperator, FilterValue};
2455	/// # use serde::{Serialize, Deserialize};
2456	/// # #[derive(Clone, Serialize, Deserialize)]
2457	/// # struct Author { id: Option<i64> }
2458	/// # #[derive(Clone)]
2459	/// # struct AuthorFields;
2460	/// # impl reinhardt_db::orm::model::FieldSelector for AuthorFields {
2461	/// #     fn with_alias(self, _alias: &str) -> Self { self }
2462	/// # }
2463	/// # impl Model for Author {
2464	/// #     type PrimaryKey = i64;
2465	/// #     type Fields = AuthorFields;
2466	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
2467	/// #     fn table_name() -> &'static str { "authors" }
2468	/// #     fn new_fields() -> Self::Fields { AuthorFields }
2469	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
2470	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
2471	/// # }
2472	/// # #[derive(Clone, Serialize, Deserialize)]
2473	/// # struct Book { id: Option<i64> }
2474	/// # #[derive(Clone)]
2475	/// # struct BookFields;
2476	/// # impl reinhardt_db::orm::model::FieldSelector for BookFields {
2477	/// #     fn with_alias(self, _alias: &str) -> Self { self }
2478	/// # }
2479	/// # impl Model for Book {
2480	/// #     type PrimaryKey = i64;
2481	/// #     type Fields = BookFields;
2482	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
2483	/// #     fn table_name() -> &'static str { "books" }
2484	/// #     fn new_fields() -> Self::Fields { BookFields }
2485	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
2486	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
2487	/// # }
2488	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
2489	/// use reinhardt_db::orm::F;
2490	/// // Find authors who have at least one book
2491	/// let authors = Author::objects()
2492	///     .filter_exists(|subq: QuerySet<Book>| {
2493	///         subq.filter(Filter::new("author_id", FilterOperator::Eq, FilterValue::FieldRef(F::new("authors.id"))))
2494	///     })
2495	///     .all()
2496	///     .await?;
2497	/// # Ok(())
2498	/// # }
2499	/// ```
2500	pub fn filter_exists<R: super::Model, F>(mut self, subquery_fn: F) -> Self
2501	where
2502		F: FnOnce(QuerySet<R>) -> QuerySet<R>,
2503	{
2504		let subquery_qs = subquery_fn(QuerySet::<R>::new());
2505		let subquery_sql = subquery_qs.as_subquery();
2506
2507		self.subquery_conditions.push(SubqueryCondition::Exists {
2508			subquery: subquery_sql,
2509		});
2510
2511		self
2512	}
2513
2514	/// Add WHERE NOT EXISTS (subquery) condition
2515	///
2516	/// Filters rows where the subquery returns no rows.
2517	/// Typically used with correlated subqueries.
2518	///
2519	/// # Examples
2520	///
2521	/// ```no_run
2522	/// # use reinhardt_db::orm::Model;
2523	/// # use reinhardt_db::orm::{QuerySet, Filter, FilterOperator, FilterValue};
2524	/// # use serde::{Serialize, Deserialize};
2525	/// # #[derive(Clone, Serialize, Deserialize)]
2526	/// # struct Author { id: Option<i64> }
2527	/// # #[derive(Clone)]
2528	/// # struct AuthorFields;
2529	/// # impl reinhardt_db::orm::model::FieldSelector for AuthorFields {
2530	/// #     fn with_alias(self, _alias: &str) -> Self { self }
2531	/// # }
2532	/// # impl Model for Author {
2533	/// #     type PrimaryKey = i64;
2534	/// #     type Fields = AuthorFields;
2535	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
2536	/// #     fn table_name() -> &'static str { "authors" }
2537	/// #     fn new_fields() -> Self::Fields { AuthorFields }
2538	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
2539	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
2540	/// # }
2541	/// # #[derive(Clone, Serialize, Deserialize)]
2542	/// # struct Book { id: Option<i64> }
2543	/// # #[derive(Clone)]
2544	/// # struct BookFields;
2545	/// # impl reinhardt_db::orm::model::FieldSelector for BookFields {
2546	/// #     fn with_alias(self, _alias: &str) -> Self { self }
2547	/// # }
2548	/// # impl Model for Book {
2549	/// #     type PrimaryKey = i64;
2550	/// #     type Fields = BookFields;
2551	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
2552	/// #     fn table_name() -> &'static str { "books" }
2553	/// #     fn new_fields() -> Self::Fields { BookFields }
2554	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
2555	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
2556	/// # }
2557	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
2558	/// use reinhardt_db::orm::F;
2559	/// // Find authors who have NO books
2560	/// let authors = Author::objects()
2561	///     .filter_not_exists(|subq: QuerySet<Book>| {
2562	///         subq.filter(Filter::new("author_id", FilterOperator::Eq, FilterValue::FieldRef(F::new("authors.id"))))
2563	///     })
2564	///     .all()
2565	///     .await?;
2566	/// # Ok(())
2567	/// # }
2568	/// ```
2569	pub fn filter_not_exists<R: super::Model, F>(mut self, subquery_fn: F) -> Self
2570	where
2571		F: FnOnce(QuerySet<R>) -> QuerySet<R>,
2572	{
2573		let subquery_qs = subquery_fn(QuerySet::<R>::new());
2574		let subquery_sql = subquery_qs.as_subquery();
2575
2576		self.subquery_conditions.push(SubqueryCondition::NotExists {
2577			subquery: subquery_sql,
2578		});
2579
2580		self
2581	}
2582
2583	/// Add a Common Table Expression (WITH clause) to the query
2584	///
2585	/// CTEs allow you to define named subqueries that can be referenced
2586	/// in the main query. This is useful for complex queries that need
2587	/// to reference the same subquery multiple times or for recursive queries.
2588	///
2589	/// # Examples
2590	///
2591	/// ```no_run
2592	/// # use reinhardt_db::orm::Model;
2593	/// # use reinhardt_db::orm::cte::CTE;
2594	/// # use serde::{Serialize, Deserialize};
2595	/// # #[derive(Clone, Serialize, Deserialize)]
2596	/// # struct Employee { id: Option<i64> }
2597	/// # #[derive(Clone)]
2598	/// # struct EmployeeFields;
2599	/// # impl reinhardt_db::orm::model::FieldSelector for EmployeeFields {
2600	/// #     fn with_alias(self, _alias: &str) -> Self { self }
2601	/// # }
2602	/// # impl Model for Employee {
2603	/// #     type PrimaryKey = i64;
2604	/// #     type Fields = EmployeeFields;
2605	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
2606	/// #     fn table_name() -> &'static str { "employees" }
2607	/// #     fn new_fields() -> Self::Fields { EmployeeFields }
2608	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
2609	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
2610	/// # }
2611	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
2612	/// // Simple CTE
2613	/// let high_earners = CTE::new("high_earners", "SELECT * FROM employees WHERE salary > 100000");
2614	/// let results = Employee::objects()
2615	///     .with_cte(high_earners)
2616	///     .all()
2617	///     .await?;
2618	///
2619	/// // Recursive CTE for hierarchical data
2620	/// let hierarchy = CTE::new(
2621	///     "org_hierarchy",
2622	///     "SELECT id, name, manager_id, 1 as level FROM employees WHERE manager_id IS NULL \
2623	///      UNION ALL \
2624	///      SELECT e.id, e.name, e.manager_id, h.level + 1 \
2625	///      FROM employees e JOIN org_hierarchy h ON e.manager_id = h.id"
2626	/// ).recursive();
2627	///
2628	/// let org = Employee::objects()
2629	///     .with_cte(hierarchy)
2630	///     .all()
2631	///     .await?;
2632	/// # Ok(())
2633	/// # }
2634	/// ```
2635	pub fn with_cte(mut self, cte: super::cte::CTE) -> Self {
2636		self.ctes.add(cte);
2637		self
2638	}
2639
2640	/// Add a LATERAL JOIN to the query
2641	///
2642	/// LATERAL JOINs allow correlated subqueries in the FROM clause,
2643	/// where the subquery can reference columns from preceding tables.
2644	/// This is useful for "top-N per group" queries and similar patterns.
2645	///
2646	/// **Note**: LATERAL JOIN is supported in PostgreSQL 9.3+, MySQL 8.0.14+,
2647	/// but NOT in SQLite.
2648	///
2649	/// # Examples
2650	///
2651	/// ```no_run
2652	/// # use reinhardt_db::orm::Model;
2653	/// # use serde::{Serialize, Deserialize};
2654	/// # #[derive(Clone, Serialize, Deserialize)]
2655	/// # struct Customer { id: Option<i64> }
2656	/// # #[derive(Clone)]
2657	/// # struct CustomerFields;
2658	/// # impl reinhardt_db::orm::model::FieldSelector for CustomerFields {
2659	/// #     fn with_alias(self, _alias: &str) -> Self { self }
2660	/// # }
2661	/// # impl Model for Customer {
2662	/// #     type PrimaryKey = i64;
2663	/// #     type Fields = CustomerFields;
2664	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
2665	/// #     fn table_name() -> &'static str { "customers" }
2666	/// #     fn new_fields() -> Self::Fields { CustomerFields }
2667	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
2668	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
2669	/// # }
2670	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
2671	/// use reinhardt_db::orm::lateral_join::{LateralJoin, LateralJoinPatterns};
2672	///
2673	/// // Get top 3 orders per customer
2674	/// let top_orders = LateralJoinPatterns::top_n_per_group(
2675	///     "recent_orders",
2676	///     "orders",
2677	///     "customer_id",
2678	///     "customers",
2679	///     "created_at DESC",
2680	///     3,
2681	/// );
2682	///
2683	/// let results = Customer::objects()
2684	///     .all()
2685	///     .with_lateral_join(top_orders)
2686	///     .all()
2687	///     .await?;
2688	///
2689	/// // Get latest order per customer
2690	/// let latest = LateralJoinPatterns::latest_per_parent(
2691	///     "latest_order",
2692	///     "orders",
2693	///     "customer_id",
2694	///     "customers",
2695	///     "created_at",
2696	/// );
2697	///
2698	/// let customers_with_orders = Customer::objects()
2699	///     .all()
2700	///     .with_lateral_join(latest)
2701	///     .all()
2702	///     .await?;
2703	/// # Ok(())
2704	/// # }
2705	/// ```
2706	pub fn with_lateral_join(mut self, join: super::lateral_join::LateralJoin) -> Self {
2707		self.lateral_joins.add(join);
2708		self
2709	}
2710
2711	/// Build WHERE condition using reinhardt-query from accumulated filters
2712	fn build_where_condition(&self) -> reinhardt_core::exception::Result<Option<Condition>> {
2713		if !self.has_where_predicates() {
2714			return Ok(None);
2715		}
2716
2717		let mut cond = Condition::all();
2718		let mut added = false;
2719
2720		for filter in &self.filters {
2721			let col = Self::filter_lhs_expr(filter);
2722
2723			let expr = match (&filter.operator, &filter.value) {
2724				// Field-to-field comparisons (must come before generic patterns)
2725				(FilterOperator::Eq, FilterValue::FieldRef(f)) => {
2726					col.eq(Expr::col(Alias::new(&f.field)))
2727				}
2728				(FilterOperator::Ne, FilterValue::FieldRef(f)) => {
2729					col.ne(Expr::col(Alias::new(&f.field)))
2730				}
2731				(FilterOperator::Gt, FilterValue::FieldRef(f)) => {
2732					col.gt(Expr::col(Alias::new(&f.field)))
2733				}
2734				(FilterOperator::Gte, FilterValue::FieldRef(f)) => {
2735					col.gte(Expr::col(Alias::new(&f.field)))
2736				}
2737				(FilterOperator::Lt, FilterValue::FieldRef(f)) => {
2738					col.lt(Expr::col(Alias::new(&f.field)))
2739				}
2740				(FilterOperator::Lte, FilterValue::FieldRef(f)) => {
2741					col.lte(Expr::col(Alias::new(&f.field)))
2742				}
2743				// OuterRef comparisons for correlated subqueries
2744				(FilterOperator::Eq, FilterValue::OuterRef(outer)) => {
2745					// For correlated subqueries, reference outer query field
2746					// e.g., WHERE books.author_id = authors.id (where authors is from outer query)
2747					col.eq(Expr::col(parse_column_reference(&outer.field)))
2748				}
2749				(FilterOperator::Ne, FilterValue::OuterRef(outer)) => {
2750					col.ne(Expr::col(parse_column_reference(&outer.field)))
2751				}
2752				(FilterOperator::Gt, FilterValue::OuterRef(outer)) => {
2753					col.gt(Expr::col(parse_column_reference(&outer.field)))
2754				}
2755				(FilterOperator::Gte, FilterValue::OuterRef(outer)) => {
2756					col.gte(Expr::col(parse_column_reference(&outer.field)))
2757				}
2758				(FilterOperator::Lt, FilterValue::OuterRef(outer)) => {
2759					col.lt(Expr::col(parse_column_reference(&outer.field)))
2760				}
2761				(FilterOperator::Lte, FilterValue::OuterRef(outer)) => {
2762					col.lte(Expr::col(parse_column_reference(&outer.field)))
2763				}
2764				// Expression comparisons (F("a") * F("b") etc.)
2765				(FilterOperator::Eq, FilterValue::Expression(expr)) => {
2766					col.eq(Self::expression_to_query_expr(expr))
2767				}
2768				(FilterOperator::Ne, FilterValue::Expression(expr)) => {
2769					col.ne(Self::expression_to_query_expr(expr))
2770				}
2771				(FilterOperator::Gt, FilterValue::Expression(expr)) => {
2772					col.gt(Self::expression_to_query_expr(expr))
2773				}
2774				(FilterOperator::Gte, FilterValue::Expression(expr)) => {
2775					col.gte(Self::expression_to_query_expr(expr))
2776				}
2777				(FilterOperator::Lt, FilterValue::Expression(expr)) => {
2778					col.lt(Self::expression_to_query_expr(expr))
2779				}
2780				(FilterOperator::Lte, FilterValue::Expression(expr)) => {
2781					col.lte(Self::expression_to_query_expr(expr))
2782				}
2783				// NULL checks
2784				(FilterOperator::Eq, FilterValue::Null) => col.is_null(),
2785				(FilterOperator::Ne, FilterValue::Null) => col.is_not_null(),
2786				(FilterOperator::IExact, FilterValue::String(s)) => {
2787					Self::like_expr(filter, s, LikePattern::Exact, true)
2788				}
2789				(FilterOperator::IExact, v) => col.eq(Self::filter_value_to_sea_value(v)),
2790				// Generic value comparisons (catch-all for other FilterValue types)
2791				(FilterOperator::Eq, v) => col.eq(Self::filter_value_to_sea_value(v)),
2792				(FilterOperator::Ne, v) => col.ne(Self::filter_value_to_sea_value(v)),
2793				(FilterOperator::Gt, v) => col.gt(Self::filter_value_to_sea_value(v)),
2794				(FilterOperator::Gte, v) => col.gte(Self::filter_value_to_sea_value(v)),
2795				(FilterOperator::Lt, v) => col.lt(Self::filter_value_to_sea_value(v)),
2796				(FilterOperator::Lte, v) => col.lte(Self::filter_value_to_sea_value(v)),
2797				(FilterOperator::In, FilterValue::String(s)) => {
2798					let values = Self::parse_array_string(s);
2799					col.is_in(values)
2800				}
2801				(FilterOperator::In, FilterValue::Array(arr)) => {
2802					col.is_in(arr.iter().map(|s| s.as_str()).collect::<Vec<_>>())
2803				}
2804				(FilterOperator::In, FilterValue::List(values)) => col.is_in(
2805					values
2806						.iter()
2807						.map(Self::filter_value_to_sea_value)
2808						.collect::<Vec<_>>(),
2809				),
2810				(FilterOperator::NotIn, FilterValue::String(s)) => {
2811					let values = Self::parse_array_string(s);
2812					col.is_not_in(values)
2813				}
2814				(FilterOperator::NotIn, FilterValue::Array(arr)) => {
2815					col.is_not_in(arr.iter().map(|s| s.as_str()).collect::<Vec<_>>())
2816				}
2817				(FilterOperator::NotIn, FilterValue::List(values)) => col.is_not_in(
2818					values
2819						.iter()
2820						.map(Self::filter_value_to_sea_value)
2821						.collect::<Vec<_>>(),
2822				),
2823				(FilterOperator::Contains, FilterValue::String(s)) => {
2824					Self::like_expr(filter, s, LikePattern::Contains, false)
2825				}
2826				(FilterOperator::IContains, FilterValue::String(s)) => {
2827					Self::like_expr(filter, s, LikePattern::Contains, true)
2828				}
2829				(FilterOperator::Contains, FilterValue::Array(arr)) => {
2830					let value = arr.first().map(String::as_str).unwrap_or("");
2831					Self::like_expr(filter, value, LikePattern::Contains, false)
2832				}
2833				(FilterOperator::StartsWith, FilterValue::String(s)) => {
2834					Self::like_expr(filter, s, LikePattern::StartsWith, false)
2835				}
2836				(FilterOperator::IStartsWith, FilterValue::String(s)) => {
2837					Self::like_expr(filter, s, LikePattern::StartsWith, true)
2838				}
2839				(FilterOperator::StartsWith, FilterValue::Array(arr)) => {
2840					let value = arr.first().map(String::as_str).unwrap_or("");
2841					Self::like_expr(filter, value, LikePattern::StartsWith, false)
2842				}
2843				(FilterOperator::EndsWith, FilterValue::String(s)) => {
2844					Self::like_expr(filter, s, LikePattern::EndsWith, false)
2845				}
2846				(FilterOperator::IEndsWith, FilterValue::String(s)) => {
2847					Self::like_expr(filter, s, LikePattern::EndsWith, true)
2848				}
2849				(FilterOperator::EndsWith, FilterValue::Array(arr)) => {
2850					let value = arr.first().map(String::as_str).unwrap_or("");
2851					Self::like_expr(filter, value, LikePattern::EndsWith, false)
2852				}
2853				(FilterOperator::Regex, FilterValue::String(pattern)) => Expr::cust_with_values(
2854					format!("{} ~ ?", Self::filter_lhs_sql(filter)),
2855					[pattern.clone()],
2856				)
2857				.into_simple_expr(),
2858				(FilterOperator::IRegex, FilterValue::String(pattern)) => Expr::cust_with_values(
2859					format!("{} ~* ?", Self::filter_lhs_sql(filter)),
2860					[pattern.clone()],
2861				)
2862				.into_simple_expr(),
2863				(FilterOperator::Range, FilterValue::Range(start, end)) => Expr::cust_with_values(
2864					format!("{} BETWEEN ? AND ?", Self::filter_lhs_sql(filter)),
2865					[
2866						Self::filter_value_to_sea_value(start),
2867						Self::filter_value_to_sea_value(end),
2868					],
2869				)
2870				.into_simple_expr(),
2871				// Handle Integer, Float, Boolean for text operators
2872				(FilterOperator::Contains, FilterValue::Integer(i) | FilterValue::Int(i)) => {
2873					col.like(format!("%{}%", i))
2874				}
2875				(FilterOperator::IContains, FilterValue::Integer(i) | FilterValue::Int(i)) => {
2876					col.binary(BinOper::ILike, SimpleExpr::from(format!("%{}%", i)))
2877				}
2878				(FilterOperator::Contains, FilterValue::Float(f)) => col.like(format!("%{}%", f)),
2879				(FilterOperator::IContains, FilterValue::Float(f)) => {
2880					col.binary(BinOper::ILike, SimpleExpr::from(format!("%{}%", f)))
2881				}
2882				(FilterOperator::Contains, FilterValue::Boolean(b) | FilterValue::Bool(b)) => {
2883					col.like(format!("%{}%", b))
2884				}
2885				(FilterOperator::IContains, FilterValue::Boolean(b) | FilterValue::Bool(b)) => {
2886					col.binary(BinOper::ILike, SimpleExpr::from(format!("%{}%", b)))
2887				}
2888				(FilterOperator::Contains, FilterValue::Null) => col.like("%"),
2889				(FilterOperator::IContains, FilterValue::Null) => {
2890					col.binary(BinOper::ILike, SimpleExpr::from("%"))
2891				}
2892				(FilterOperator::StartsWith, FilterValue::Integer(i) | FilterValue::Int(i)) => {
2893					col.like(format!("{}%", i))
2894				}
2895				(FilterOperator::IStartsWith, FilterValue::Integer(i) | FilterValue::Int(i)) => {
2896					col.binary(BinOper::ILike, SimpleExpr::from(format!("{}%", i)))
2897				}
2898				(FilterOperator::StartsWith, FilterValue::Float(f)) => col.like(format!("{}%", f)),
2899				(FilterOperator::IStartsWith, FilterValue::Float(f)) => {
2900					col.binary(BinOper::ILike, SimpleExpr::from(format!("{}%", f)))
2901				}
2902				(FilterOperator::StartsWith, FilterValue::Boolean(b) | FilterValue::Bool(b)) => {
2903					col.like(format!("{}%", b))
2904				}
2905				(FilterOperator::IStartsWith, FilterValue::Boolean(b) | FilterValue::Bool(b)) => {
2906					col.binary(BinOper::ILike, SimpleExpr::from(format!("{}%", b)))
2907				}
2908				(FilterOperator::StartsWith, FilterValue::Null) => col.like("%"),
2909				(FilterOperator::IStartsWith, FilterValue::Null) => {
2910					col.binary(BinOper::ILike, SimpleExpr::from("%"))
2911				}
2912				(FilterOperator::EndsWith, FilterValue::Integer(i) | FilterValue::Int(i)) => {
2913					col.like(format!("%{}", i))
2914				}
2915				(FilterOperator::IEndsWith, FilterValue::Integer(i) | FilterValue::Int(i)) => {
2916					col.binary(BinOper::ILike, SimpleExpr::from(format!("%{}", i)))
2917				}
2918				(FilterOperator::EndsWith, FilterValue::Float(f)) => col.like(format!("%{}", f)),
2919				(FilterOperator::IEndsWith, FilterValue::Float(f)) => {
2920					col.binary(BinOper::ILike, SimpleExpr::from(format!("%{}", f)))
2921				}
2922				(FilterOperator::EndsWith, FilterValue::Boolean(b) | FilterValue::Bool(b)) => {
2923					col.like(format!("%{}", b))
2924				}
2925				(FilterOperator::IEndsWith, FilterValue::Boolean(b) | FilterValue::Bool(b)) => {
2926					col.binary(BinOper::ILike, SimpleExpr::from(format!("%{}", b)))
2927				}
2928				(FilterOperator::EndsWith, FilterValue::Null) => col.like("%"),
2929				(FilterOperator::IEndsWith, FilterValue::Null) => {
2930					col.binary(BinOper::ILike, SimpleExpr::from("%"))
2931				}
2932				// Handle In/NotIn for non-String types
2933				(FilterOperator::In, FilterValue::Integer(i) | FilterValue::Int(i)) => {
2934					col.is_in(vec![*i])
2935				}
2936				(FilterOperator::In, FilterValue::Float(f)) => col.is_in(vec![*f]),
2937				(FilterOperator::In, FilterValue::Boolean(b) | FilterValue::Bool(b)) => {
2938					col.is_in(vec![*b])
2939				}
2940				(FilterOperator::In, FilterValue::Null) => {
2941					col.is_in(vec![reinhardt_query::value::Value::Int(None)])
2942				}
2943				(FilterOperator::NotIn, FilterValue::Integer(i) | FilterValue::Int(i)) => {
2944					col.is_not_in(vec![*i])
2945				}
2946				(FilterOperator::NotIn, FilterValue::Float(f)) => col.is_not_in(vec![*f]),
2947				(FilterOperator::NotIn, FilterValue::Boolean(b) | FilterValue::Bool(b)) => {
2948					col.is_not_in(vec![*b])
2949				}
2950				(FilterOperator::NotIn, FilterValue::Null) => {
2951					col.is_not_in(vec![reinhardt_query::value::Value::Int(None)])
2952				}
2953				// IsNull/IsNotNull operators
2954				(FilterOperator::IsNull, _) => col.is_null(),
2955				(FilterOperator::IsNotNull, _) => col.is_not_null(),
2956				// PostgreSQL Array operators (using custom SQL)
2957				(FilterOperator::ArrayContains, FilterValue::Array(arr)) => {
2958					// field @> ARRAY[?, ?] - parameterized
2959					let placeholders = arr.iter().map(|_| "?").collect::<Vec<_>>().join(", ");
2960					Expr::cust_with_values(
2961						format!(
2962							"{} @> ARRAY[{}]",
2963							Self::filter_lhs_sql(filter),
2964							placeholders
2965						),
2966						arr.iter().cloned(),
2967					)
2968					.into_simple_expr()
2969				}
2970				(FilterOperator::ArrayContainedBy, FilterValue::Array(arr)) => {
2971					// field <@ ARRAY[?, ?] - parameterized
2972					let placeholders = arr.iter().map(|_| "?").collect::<Vec<_>>().join(", ");
2973					Expr::cust_with_values(
2974						format!(
2975							"{} <@ ARRAY[{}]",
2976							Self::filter_lhs_sql(filter),
2977							placeholders
2978						),
2979						arr.iter().cloned(),
2980					)
2981					.into_simple_expr()
2982				}
2983				(FilterOperator::ArrayOverlap, FilterValue::Array(arr)) => {
2984					// field && ARRAY[?, ?] - parameterized
2985					let placeholders = arr.iter().map(|_| "?").collect::<Vec<_>>().join(", ");
2986					Expr::cust_with_values(
2987						format!(
2988							"{} && ARRAY[{}]",
2989							Self::filter_lhs_sql(filter),
2990							placeholders
2991						),
2992						arr.iter().cloned(),
2993					)
2994					.into_simple_expr()
2995				}
2996				// PostgreSQL Full-text search
2997				(FilterOperator::FullTextMatch, FilterValue::String(query)) => {
2998					// field @@ plainto_tsquery('english', ?) - parameterized
2999					Expr::cust_with_values(
3000						format!(
3001							"{} @@ plainto_tsquery('english', ?)",
3002							Self::filter_lhs_sql(filter)
3003						),
3004						[query.clone()],
3005					)
3006					.into_simple_expr()
3007				}
3008				// PostgreSQL JSONB operators
3009				(FilterOperator::JsonbContains, FilterValue::String(json)) => {
3010					// field @> ?::jsonb - parameterized
3011					Expr::cust_with_values(
3012						format!("{} @> ?::jsonb", Self::filter_lhs_sql(filter)),
3013						[json.clone()],
3014					)
3015					.into_simple_expr()
3016				}
3017				(FilterOperator::JsonbContainedBy, FilterValue::String(json)) => {
3018					// field <@ ?::jsonb - parameterized
3019					Expr::cust_with_values(
3020						format!("{} <@ ?::jsonb", Self::filter_lhs_sql(filter)),
3021						[json.clone()],
3022					)
3023					.into_simple_expr()
3024				}
3025				(FilterOperator::JsonbKeyExists, FilterValue::String(key)) => {
3026					// field ? 'key' - using PgBinOper for safe parameterization
3027					Expr::cust(Self::filter_lhs_sql(filter))
3028						.into_simple_expr()
3029						.binary(
3030							BinOper::PgOperator(PgBinOper::JsonContainsKey),
3031							SimpleExpr::from(key.clone()),
3032						)
3033				}
3034				(FilterOperator::JsonbAnyKeyExists, FilterValue::Array(keys)) => {
3035					// field ?| array[?, ?] - using PgBinOper for safe parameterization
3036					let placeholders = keys.iter().map(|_| "?").collect::<Vec<_>>().join(", ");
3037					let array_expr = Expr::cust_with_values(
3038						format!("array[{}]", placeholders),
3039						keys.iter().cloned(),
3040					)
3041					.into_simple_expr();
3042					Expr::cust(Self::filter_lhs_sql(filter))
3043						.into_simple_expr()
3044						.binary(
3045							BinOper::PgOperator(PgBinOper::JsonContainsAnyKey),
3046							array_expr,
3047						)
3048				}
3049				(FilterOperator::JsonbAllKeysExist, FilterValue::Array(keys)) => {
3050					// field ?& array[?, ?] - using PgBinOper for safe parameterization
3051					let placeholders = keys.iter().map(|_| "?").collect::<Vec<_>>().join(", ");
3052					let array_expr = Expr::cust_with_values(
3053						format!("array[{}]", placeholders),
3054						keys.iter().cloned(),
3055					)
3056					.into_simple_expr();
3057					Expr::cust(Self::filter_lhs_sql(filter))
3058						.into_simple_expr()
3059						.binary(
3060							BinOper::PgOperator(PgBinOper::JsonContainsAllKeys),
3061							array_expr,
3062						)
3063				}
3064				(FilterOperator::JsonbPathExists, FilterValue::String(path)) => {
3065					// field @? ? - parameterized
3066					Expr::cust_with_values(
3067						format!("{} @? ?", Self::filter_lhs_sql(filter)),
3068						[path.clone()],
3069					)
3070					.into_simple_expr()
3071				}
3072				// PostgreSQL Range operators
3073				(FilterOperator::RangeContains, v) => {
3074					// field @> ? - parameterized
3075					Expr::cust_with_values(
3076						format!("{} @> ?", Self::filter_lhs_sql(filter)),
3077						[Self::filter_value_to_sea_value(v)],
3078					)
3079					.into_simple_expr()
3080				}
3081				(FilterOperator::RangeContainedBy, FilterValue::String(range)) => {
3082					// field <@ ? - parameterized
3083					Expr::cust_with_values(
3084						format!("{} <@ ?", Self::filter_lhs_sql(filter)),
3085						[range.clone()],
3086					)
3087					.into_simple_expr()
3088				}
3089				(FilterOperator::RangeOverlaps, FilterValue::String(range)) => {
3090					// field && ? - parameterized
3091					Expr::cust_with_values(
3092						format!("{} && ?", Self::filter_lhs_sql(filter)),
3093						[range.clone()],
3094					)
3095					.into_simple_expr()
3096				}
3097				// Fallback for unsupported combinations
3098				_ => {
3099					// Default to equality for unhandled cases
3100					col.eq(Self::filter_value_to_sea_value(&filter.value))
3101				}
3102			};
3103
3104			cond = cond.add(expr);
3105			added = true;
3106		}
3107
3108		for filter_condition in &self.filter_conditions {
3109			if let Some(expr) = Self::build_filter_condition(filter_condition, 0)? {
3110				cond = cond.add(expr);
3111				added = true;
3112			}
3113		}
3114
3115		// Add subquery conditions
3116		for subq_cond in &self.subquery_conditions {
3117			let expr = match subq_cond {
3118				SubqueryCondition::In { field, subquery } => {
3119					// field IN (subquery)
3120					Expr::cust(format!("{} IN {}", quote_identifier(field), subquery))
3121						.into_simple_expr()
3122				}
3123				SubqueryCondition::NotIn { field, subquery } => {
3124					// field NOT IN (subquery)
3125					Expr::cust(format!("{} NOT IN {}", quote_identifier(field), subquery))
3126						.into_simple_expr()
3127				}
3128				SubqueryCondition::Exists { subquery } => {
3129					// EXISTS (subquery)
3130					Expr::cust(format!("EXISTS {}", subquery)).into_simple_expr()
3131				}
3132				SubqueryCondition::NotExists { subquery } => {
3133					// NOT EXISTS (subquery)
3134					Expr::cust(format!("NOT EXISTS {}", subquery)).into_simple_expr()
3135				}
3136			};
3137
3138			cond = cond.add(expr);
3139			added = true;
3140		}
3141
3142		Ok(added.then_some(cond))
3143	}
3144
3145	fn build_filter_condition(
3146		filter_condition: &FilterCondition,
3147		depth: usize,
3148	) -> reinhardt_core::exception::Result<Option<Condition>> {
3149		if depth >= MAX_FILTER_CONDITION_DEPTH {
3150			return Err(reinhardt_core::exception::Error::Validation(format!(
3151				"Filter condition exceeded maximum depth of {} levels",
3152				MAX_FILTER_CONDITION_DEPTH
3153			)));
3154		}
3155
3156		match filter_condition {
3157			FilterCondition::Single(filter) => {
3158				let mut queryset = Self::new();
3159				queryset.filters.push(filter.clone());
3160				queryset.build_where_condition()
3161			}
3162			FilterCondition::And(conditions) => {
3163				let mut condition = Condition::all();
3164				let mut added = false;
3165				for item in conditions {
3166					if let Some(sub_condition) = Self::build_filter_condition(item, depth + 1)? {
3167						condition = condition.add(sub_condition);
3168						added = true;
3169					}
3170				}
3171				Ok(added.then_some(condition))
3172			}
3173			FilterCondition::Or(conditions) => {
3174				let mut condition = Condition::any();
3175				let mut added = false;
3176				for item in conditions {
3177					if let Some(sub_condition) = Self::build_filter_condition(item, depth + 1)? {
3178						condition = condition.add(sub_condition);
3179						added = true;
3180					}
3181				}
3182				Ok(added.then_some(condition))
3183			}
3184			FilterCondition::Not(condition) => {
3185				Ok(Self::build_filter_condition(condition, depth + 1)?
3186					.map(|condition| condition.not()))
3187			}
3188		}
3189	}
3190
3191	fn false_condition() -> Condition {
3192		Condition::all().add(Expr::cust("FALSE").into_simple_expr())
3193	}
3194
3195	fn build_where_condition_or_false(&self) -> Option<Condition> {
3196		match self.build_where_condition() {
3197			Ok(condition) => condition,
3198			Err(_) => Some(Self::false_condition()),
3199		}
3200	}
3201
3202	/// Convert FilterValue to reinhardt_query::value::Value
3203	/// Convert Expression to reinhardt-query Expr for use in WHERE clauses
3204	///
3205	/// Uses Expr::cust() for arithmetic operations as reinhardt-query doesn't provide
3206	/// multiply/divide/etc. methods. SQL injection risk is low since F() only
3207	/// accepts field names.
3208	fn expression_to_query_expr(expr: &super::annotation::Expression) -> Expr {
3209		use crate::orm::annotation::Expression;
3210
3211		match expr {
3212			Expression::Add(left, right) => {
3213				let left_sql = Self::annotation_value_to_sql(left);
3214				let right_sql = Self::annotation_value_to_sql(right);
3215				Expr::cust(format!("({} + {})", left_sql, right_sql))
3216			}
3217			Expression::Subtract(left, right) => {
3218				let left_sql = Self::annotation_value_to_sql(left);
3219				let right_sql = Self::annotation_value_to_sql(right);
3220				Expr::cust(format!("({} - {})", left_sql, right_sql))
3221			}
3222			Expression::Multiply(left, right) => {
3223				let left_sql = Self::annotation_value_to_sql(left);
3224				let right_sql = Self::annotation_value_to_sql(right);
3225				Expr::cust(format!("({} * {})", left_sql, right_sql))
3226			}
3227			Expression::Divide(left, right) => {
3228				let left_sql = Self::annotation_value_to_sql(left);
3229				let right_sql = Self::annotation_value_to_sql(right);
3230				Expr::cust(format!("({} / {})", left_sql, right_sql))
3231			}
3232			Expression::Case { whens, default } => {
3233				let mut case_sql = "CASE".to_string();
3234				for when in whens.iter() {
3235					// Use When::to_sql() which generates "WHEN condition THEN value"
3236					case_sql.push_str(&format!(" {}", when.to_sql()));
3237				}
3238				if let Some(default_val) = default {
3239					case_sql.push_str(&format!(
3240						" ELSE {}",
3241						Self::annotation_value_to_sql(default_val)
3242					));
3243				}
3244				case_sql.push_str(" END");
3245				Expr::cust(case_sql)
3246			}
3247			Expression::Coalesce(values) => {
3248				let value_sqls = values
3249					.iter()
3250					.map(|v| Self::annotation_value_to_sql(v))
3251					.collect::<Vec<_>>()
3252					.join(", ");
3253				Expr::cust(format!("COALESCE({})", value_sqls))
3254			}
3255		}
3256	}
3257
3258	/// Convert AnnotationValue to SQL string for custom expressions
3259	///
3260	/// Delegates to the `AnnotationValue::to_sql()` method which provides
3261	/// complete SQL generation for all annotation value types.
3262	fn annotation_value_to_sql(value: &super::annotation::AnnotationValue) -> String {
3263		value.to_sql()
3264	}
3265
3266	fn filter_lhs_expr(filter: &Filter) -> Expr {
3267		filter_lhs_expr(filter)
3268	}
3269
3270	fn filter_lhs_sql(filter: &Filter) -> String {
3271		filter_lhs_sql(filter)
3272	}
3273
3274	fn like_expr(
3275		filter: &Filter,
3276		value: &str,
3277		pattern: LikePattern,
3278		case_insensitive: bool,
3279	) -> SimpleExpr {
3280		let operator = if case_insensitive { "ILIKE" } else { "LIKE" };
3281		Expr::cust_with_values(
3282			format!(
3283				"{} {} ? ESCAPE '\\'",
3284				Self::filter_lhs_sql(filter),
3285				operator
3286			),
3287			[pattern.apply(value)],
3288		)
3289		.into_simple_expr()
3290	}
3291
3292	fn filter_value_to_sea_value(v: &FilterValue) -> reinhardt_query::value::Value {
3293		match v {
3294			FilterValue::String(s) => {
3295				// Try to parse as UUID first for proper PostgreSQL uuid column handling
3296				if let Ok(uuid) = Uuid::parse_str(s) {
3297					reinhardt_query::value::Value::Uuid(Some(Box::new(uuid)))
3298				} else {
3299					s.clone().into()
3300				}
3301			}
3302			FilterValue::Integer(i) | FilterValue::Int(i) => (*i).into(),
3303			FilterValue::Float(f) => (*f).into(),
3304			FilterValue::Boolean(b) | FilterValue::Bool(b) => (*b).into(),
3305			FilterValue::Null => reinhardt_query::value::Value::Int(None),
3306			FilterValue::Array(arr) => arr.join(",").into(),
3307			FilterValue::List(values) => values
3308				.iter()
3309				.map(Self::value_to_string)
3310				.collect::<Vec<_>>()
3311				.join(",")
3312				.into(),
3313			FilterValue::Range(start, end) => format!(
3314				"{},{}",
3315				Self::value_to_string(start),
3316				Self::value_to_string(end)
3317			)
3318			.into(),
3319			// FieldRef, Expression, and OuterRef are typically handled separately
3320			// in build_where_condition(), but provide proper conversion as fallback
3321			FilterValue::FieldRef(f) => f.field.clone().into(),
3322			FilterValue::Expression(expr) => expr.to_sql().into(),
3323			FilterValue::OuterRef(outer_ref) => outer_ref.field.clone().into(),
3324		}
3325	}
3326
3327	/// Convert FilterValue to String representation
3328	// Allow dead_code: internal conversion helper for filter value stringification in queries
3329	#[allow(dead_code)]
3330	fn value_to_string(v: &FilterValue) -> String {
3331		match v {
3332			FilterValue::String(s) => s.clone(),
3333			FilterValue::Integer(i) | FilterValue::Int(i) => i.to_string(),
3334			FilterValue::Float(f) => f.to_string(),
3335			FilterValue::Boolean(b) | FilterValue::Bool(b) => b.to_string(),
3336			FilterValue::Null => String::new(),
3337			FilterValue::Array(arr) => arr.join(","),
3338			FilterValue::List(values) => values
3339				.iter()
3340				.map(Self::value_to_string)
3341				.collect::<Vec<_>>()
3342				.join(","),
3343			FilterValue::Range(start, end) => {
3344				format!(
3345					"{},{}",
3346					Self::value_to_string(start),
3347					Self::value_to_string(end)
3348				)
3349			}
3350			FilterValue::FieldRef(f) => f.field.clone(),
3351			FilterValue::Expression(expr) => expr.to_sql(),
3352			FilterValue::OuterRef(outer_ref) => outer_ref.field.clone(),
3353		}
3354	}
3355
3356	/// Parse array string into `Vec<reinhardt_query::value::Value>`
3357	/// Supports comma-separated values or JSON array format
3358	fn parse_array_string(s: &str) -> Vec<reinhardt_query::value::Value> {
3359		let trimmed = s.trim();
3360
3361		// Try parsing as JSON array first
3362		if trimmed.starts_with('[')
3363			&& trimmed.ends_with(']')
3364			&& let Ok(arr) = serde_json::from_str::<Vec<serde_json::Value>>(trimmed)
3365		{
3366			return arr
3367				.iter()
3368				.map(|v| match v {
3369					serde_json::Value::String(s) => s.clone().into(),
3370					serde_json::Value::Number(n) => {
3371						if let Some(i) = n.as_i64() {
3372							i.into()
3373						} else if let Some(f) = n.as_f64() {
3374							f.into()
3375						} else {
3376							n.to_string().into()
3377						}
3378					}
3379					serde_json::Value::Bool(b) => (*b).into(),
3380					_ => v.to_string().into(),
3381				})
3382				.collect();
3383		}
3384
3385		// Fallback to comma-separated parsing
3386		trimmed
3387			.split(',')
3388			.map(|s| s.trim())
3389			.filter(|s| !s.is_empty())
3390			.map(|s| s.to_string().into())
3391			.collect()
3392	}
3393
3394	/// Convert FilterValue to array of reinhardt_query::value::Value
3395	// Allow dead_code: internal conversion for IN clause array parameter binding
3396	#[allow(dead_code)]
3397	fn value_to_array(v: &FilterValue) -> Vec<reinhardt_query::value::Value> {
3398		match v {
3399			FilterValue::String(s) => Self::parse_array_string(s),
3400			FilterValue::Integer(i) | FilterValue::Int(i) => vec![(*i).into()],
3401			FilterValue::Float(f) => vec![(*f).into()],
3402			FilterValue::Boolean(b) | FilterValue::Bool(b) => vec![(*b).into()],
3403			FilterValue::Null => vec![reinhardt_query::value::Value::Int(None)],
3404			FilterValue::Array(arr) => arr.iter().map(|s| s.clone().into()).collect(),
3405			FilterValue::List(values) => {
3406				values.iter().map(Self::filter_value_to_sea_value).collect()
3407			}
3408			FilterValue::Range(start, end) => vec![
3409				Self::filter_value_to_sea_value(start),
3410				Self::filter_value_to_sea_value(end),
3411			],
3412			FilterValue::FieldRef(f) => vec![f.field.clone().into()],
3413			FilterValue::Expression(expr) => vec![expr.to_sql().into()],
3414			FilterValue::OuterRef(outer) => vec![outer.field.clone().into()],
3415		}
3416	}
3417
3418	/// Build WHERE clause from accumulated filters
3419	///
3420	/// # Deprecation Note
3421	///
3422	/// This method is maintained for backward compatibility with existing code that
3423	/// expects a string-based WHERE clause. New code should use `build_where_condition()`
3424	/// which returns a `Condition` object that can be directly added to reinhardt-query statements.
3425	///
3426	/// This method generates a complete SELECT statement internally and extracts only
3427	/// the WHERE portion, which is less efficient than using `build_where_condition()`.
3428	// Allow dead_code: backward-compatible string-based WHERE clause builder for legacy code paths
3429	#[allow(dead_code)]
3430	fn build_where_clause(&self) -> (String, Vec<String>) {
3431		if !self.has_where_predicates() {
3432			return (String::new(), Vec::new());
3433		}
3434
3435		// Build reinhardt-query condition
3436		let mut stmt = Query::select();
3437		stmt.from(Alias::new("dummy"));
3438
3439		if let Some(cond) = self.build_where_condition_or_false() {
3440			stmt.cond_where(cond);
3441		}
3442
3443		// Convert to SQL string with inline values
3444		use reinhardt_query::prelude::PostgresQueryBuilder;
3445		let sql = stmt.to_string(PostgresQueryBuilder);
3446
3447		// Extract WHERE clause portion by finding the WHERE keyword
3448		let where_clause = if let Some(idx) = sql.find(" WHERE ") {
3449			sql[idx..].to_string()
3450		} else {
3451			String::new()
3452		};
3453
3454		(where_clause, Vec::new())
3455	}
3456
3457	/// Eagerly load related objects using JOIN queries
3458	///
3459	/// This method performs SQL JOINs to fetch related objects in a single query,
3460	/// reducing the number of database round-trips and preventing N+1 query problems.
3461	///
3462	/// # Performance
3463	///
3464	/// Best for one-to-one and many-to-one relationships where JOIN won't create
3465	/// significant data duplication. For one-to-many and many-to-many relationships,
3466	/// consider using `prefetch_related()` instead.
3467	///
3468	/// # Examples
3469	///
3470	/// ```no_run
3471	/// # use reinhardt_db::orm::Model;
3472	/// # use serde::{Serialize, Deserialize};
3473	/// # #[derive(Clone, Serialize, Deserialize)]
3474	/// # struct Post { id: Option<i64>, author: Author, category: Category }
3475	/// # #[derive(Clone, Serialize, Deserialize)]
3476	/// # struct Author { name: String }
3477	/// # #[derive(Clone, Serialize, Deserialize)]
3478	/// # struct Category { name: String }
3479	/// # #[derive(Clone)]
3480	/// # struct PostFields;
3481	/// # impl reinhardt_db::orm::model::FieldSelector for PostFields {
3482	/// #     fn with_alias(self, _alias: &str) -> Self { self }
3483	/// # }
3484	/// # impl Model for Post {
3485	/// #     type PrimaryKey = i64;
3486	/// #     type Fields = PostFields;
3487	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
3488	/// #     fn table_name() -> &'static str { "posts" }
3489	/// #     fn new_fields() -> Self::Fields { PostFields }
3490	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
3491	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
3492	/// # }
3493	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
3494	/// // Single query with JOINs instead of N+1 queries
3495	/// let posts = Post::objects()
3496	///     .select_related(&["author", "category"])
3497	///     .all()
3498	///     .await?;
3499	///
3500	/// // Each post has author and category pre-loaded
3501	/// for post in posts {
3502	///     println!("Author: {}", post.author.name); // No additional query
3503	/// }
3504	/// # Ok(())
3505	/// # }
3506	/// ```
3507	pub fn select_related(mut self, fields: &[&str]) -> Self {
3508		self.select_related_fields = fields.iter().map(|s| s.to_string()).collect();
3509		self
3510	}
3511
3512	/// Generate SELECT query with JOIN clauses for select_related fields
3513	///
3514	/// Returns reinhardt-query SelectStatement with LEFT JOIN for each related field to enable eager loading.
3515	///
3516	/// # Examples
3517	///
3518	/// ```no_run
3519	/// # use reinhardt_db::orm::Model;
3520	/// # use reinhardt_db::orm::{Filter, FilterOperator, FilterValue};
3521	/// # use serde::{Serialize, Deserialize};
3522	/// # #[derive(Clone, Serialize, Deserialize)]
3523	/// # struct Post { id: Option<i64> }
3524	/// # #[derive(Clone)]
3525	/// # struct PostFields;
3526	/// # impl reinhardt_db::orm::model::FieldSelector for PostFields {
3527	/// #     fn with_alias(self, _alias: &str) -> Self { self }
3528	/// # }
3529	/// # impl Model for Post {
3530	/// #     type PrimaryKey = i64;
3531	/// #     type Fields = PostFields;
3532	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
3533	/// #     fn table_name() -> &'static str { "posts" }
3534	/// #     fn new_fields() -> Self::Fields { PostFields }
3535	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
3536	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
3537	/// # }
3538	/// let queryset = Post::objects()
3539	///     .select_related(&["author", "category"])
3540	///     .filter(Filter::new("published", FilterOperator::Eq, FilterValue::Boolean(true)));
3541	///
3542	/// let stmt = queryset.select_related_query();
3543	/// // Generates:
3544	/// // SELECT posts.*, author.*, category.* FROM posts
3545	/// //   LEFT JOIN users AS author ON posts.author_id = author.id
3546	/// //   LEFT JOIN categories AS category ON posts.category_id = category.id
3547	/// //   WHERE posts.published = $1
3548	/// ```
3549	pub fn select_related_query(&self) -> SelectStatement {
3550		let table_name = T::table_name();
3551		let mut stmt = Query::select();
3552
3553		// Apply FROM clause with optional alias
3554		if let Some(ref alias) = self.from_alias {
3555			stmt.from_as(Alias::new(table_name), Alias::new(alias));
3556		} else {
3557			stmt.from(Alias::new(table_name));
3558		}
3559
3560		// Apply DISTINCT if enabled
3561		if self.distinct_enabled {
3562			stmt.distinct();
3563		}
3564
3565		// Add main table columns
3566		stmt.column(ColumnRef::table_asterisk(Alias::new(table_name)));
3567
3568		// Add LEFT JOIN for each related field
3569		for related_field in &self.select_related_fields {
3570			// Convention: related_field is the field name in the model
3571			// We assume FK field is "{related_field}_id" and join to "{related_field}s" table
3572			let fk_field = Alias::new(format!("{}_id", related_field));
3573			let related_table = Alias::new(format!("{}s", related_field));
3574			let related_alias = Alias::new(related_field);
3575
3576			// LEFT JOIN related_table AS related_field ON table.fk_field = related_field.id
3577			stmt.left_join(
3578				related_table,
3579				Expr::col((Alias::new(table_name), fk_field))
3580					.equals((related_alias.clone(), Alias::new("id"))),
3581			);
3582
3583			// Add related table columns to SELECT
3584			stmt.column(ColumnRef::table_asterisk(related_alias));
3585		}
3586
3587		// Apply manual JOINs
3588		for join in &self.joins {
3589			if join.on_condition.is_empty() {
3590				// CROSS JOIN (no ON condition)
3591				if let Some(ref alias) = join.target_alias {
3592					stmt.cross_join((Alias::new(&join.target_table), Alias::new(alias)));
3593				} else {
3594					stmt.cross_join(Alias::new(&join.target_table));
3595				}
3596			} else {
3597				// Convert reinhardt JoinType to reinhardt-query JoinType
3598				let sea_join_type = match join.join_type {
3599					super::sqlalchemy_query::JoinType::Inner => SeaJoinType::InnerJoin,
3600					super::sqlalchemy_query::JoinType::Left => SeaJoinType::LeftJoin,
3601					super::sqlalchemy_query::JoinType::Right => SeaJoinType::RightJoin,
3602					super::sqlalchemy_query::JoinType::Full => SeaJoinType::FullOuterJoin,
3603				};
3604
3605				// Build the join with optional alias
3606				if let Some(ref alias) = join.target_alias {
3607					stmt.join(
3608						sea_join_type,
3609						(Alias::new(&join.target_table), Alias::new(alias)),
3610						Expr::cust(join.on_condition.clone()),
3611					);
3612				} else {
3613					stmt.join(
3614						sea_join_type,
3615						Alias::new(&join.target_table),
3616						Expr::cust(join.on_condition.clone()),
3617					);
3618				}
3619			}
3620		}
3621
3622		// Apply WHERE conditions
3623		if let Some(cond) = self.build_where_condition_or_false() {
3624			stmt.cond_where(cond);
3625		}
3626
3627		// Apply GROUP BY
3628		for group_field in &self.group_by_fields {
3629			let col_ref = parse_column_reference(group_field);
3630			stmt.group_by_col(col_ref);
3631		}
3632
3633		// Apply HAVING
3634		for having_cond in &self.having_conditions {
3635			match having_cond {
3636				HavingCondition::AggregateCompare {
3637					func,
3638					field,
3639					operator,
3640					value,
3641				} => {
3642					// Build aggregate function expression
3643					let agg_expr = match func {
3644						AggregateFunc::Avg => {
3645							Func::avg(Expr::col(Alias::new(field)).into_simple_expr())
3646						}
3647						AggregateFunc::Count => {
3648							if field == "*" {
3649								Func::count(Expr::asterisk().into_simple_expr())
3650							} else {
3651								Func::count(Expr::col(Alias::new(field)).into_simple_expr())
3652							}
3653						}
3654						AggregateFunc::Sum => {
3655							Func::sum(Expr::col(Alias::new(field)).into_simple_expr())
3656						}
3657						AggregateFunc::Min => {
3658							Func::min(Expr::col(Alias::new(field)).into_simple_expr())
3659						}
3660						AggregateFunc::Max => {
3661							Func::max(Expr::col(Alias::new(field)).into_simple_expr())
3662						}
3663					};
3664
3665					// Build comparison expression
3666					let having_expr = match operator {
3667						ComparisonOp::Eq => match value {
3668							AggregateValue::Int(v) => agg_expr.eq(*v),
3669							AggregateValue::Float(v) => agg_expr.eq(*v),
3670						},
3671						ComparisonOp::Ne => match value {
3672							AggregateValue::Int(v) => agg_expr.ne(*v),
3673							AggregateValue::Float(v) => agg_expr.ne(*v),
3674						},
3675						ComparisonOp::Gt => match value {
3676							AggregateValue::Int(v) => agg_expr.gt(*v),
3677							AggregateValue::Float(v) => agg_expr.gt(*v),
3678						},
3679						ComparisonOp::Gte => match value {
3680							AggregateValue::Int(v) => agg_expr.gte(*v),
3681							AggregateValue::Float(v) => agg_expr.gte(*v),
3682						},
3683						ComparisonOp::Lt => match value {
3684							AggregateValue::Int(v) => agg_expr.lt(*v),
3685							AggregateValue::Float(v) => agg_expr.lt(*v),
3686						},
3687						ComparisonOp::Lte => match value {
3688							AggregateValue::Int(v) => agg_expr.lte(*v),
3689							AggregateValue::Float(v) => agg_expr.lte(*v),
3690						},
3691					};
3692
3693					stmt.and_having(having_expr);
3694				}
3695			}
3696		}
3697
3698		// Apply ORDER BY
3699		for order_field in &self.order_by_fields {
3700			let (field, is_desc) = if let Some(stripped) = order_field.strip_prefix('-') {
3701				(stripped, true)
3702			} else {
3703				(order_field.as_str(), false)
3704			};
3705
3706			let col_ref = parse_column_reference(field);
3707			let expr = Expr::col(col_ref);
3708			if is_desc {
3709				stmt.order_by_expr(expr, Order::Desc);
3710			} else {
3711				stmt.order_by_expr(expr, Order::Asc);
3712			}
3713		}
3714
3715		// Apply LIMIT/OFFSET
3716		if let Some(limit) = self.limit {
3717			stmt.limit(limit as u64);
3718		}
3719		if let Some(offset) = self.offset {
3720			stmt.offset(offset as u64);
3721		}
3722
3723		stmt.to_owned()
3724	}
3725
3726	/// Eagerly load related objects using separate queries
3727	///
3728	/// This method performs separate SQL queries for related objects and joins them
3729	/// in memory, which is more efficient than JOINs for one-to-many and many-to-many
3730	/// relationships that would create significant data duplication.
3731	///
3732	/// # Performance
3733	///
3734	/// Best for one-to-many and many-to-many relationships where JOINs would create
3735	/// data duplication (e.g., a post with 100 comments would duplicate post data 100 times).
3736	/// Uses 1 + N queries where N is the number of prefetch_related fields.
3737	///
3738	/// # Examples
3739	///
3740	/// ```no_run
3741	/// # use reinhardt_db::orm::Model;
3742	/// # use serde::{Serialize, Deserialize};
3743	/// # #[derive(Clone, Serialize, Deserialize)]
3744	/// # struct Post { id: Option<i64>, comments: Vec<Comment>, tags: Vec<Tag> }
3745	/// # #[derive(Clone, Serialize, Deserialize)]
3746	/// # struct Comment { text: String }
3747	/// # #[derive(Clone, Serialize, Deserialize)]
3748	/// # struct Tag { name: String }
3749	/// # #[derive(Clone)]
3750	/// # struct PostFields;
3751	/// # impl reinhardt_db::orm::model::FieldSelector for PostFields {
3752	/// #     fn with_alias(self, _alias: &str) -> Self { self }
3753	/// # }
3754	/// # impl Model for Post {
3755	/// #     type PrimaryKey = i64;
3756	/// #     type Fields = PostFields;
3757	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
3758	/// #     fn table_name() -> &'static str { "posts" }
3759	/// #     fn new_fields() -> Self::Fields { PostFields }
3760	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
3761	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
3762	/// # }
3763	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
3764	/// // 2 queries total instead of N+1 queries
3765	/// let posts = Post::objects()
3766	///     .prefetch_related(&["comments", "tags"])
3767	///     .all()
3768	///     .await?;
3769	///
3770	/// // Each post has comments and tags pre-loaded
3771	/// for post in posts {
3772	///     for comment in &post.comments {
3773	///         println!("Comment: {}", comment.text); // No additional query
3774	///     }
3775	/// }
3776	/// # Ok(())
3777	/// # }
3778	/// ```
3779	pub fn prefetch_related(mut self, fields: &[&str]) -> Self {
3780		self.prefetch_related_fields = fields.iter().map(|s| s.to_string()).collect();
3781		self
3782	}
3783
3784	/// Generate SELECT queries for prefetch_related fields
3785	///
3786	/// Returns a vector of (field_name, SelectStatement) tuples, one for each prefetch field.
3787	/// Each query fetches related objects using IN clause with collected primary keys.
3788	///
3789	/// # Examples
3790	///
3791	/// ```no_run
3792	/// # use reinhardt_db::orm::Model;
3793	/// # use serde::{Serialize, Deserialize};
3794	/// # #[derive(Clone, Serialize, Deserialize)]
3795	/// # struct Post { id: Option<i64> }
3796	/// # #[derive(Clone)]
3797	/// # struct PostFields;
3798	/// # impl reinhardt_db::orm::model::FieldSelector for PostFields {
3799	/// #     fn with_alias(self, _alias: &str) -> Self { self }
3800	/// # }
3801	/// # impl Model for Post {
3802	/// #     type PrimaryKey = i64;
3803	/// #     type Fields = PostFields;
3804	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
3805	/// #     fn table_name() -> &'static str { "posts" }
3806	/// #     fn new_fields() -> Self::Fields { PostFields }
3807	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
3808	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
3809	/// # }
3810	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
3811	/// let queryset = Post::objects()
3812	///     .prefetch_related(&["comments", "tags"]);
3813	///
3814	/// let main_results = queryset.all().await?; // Main query
3815	/// let pk_values = vec![1, 2, 3]; // Collected from main results
3816	///
3817	/// let prefetch_queries = queryset.prefetch_related_queries(&pk_values);
3818	/// // Returns SelectStatements for:
3819	/// // 1. comments: SELECT * FROM comments WHERE post_id IN ($1, $2, $3)
3820	/// // 2. tags: SELECT tags.* FROM tags
3821	/// //          INNER JOIN post_tags ON tags.id = post_tags.tag_id
3822	/// //          WHERE post_tags.post_id IN ($1, $2, $3)
3823	/// # Ok(())
3824	/// # }
3825	/// ```
3826	pub fn prefetch_related_queries(&self, pk_values: &[i64]) -> Vec<(String, SelectStatement)> {
3827		if pk_values.is_empty() {
3828			return Vec::new();
3829		}
3830
3831		let mut queries = Vec::new();
3832
3833		for related_field in &self.prefetch_related_fields {
3834			// Determine if this is a many-to-many relation or one-to-many
3835			// by querying the model's relationship metadata
3836			let is_m2m = self.is_many_to_many_relation(related_field);
3837
3838			let stmt = if is_m2m {
3839				self.prefetch_many_to_many_query(related_field, pk_values)
3840			} else {
3841				self.prefetch_one_to_many_query(related_field, pk_values)
3842			};
3843
3844			queries.push((related_field.clone(), stmt));
3845		}
3846
3847		queries
3848	}
3849
3850	/// Check if a related field is a many-to-many relation
3851	///
3852	/// Determines relationship type by querying the model's metadata.
3853	/// Returns true if the relationship is defined as ManyToMany in the model metadata.
3854	fn is_many_to_many_relation(&self, related_field: &str) -> bool {
3855		// Get relationship metadata from the model
3856		let relations = T::relationship_metadata();
3857
3858		// Find the relationship with the matching name
3859		relations
3860			.iter()
3861			.find(|rel| rel.name == related_field)
3862			.map(|rel| rel.relationship_type == super::relationship::RelationshipType::ManyToMany)
3863			.unwrap_or(false)
3864	}
3865
3866	/// Generate query for one-to-many prefetch
3867	///
3868	/// Generates: SELECT * FROM related_table WHERE fk_field IN (pk_values)
3869	fn prefetch_one_to_many_query(
3870		&self,
3871		related_field: &str,
3872		pk_values: &[i64],
3873	) -> SelectStatement {
3874		let table_name = T::table_name();
3875		let related_table = Alias::new(format!("{}s", related_field));
3876		let fk_field = Alias::new(format!("{}_id", table_name.trim_end_matches('s')));
3877
3878		let mut stmt = Query::select();
3879		stmt.from(related_table).column(ColumnRef::Asterisk);
3880
3881		// Add IN clause with pk_values
3882		let values: Vec<reinhardt_query::value::Value> =
3883			pk_values.iter().map(|&id| id.into()).collect();
3884		stmt.and_where(Expr::col(fk_field).is_in(values));
3885
3886		stmt.to_owned()
3887	}
3888
3889	/// Generate query for many-to-many prefetch
3890	///
3891	/// Generates: SELECT related.*, junction.main_id FROM related
3892	///            INNER JOIN junction ON related.id = junction.related_id
3893	///            WHERE junction.main_id IN (pk_values)
3894	fn prefetch_many_to_many_query(
3895		&self,
3896		related_field: &str,
3897		pk_values: &[i64],
3898	) -> SelectStatement {
3899		let table_name = T::table_name();
3900		// Apply the canonical M2M naming rule used by
3901		// `ManyToManyAccessor::default_through_table` and the autodetector
3902		// (`crates/reinhardt-db/src/migrations/autodetector.rs`):
3903		// `{source_table.to_lowercase()}_{to_snake_case(field_name)}`.
3904		// Without this, prefetch joins target a junction table whose
3905		// casing/snake-case diverges from what `makemigrations` produced
3906		// for the same M2M field (#4659).
3907		let junction_table = Alias::new(format!(
3908			"{}_{}",
3909			table_name.to_lowercase(),
3910			to_snake_case(related_field)
3911		));
3912
3913		// Look up relationship metadata to derive FK names correctly
3914		let rel_info = T::relationship_metadata().into_iter().find(|r| {
3915			r.name == related_field
3916				&& r.relationship_type == super::relationship::RelationshipType::ManyToMany
3917		});
3918
3919		// Derive related table name from metadata
3920		let related_table = if let Some(ref info) = rel_info {
3921			Alias::new(to_snake_case(&info.related_model).to_lowercase())
3922		} else {
3923			// Fallback to pluralization heuristic
3924			Alias::new(format!("{}s", related_field))
3925		};
3926
3927		// Derive junction FK names from metadata or use default_link_fields logic
3928		let table_name_lower = table_name.to_lowercase();
3929		let (junction_main_fk, junction_related_fk) = if let Some(ref info) = rel_info {
3930			let source_fk = if let Some(ref sf) = info.source_field {
3931				sf.clone()
3932			} else {
3933				// Mirror ManyToManyAccessor::default_link_fields logic
3934				let related_lower = to_snake_case(&info.related_model).to_lowercase();
3935				if table_name_lower == related_lower {
3936					format!("from_{}_id", table_name_lower)
3937				} else {
3938					format!("{}_id", table_name_lower)
3939				}
3940			};
3941
3942			let target_fk = if let Some(ref tf) = info.target_field {
3943				tf.clone()
3944			} else {
3945				let related_lower = to_snake_case(&info.related_model).to_lowercase();
3946				if table_name_lower == related_lower {
3947					format!("to_{}_id", table_name_lower)
3948				} else {
3949					format!("{}_id", to_snake_case(related_field))
3950				}
3951			};
3952
3953			(Alias::new(source_fk), Alias::new(target_fk))
3954		} else {
3955			// Fallback to heuristics
3956			let source_fk = format!("{}_id", table_name_lower);
3957			let target_fk = format!("{}_id", to_snake_case(related_field));
3958			(Alias::new(source_fk), Alias::new(target_fk))
3959		};
3960
3961		let mut stmt = Query::select();
3962		stmt.from(related_table.clone())
3963			.column(ColumnRef::table_asterisk(related_table.clone()))
3964			.column((junction_table.clone(), junction_main_fk.clone()))
3965			.inner_join(
3966				junction_table.clone(),
3967				Expr::col((related_table.clone(), Alias::new("id")))
3968					.equals((junction_table.clone(), junction_related_fk)),
3969			);
3970
3971		// Add IN clause with pk_values
3972		let values: Vec<reinhardt_query::value::Value> =
3973			pk_values.iter().map(|&id| id.into()).collect();
3974		stmt.and_where(Expr::col((junction_table, junction_main_fk)).is_in(values));
3975
3976		stmt.to_owned()
3977	}
3978
3979	/// Execute the queryset and return all matching records
3980	///
3981	/// Fetches all records from the database that match the accumulated filters.
3982	/// If `select_related` fields are specified, performs JOIN queries for eager loading.
3983	///
3984	/// # Examples
3985	///
3986	/// ```no_run
3987	/// # use reinhardt_db::orm::Model;
3988	/// # use reinhardt_db::orm::{Filter, FilterOperator, FilterValue};
3989	/// # use serde::{Serialize, Deserialize};
3990	/// # #[derive(Clone, Serialize, Deserialize)]
3991	/// # struct User { id: Option<i64> }
3992	/// # #[derive(Clone)]
3993	/// # struct UserFields;
3994	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
3995	/// #     fn with_alias(self, _alias: &str) -> Self { self }
3996	/// # }
3997	/// # impl Model for User {
3998	/// #     type PrimaryKey = i64;
3999	/// #     type Fields = UserFields;
4000	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
4001	/// #     fn table_name() -> &'static str { "users" }
4002	/// #     fn new_fields() -> Self::Fields { UserFields }
4003	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
4004	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
4005	/// # }
4006	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
4007	/// // Fetch all users (Manager.all() returns QuerySet, then call .all().await)
4008	/// let users = User::objects().all().all().await?;
4009	///
4010	/// // Fetch filtered users with eager loading
4011	/// let active_users = User::objects()
4012	///     .filter(Filter::new(
4013	///         "is_active",
4014	///         FilterOperator::Eq,
4015	///         FilterValue::Boolean(true),
4016	///     ))
4017	///     .select_related(&["profile"])
4018	///     .all()
4019	///     .await?;
4020	/// # Ok(())
4021	/// # }
4022	/// ```
4023	///
4024	/// # Errors
4025	///
4026	/// Returns an error if:
4027	/// - Database connection fails
4028	/// - SQL execution fails
4029	/// - Deserialization of results fails
4030	pub async fn all(&self) -> reinhardt_core::exception::Result<Vec<T>>
4031	where
4032		T: serde::de::DeserializeOwned,
4033	{
4034		let conn = super::manager::get_connection().await?;
4035
4036		let stmt = if self.select_related_fields.is_empty() {
4037			// Simple SELECT without JOINs
4038			let mut stmt = Query::select();
4039			stmt.from(Alias::new(T::table_name()));
4040
4041			// Column selection considering selected_fields and deferred_fields
4042			if let Some(ref fields) = self.selected_fields {
4043				for field in fields {
4044					// Detect raw SQL expressions (like COUNT(*), AVG(price), etc.)
4045					if field.contains('(') && field.contains(')') {
4046						// Use expr() for raw SQL expressions - clone to satisfy lifetime
4047						stmt.expr(Expr::cust(field.clone()));
4048					} else {
4049						// Regular column reference
4050						let col_ref = parse_column_reference(field);
4051						stmt.column(col_ref);
4052					}
4053				}
4054			} else if !self.deferred_fields.is_empty() {
4055				let all_fields = T::field_metadata();
4056				for field in all_fields {
4057					if !self.deferred_fields.contains(&field.name) {
4058						let col_ref = parse_column_reference(&field.name);
4059						stmt.column(col_ref);
4060					}
4061				}
4062			} else {
4063				stmt.column(ColumnRef::Asterisk);
4064			}
4065
4066			if let Some(cond) = self.build_where_condition()? {
4067				stmt.cond_where(cond);
4068			}
4069
4070			// Apply ORDER BY clause
4071			for order_field in &self.order_by_fields {
4072				let (field, is_desc) = if let Some(stripped) = order_field.strip_prefix('-') {
4073					(stripped, true)
4074				} else {
4075					(order_field.as_str(), false)
4076				};
4077
4078				let col_ref = parse_column_reference(field);
4079				let expr = Expr::col(col_ref);
4080				if is_desc {
4081					stmt.order_by_expr(expr, Order::Desc);
4082				} else {
4083					stmt.order_by_expr(expr, Order::Asc);
4084				}
4085			}
4086
4087			// Apply LIMIT/OFFSET
4088			if let Some(limit) = self.limit {
4089				stmt.limit(limit as u64);
4090			}
4091			if let Some(offset) = self.offset {
4092				stmt.offset(offset as u64);
4093			}
4094
4095			stmt.to_owned()
4096		} else {
4097			// SELECT with JOINs for select_related
4098			self.select_related_query()
4099		};
4100
4101		// Convert statement to SQL with inline values (no placeholders)
4102		let sql = stmt.to_string(PostgresQueryBuilder);
4103
4104		// Execute query and deserialize results
4105		let started_at = Instant::now();
4106		let query_result = conn.query(&sql, vec![]).await;
4107		let duration = started_at.elapsed();
4108
4109		let rows = match query_result {
4110			Ok(rows) => {
4111				super::instrumentation::instrumentation()
4112					.orm_query_end_with_params(&sql, &[], duration)
4113					.await;
4114				rows
4115			}
4116			Err(error) => {
4117				super::instrumentation::instrumentation()
4118					.query_error(&sql, &format!("{error:?}"), duration)
4119					.await;
4120				return Err(error.into());
4121			}
4122		};
4123		rows.into_iter()
4124			.map(|row| {
4125				serde_json::from_value(serde_json::to_value(&row.data).map_err(|e| {
4126					reinhardt_core::exception::Error::Database(format!(
4127						"Serialization error: {}",
4128						e
4129					))
4130				})?)
4131				.map_err(|e| {
4132					reinhardt_core::exception::Error::Database(format!(
4133						"Deserialization error: {}",
4134						e
4135					))
4136				})
4137			})
4138			.collect()
4139	}
4140
4141	/// Execute the queryset and return the first matching record
4142	///
4143	/// Returns `None` if no records match the query.
4144	///
4145	/// # Examples
4146	///
4147	/// ```no_run
4148	/// # use reinhardt_db::orm::Model;
4149	/// # use reinhardt_db::orm::{Filter, FilterOperator, FilterValue};
4150	/// # use serde::{Serialize, Deserialize};
4151	/// # #[derive(Clone, Serialize, Deserialize)]
4152	/// # struct User { id: Option<i64>, username: String }
4153	/// # #[derive(Clone)]
4154	/// # struct UserFields;
4155	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
4156	/// #     fn with_alias(self, _alias: &str) -> Self { self }
4157	/// # }
4158	/// # impl Model for User {
4159	/// #     type PrimaryKey = i64;
4160	/// #     type Fields = UserFields;
4161	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
4162	/// #     fn table_name() -> &'static str { "users" }
4163	/// #     fn new_fields() -> Self::Fields { UserFields }
4164	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
4165	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
4166	/// # }
4167	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
4168	/// // Fetch first active user
4169	/// let user = User::objects()
4170	///     .filter(Filter::new(
4171	///         "is_active",
4172	///         FilterOperator::Eq,
4173	///         FilterValue::Boolean(true),
4174	///     ))
4175	///     .first()
4176	///     .await?;
4177	///
4178	/// match user {
4179	///     Some(u) => println!("Found user: {}", u.username),
4180	///     None => println!("No active users found"),
4181	/// }
4182	/// # Ok(())
4183	/// # }
4184	/// ```
4185	pub async fn first(&self) -> reinhardt_core::exception::Result<Option<T>>
4186	where
4187		T: serde::de::DeserializeOwned,
4188	{
4189		let mut results = self.all().await?;
4190		Ok(results.drain(..).next())
4191	}
4192
4193	/// Execute the queryset and return a single matching record
4194	///
4195	/// Returns an error if zero or multiple records are found.
4196	///
4197	/// # Examples
4198	///
4199	/// ```no_run
4200	/// # use reinhardt_db::orm::Model;
4201	/// # use reinhardt_db::orm::{Filter, FilterOperator, FilterValue};
4202	/// # use serde::{Serialize, Deserialize};
4203	/// # #[derive(Clone, Serialize, Deserialize)]
4204	/// # struct User { id: Option<i64>, email: String }
4205	/// # #[derive(Clone)]
4206	/// # struct UserFields;
4207	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
4208	/// #     fn with_alias(self, _alias: &str) -> Self { self }
4209	/// # }
4210	/// # impl Model for User {
4211	/// #     type PrimaryKey = i64;
4212	/// #     type Fields = UserFields;
4213	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
4214	/// #     fn table_name() -> &'static str { "users" }
4215	/// #     fn new_fields() -> Self::Fields { UserFields }
4216	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
4217	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
4218	/// # }
4219	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
4220	/// // Fetch user with specific email (must be unique)
4221	/// let user = User::objects()
4222	///     .filter(Filter::new(
4223	///         "email",
4224	///         FilterOperator::Eq,
4225	///         FilterValue::String("alice@example.com".to_string()),
4226	///     ))
4227	///     .get()
4228	///     .await?;
4229	/// # Ok(())
4230	/// # }
4231	/// ```
4232	///
4233	/// # Errors
4234	///
4235	/// Returns an error if:
4236	/// - No records match the query
4237	/// - Multiple records match the query
4238	/// - Database connection fails
4239	pub async fn get(&self) -> reinhardt_core::exception::Result<T>
4240	where
4241		T: serde::de::DeserializeOwned,
4242	{
4243		let results = self.all().await?;
4244		match results.len() {
4245			0 => Err(reinhardt_core::exception::Error::Database(
4246				"No record found matching the query".to_string(),
4247			)),
4248			1 => Ok(results.into_iter().next().unwrap()),
4249			n => Err(reinhardt_core::exception::Error::Database(format!(
4250				"Multiple records found ({}), expected exactly one",
4251				n
4252			))),
4253		}
4254	}
4255
4256	/// Execute the queryset with an explicit database connection and return all records
4257	///
4258	/// # Examples
4259	///
4260	/// ```no_run
4261	/// # use reinhardt_db::orm::Model;
4262	/// # use serde::{Serialize, Deserialize};
4263	/// # #[derive(Clone, Serialize, Deserialize)]
4264	/// # struct User { id: Option<i64> }
4265	/// # #[derive(Clone)]
4266	/// # struct UserFields;
4267	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
4268	/// #     fn with_alias(self, _alias: &str) -> Self { self }
4269	/// # }
4270	/// # impl Model for User {
4271	/// #     type PrimaryKey = i64;
4272	/// #     type Fields = UserFields;
4273	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
4274	/// #     fn table_name() -> &'static str { "users" }
4275	/// #     fn new_fields() -> Self::Fields { UserFields }
4276	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
4277	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
4278	/// # }
4279	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
4280	/// # let db = reinhardt_db::orm::manager::get_connection().await?;
4281	/// let users = User::objects()
4282	///     .all()
4283	///     .all_with_db(&db)
4284	///     .await?;
4285	/// # Ok(())
4286	/// # }
4287	/// ```
4288	pub async fn all_with_db(
4289		&self,
4290		conn: &super::connection::DatabaseConnection,
4291	) -> reinhardt_core::exception::Result<Vec<T>>
4292	where
4293		T: serde::de::DeserializeOwned,
4294	{
4295		let stmt = if self.select_related_fields.is_empty() {
4296			let mut stmt = Query::select();
4297			stmt.from(Alias::new(T::table_name()));
4298
4299			// Column selection considering selected_fields and deferred_fields
4300			if let Some(ref fields) = self.selected_fields {
4301				for field in fields {
4302					// Detect raw SQL expressions (like COUNT(*), AVG(price), etc.)
4303					if field.contains('(') && field.contains(')') {
4304						// Use expr() for raw SQL expressions - clone to satisfy lifetime
4305						stmt.expr(Expr::cust(field.clone()));
4306					} else {
4307						// Regular column reference
4308						let col_ref = parse_column_reference(field);
4309						stmt.column(col_ref);
4310					}
4311				}
4312			} else if !self.deferred_fields.is_empty() {
4313				let all_fields = T::field_metadata();
4314				for field in all_fields {
4315					if !self.deferred_fields.contains(&field.name) {
4316						let col_ref = parse_column_reference(&field.name);
4317						stmt.column(col_ref);
4318					}
4319				}
4320			} else {
4321				stmt.column(ColumnRef::Asterisk);
4322			}
4323
4324			if let Some(cond) = self.build_where_condition()? {
4325				stmt.cond_where(cond);
4326			}
4327
4328			// Apply ORDER BY clause
4329			for order_field in &self.order_by_fields {
4330				let (field, is_desc) = if let Some(stripped) = order_field.strip_prefix('-') {
4331					(stripped, true)
4332				} else {
4333					(order_field.as_str(), false)
4334				};
4335
4336				let col_ref = parse_column_reference(field);
4337				let expr = Expr::col(col_ref);
4338				if is_desc {
4339					stmt.order_by_expr(expr, Order::Desc);
4340				} else {
4341					stmt.order_by_expr(expr, Order::Asc);
4342				}
4343			}
4344
4345			// Apply LIMIT/OFFSET
4346			if let Some(limit) = self.limit {
4347				stmt.limit(limit as u64);
4348			}
4349			if let Some(offset) = self.offset {
4350				stmt.offset(offset as u64);
4351			}
4352
4353			stmt.to_owned()
4354		} else {
4355			self.select_related_query()
4356		};
4357
4358		let sql = render_select_statement(&stmt, conn.backend());
4359
4360		let started_at = Instant::now();
4361		let query_result = conn.query(&sql, vec![]).await;
4362		let duration = started_at.elapsed();
4363
4364		let rows = match query_result {
4365			Ok(rows) => {
4366				super::instrumentation::instrumentation()
4367					.orm_query_end_with_params(&sql, &[], duration)
4368					.await;
4369				rows
4370			}
4371			Err(error) => {
4372				super::instrumentation::instrumentation()
4373					.query_error(&sql, &format!("{error:?}"), duration)
4374					.await;
4375				return Err(error.into());
4376			}
4377		};
4378		rows.into_iter()
4379			.map(|row| {
4380				serde_json::from_value(serde_json::to_value(&row.data).map_err(|e| {
4381					reinhardt_core::exception::Error::Database(format!(
4382						"Serialization error: {}",
4383						e
4384					))
4385				})?)
4386				.map_err(|e| {
4387					reinhardt_core::exception::Error::Database(format!(
4388						"Deserialization error: {}",
4389						e
4390					))
4391				})
4392			})
4393			.collect()
4394	}
4395
4396	/// Execute the queryset with an explicit database connection and return a single record
4397	///
4398	/// # Examples
4399	///
4400	/// ```no_run
4401	/// # use reinhardt_db::orm::Model;
4402	/// # use serde::{Serialize, Deserialize};
4403	/// # #[derive(Clone, Serialize, Deserialize)]
4404	/// # struct User { id: Option<i64> }
4405	/// # #[derive(Clone)]
4406	/// # struct UserFields;
4407	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
4408	/// #     fn with_alias(self, _alias: &str) -> Self { self }
4409	/// # }
4410	/// # impl Model for User {
4411	/// #     type PrimaryKey = i64;
4412	/// #     type Fields = UserFields;
4413	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
4414	/// #     fn table_name() -> &'static str { "users" }
4415	/// #     fn new_fields() -> Self::Fields { UserFields }
4416	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
4417	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
4418	/// # }
4419	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
4420	/// # let user_id = 1;
4421	/// let db = reinhardt_db::orm::manager::get_connection().await?;
4422	/// let user = User::objects()
4423	///     .filter(reinhardt_db::orm::Filter::new("id", reinhardt_db::orm::FilterOperator::Eq, reinhardt_db::orm::FilterValue::Integer(user_id)))
4424	///     .get_with_db(&db)
4425	///     .await?;
4426	/// # Ok(())
4427	/// # }
4428	/// ```
4429	pub async fn get_with_db(
4430		&self,
4431		conn: &super::connection::DatabaseConnection,
4432	) -> reinhardt_core::exception::Result<T>
4433	where
4434		T: serde::de::DeserializeOwned,
4435	{
4436		let results = self.all_with_db(conn).await?;
4437		match results.len() {
4438			0 => Err(reinhardt_core::exception::Error::NotFound(
4439				"No record found matching the query".to_string(),
4440			)),
4441			1 => Ok(results.into_iter().next().unwrap()),
4442			n => Err(reinhardt_core::exception::Error::Database(format!(
4443				"Multiple records found ({}), expected exactly one",
4444				n
4445			))),
4446		}
4447	}
4448
4449	/// Execute the queryset with an explicit database connection and return the first record
4450	///
4451	/// # Examples
4452	///
4453	/// ```no_run
4454	/// # use reinhardt_db::orm::Model;
4455	/// # use serde::{Serialize, Deserialize};
4456	/// # #[derive(Clone, Serialize, Deserialize)]
4457	/// # struct User { id: Option<i64> }
4458	/// # #[derive(Clone)]
4459	/// # struct UserFields;
4460	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
4461	/// #     fn with_alias(self, _alias: &str) -> Self { self }
4462	/// # }
4463	/// # impl Model for User {
4464	/// #     type PrimaryKey = i64;
4465	/// #     type Fields = UserFields;
4466	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
4467	/// #     fn table_name() -> &'static str { "users" }
4468	/// #     fn new_fields() -> Self::Fields { UserFields }
4469	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
4470	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
4471	/// # }
4472	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
4473	/// let db = reinhardt_db::orm::manager::get_connection().await?;
4474	/// let user = User::objects()
4475	///     .filter(reinhardt_db::orm::Filter::new("status", reinhardt_db::orm::FilterOperator::Eq, reinhardt_db::orm::FilterValue::String("active".to_string())))
4476	///     .first_with_db(&db)
4477	///     .await?;
4478	/// # Ok(())
4479	/// # }
4480	/// ```
4481	pub async fn first_with_db(
4482		&self,
4483		conn: &super::connection::DatabaseConnection,
4484	) -> reinhardt_core::exception::Result<Option<T>>
4485	where
4486		T: serde::de::DeserializeOwned,
4487	{
4488		let mut results = self.all_with_db(conn).await?;
4489		Ok(results.drain(..).next())
4490	}
4491
4492	/// Execute the queryset and return the count of matching records
4493	///
4494	/// More efficient than calling `all().await?.len()` as it only executes COUNT query.
4495	///
4496	/// # Examples
4497	///
4498	/// ```no_run
4499	/// # use reinhardt_db::orm::Model;
4500	/// # use reinhardt_db::orm::{Filter, FilterOperator, FilterValue};
4501	/// # use serde::{Serialize, Deserialize};
4502	/// # #[derive(Clone, Serialize, Deserialize)]
4503	/// # struct User { id: Option<i64> }
4504	/// # #[derive(Clone)]
4505	/// # struct UserFields;
4506	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
4507	/// #     fn with_alias(self, _alias: &str) -> Self { self }
4508	/// # }
4509	/// # impl Model for User {
4510	/// #     type PrimaryKey = i64;
4511	/// #     type Fields = UserFields;
4512	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
4513	/// #     fn table_name() -> &'static str { "users" }
4514	/// #     fn new_fields() -> Self::Fields { UserFields }
4515	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
4516	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
4517	/// # }
4518	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
4519	/// // Count active users
4520	/// let count = User::objects()
4521	///     .filter(Filter::new(
4522	///         "is_active",
4523	///         FilterOperator::Eq,
4524	///         FilterValue::Boolean(true),
4525	///     ))
4526	///     .count()
4527	///     .await?;
4528	///
4529	/// println!("Active users: {}", count);
4530	/// # Ok(())
4531	/// # }
4532	/// ```
4533	pub async fn count(&self) -> reinhardt_core::exception::Result<usize> {
4534		use reinhardt_query::prelude::{Func, PostgresQueryBuilder, QueryBuilder};
4535
4536		let conn = super::manager::get_connection().await?;
4537
4538		// Build COUNT query using reinhardt-query
4539		let mut stmt = Query::select();
4540		stmt.from(Alias::new(T::table_name()))
4541			.expr(Func::count(Expr::asterisk().into_simple_expr()));
4542
4543		// Add WHERE conditions
4544		if let Some(cond) = self.build_where_condition()? {
4545			stmt.cond_where(cond);
4546		}
4547
4548		// Convert to SQL and extract parameter values
4549		let (sql, values) = PostgresQueryBuilder.build_select(&stmt);
4550
4551		// Convert reinhardt_query::value::Values to QueryValue
4552		let params = super::execution::convert_values(values);
4553
4554		// Execute query with parameters
4555		let rows = conn.query(&sql, params).await?;
4556		if let Some(row) = rows.first() {
4557			// Extract count from first row
4558			if let Some(count_value) = row.data.get("count")
4559				&& let Some(count) = count_value.as_i64()
4560			{
4561				return Ok(count as usize);
4562			}
4563		}
4564
4565		Ok(0)
4566	}
4567
4568	/// Check if any records match the queryset
4569	///
4570	/// More efficient than calling `count().await? > 0` as it can short-circuit.
4571	///
4572	/// # Examples
4573	///
4574	/// ```no_run
4575	/// # use reinhardt_db::orm::Model;
4576	/// # use reinhardt_db::orm::{Filter, FilterOperator, FilterValue};
4577	/// # use serde::{Serialize, Deserialize};
4578	/// # #[derive(Clone, Serialize, Deserialize)]
4579	/// # struct User { id: Option<i64> }
4580	/// # #[derive(Clone)]
4581	/// # struct UserFields;
4582	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
4583	/// #     fn with_alias(self, _alias: &str) -> Self { self }
4584	/// # }
4585	/// # impl Model for User {
4586	/// #     type PrimaryKey = i64;
4587	/// #     type Fields = UserFields;
4588	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
4589	/// #     fn table_name() -> &'static str { "users" }
4590	/// #     fn new_fields() -> Self::Fields { UserFields }
4591	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
4592	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
4593	/// # }
4594	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
4595	/// // Check if any admin users exist
4596	/// let has_admin = User::objects()
4597	///     .filter(Filter::new(
4598	///         "role",
4599	///         FilterOperator::Eq,
4600	///         FilterValue::String("admin".to_string()),
4601	///     ))
4602	///     .exists()
4603	///     .await?;
4604	///
4605	/// if has_admin {
4606	///     println!("Admin users exist");
4607	/// }
4608	/// # Ok(())
4609	/// # }
4610	/// ```
4611	pub async fn exists(&self) -> reinhardt_core::exception::Result<bool> {
4612		let count = self.count().await?;
4613		Ok(count > 0)
4614	}
4615
4616	/// Create a new object in the database
4617	///
4618	/// # Examples
4619	///
4620	/// ```no_run
4621	/// # use reinhardt_db::orm::Model;
4622	/// # use serde::{Serialize, Deserialize};
4623	/// # #[derive(Clone, Serialize, Deserialize)]
4624	/// # struct User { id: Option<i64>, username: String, email: String }
4625	/// # #[derive(Clone)]
4626	/// # struct UserFields;
4627	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
4628	/// #     fn with_alias(self, _alias: &str) -> Self { self }
4629	/// # }
4630	/// # impl Model for User {
4631	/// #     type PrimaryKey = i64;
4632	/// #     type Fields = UserFields;
4633	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
4634	/// #     fn table_name() -> &'static str { "users" }
4635	/// #     fn new_fields() -> Self::Fields { UserFields }
4636	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
4637	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
4638	/// # }
4639	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
4640	/// let user = User {
4641	///     id: None,
4642	///     username: "alice".to_string(),
4643	///     email: "alice@example.com".to_string(),
4644	/// };
4645	/// let created = User::objects().create(&user).await?;
4646	/// # Ok(())
4647	/// # }
4648	/// ```
4649	pub async fn create(&self, object: T) -> reinhardt_core::exception::Result<T>
4650	where
4651		T: super::Model + Clone,
4652	{
4653		// Delegate to Manager::create() which handles all the SQL generation,
4654		// database connection, primary key retrieval, and error handling
4655		match &self.manager {
4656			Some(manager) => manager.create(&object).await,
4657			None => {
4658				// Fallback: create a new manager instance if none exists
4659				let manager = super::manager::Manager::<T>::new();
4660				manager.create(&object).await
4661			}
4662		}
4663	}
4664
4665	/// Generate UPDATE statement using reinhardt-query
4666	pub fn update_query(
4667		&self,
4668		updates: &HashMap<String, UpdateValue>,
4669	) -> reinhardt_query::prelude::UpdateStatement {
4670		let mut stmt = Query::update();
4671		stmt.table(Alias::new(T::table_name()));
4672
4673		// Add SET clauses
4674		for (field, value) in updates {
4675			stmt.value_expr(Alias::new(field), Self::update_value_to_query_expr(value));
4676		}
4677
4678		// Add WHERE conditions
4679		if let Some(cond) = self.build_where_condition_or_false() {
4680			stmt.cond_where(cond);
4681		}
4682
4683		stmt.to_owned()
4684	}
4685
4686	/// Generate an UPDATE statement for field assignments on rows matched by this `QuerySet`.
4687	///
4688	/// Unlike [`QuerySet::update_query`], this public partial-update builder validates
4689	/// that at least one non-empty predicate is present so callers cannot
4690	/// accidentally update every row in the model table.
4691	pub fn update_fields_query<I, A>(
4692		&self,
4693		values: I,
4694	) -> reinhardt_core::exception::Result<UpdateStatement>
4695	where
4696		I: IntoIterator<Item = A>,
4697		A: Into<FieldAssignment>,
4698	{
4699		let assignments = Self::collect_field_assignments(values);
4700		self.update_fields_query_from_assignments(&assignments)
4701	}
4702
4703	/// Generate PostgreSQL UPDATE SQL for field assignments on this `QuerySet`.
4704	///
4705	/// This mirrors [`QuerySet::update_sql`] for tests and custom SQL inspection.
4706	/// Use [`QuerySet::update_fields`] to execute the update against the configured
4707	/// database backend.
4708	pub fn update_fields_sql<I, A>(
4709		&self,
4710		values: I,
4711	) -> reinhardt_core::exception::Result<(String, Vec<String>)>
4712	where
4713		I: IntoIterator<Item = A>,
4714		A: Into<FieldAssignment>,
4715	{
4716		let stmt = self.update_fields_query(values)?;
4717		let (sql, values) = PostgresQueryBuilder.build_update(&stmt);
4718		let params = values
4719			.iter()
4720			.map(|value| Self::sea_value_to_string(value))
4721			.collect();
4722		Ok((sql, params))
4723	}
4724
4725	/// Update fields for rows matched by this `QuerySet` and return the affected row count.
4726	///
4727	/// The generated `UPDATE` preserves every filter, composite condition, and
4728	/// subquery predicate already attached to the `QuerySet`.
4729	pub async fn update_fields<I, A>(self, values: I) -> reinhardt_core::exception::Result<u64>
4730	where
4731		I: IntoIterator<Item = A>,
4732		A: Into<FieldAssignment>,
4733	{
4734		let conn = super::manager::get_connection().await?;
4735		self.update_fields_with_conn(&conn, values).await
4736	}
4737
4738	/// Update fields using an explicit database connection.
4739	pub async fn update_fields_with_conn<I, A>(
4740		&self,
4741		conn: &super::connection::DatabaseConnection,
4742		values: I,
4743	) -> reinhardt_core::exception::Result<u64>
4744	where
4745		I: IntoIterator<Item = A>,
4746		A: Into<FieldAssignment>,
4747	{
4748		let stmt = self.update_fields_query(values)?;
4749		let (sql, values) = Self::build_update_for_backend(&stmt, conn.backend());
4750		let params = super::execution::convert_values(values);
4751
4752		conn.execute(&sql, params)
4753			.await
4754			.map_err(|error| reinhardt_core::exception::Error::Database(error.to_string()))
4755	}
4756
4757	fn collect_field_assignments<I, A>(values: I) -> Vec<FieldAssignment>
4758	where
4759		I: IntoIterator<Item = A>,
4760		A: Into<FieldAssignment>,
4761	{
4762		values.into_iter().map(Into::into).collect()
4763	}
4764
4765	fn update_fields_query_from_assignments(
4766		&self,
4767		assignments: &[FieldAssignment],
4768	) -> reinhardt_core::exception::Result<UpdateStatement> {
4769		Self::validate_update_fields(assignments)?;
4770
4771		if !self.has_where_predicates() {
4772			return Err(reinhardt_core::exception::Error::Validation(
4773				"QuerySet::update_fields requires at least one filter predicate".to_string(),
4774			));
4775		}
4776
4777		let condition = self.build_where_condition()?.ok_or_else(|| {
4778			reinhardt_core::exception::Error::Validation(
4779				"QuerySet::update_fields requires at least one non-empty filter predicate"
4780					.to_string(),
4781			)
4782		})?;
4783
4784		let mut stmt = Query::update();
4785		stmt.table(Alias::new(T::table_name()));
4786
4787		for assignment in assignments {
4788			stmt.value_expr(
4789				Alias::new(assignment.field()),
4790				Self::update_value_to_query_expr(assignment.value()),
4791			);
4792		}
4793
4794		stmt.cond_where(condition);
4795
4796		Ok(stmt.to_owned())
4797	}
4798
4799	fn validate_update_fields(
4800		assignments: &[FieldAssignment],
4801	) -> reinhardt_core::exception::Result<()> {
4802		if assignments.is_empty() {
4803			return Err(reinhardt_core::exception::Error::Validation(
4804				"QuerySet::update_fields requires at least one field assignment".to_string(),
4805			));
4806		}
4807
4808		if assignments
4809			.iter()
4810			.any(|assignment| assignment.field().trim().is_empty())
4811		{
4812			return Err(reinhardt_core::exception::Error::Validation(
4813				"QuerySet::update_fields field names must not be empty".to_string(),
4814			));
4815		}
4816
4817		Ok(())
4818	}
4819
4820	fn build_update_for_backend(
4821		stmt: &UpdateStatement,
4822		backend: super::connection::DatabaseBackend,
4823	) -> (String, reinhardt_query::prelude::Values) {
4824		match backend {
4825			super::connection::DatabaseBackend::Postgres => PostgresQueryBuilder.build_update(stmt),
4826			super::connection::DatabaseBackend::MySql => MySqlQueryBuilder.build_update(stmt),
4827			super::connection::DatabaseBackend::Sqlite => SqliteQueryBuilder.build_update(stmt),
4828		}
4829	}
4830
4831	fn update_value_to_query_expr(value: &UpdateValue) -> Expr {
4832		match value {
4833			UpdateValue::String(s) => Expr::val(s.clone()),
4834			UpdateValue::Integer(i) => Expr::val(*i),
4835			UpdateValue::Float(f) => Expr::val(*f),
4836			UpdateValue::Boolean(b) => Expr::val(*b),
4837			UpdateValue::Null => Expr::cust("NULL"),
4838			UpdateValue::Timestamp(dt) => Expr::val(
4839				reinhardt_query::value::Value::ChronoDateTimeUtc(Some(Box::new(*dt))),
4840			),
4841			UpdateValue::Uuid(uuid) => {
4842				Expr::val(reinhardt_query::value::Value::Uuid(Some(Box::new(*uuid))))
4843			}
4844			UpdateValue::FieldRef(f) => Expr::col(Alias::new(&f.field)),
4845			UpdateValue::Expression(expr) => Self::expression_to_query_expr(expr),
4846		}
4847	}
4848
4849	/// Generate UPDATE SQL with WHERE clause and parameter binding
4850	///
4851	/// Returns SQL with placeholders ($1, $2, etc.) and the values to bind.
4852	///
4853	/// # Examples
4854	///
4855	/// ```no_run
4856	/// # use reinhardt_db::orm::Model;
4857	/// # use reinhardt_db::orm::{Filter, FilterOperator, FilterValue};
4858	/// # use reinhardt_db::orm::query::UpdateValue;
4859	/// # use serde::{Serialize, Deserialize};
4860	/// # #[derive(Clone, Serialize, Deserialize)]
4861	/// # struct User { id: Option<i64> }
4862	/// # #[derive(Clone)]
4863	/// # struct UserFields;
4864	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
4865	/// #     fn with_alias(self, _alias: &str) -> Self { self }
4866	/// # }
4867	/// # impl Model for User {
4868	/// #     type PrimaryKey = i64;
4869	/// #     type Fields = UserFields;
4870	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
4871	/// #     fn table_name() -> &'static str { "users" }
4872	/// #     fn new_fields() -> Self::Fields { UserFields }
4873	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
4874	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
4875	/// # }
4876	/// use std::collections::HashMap;
4877	/// let queryset = User::objects()
4878	///     .filter(Filter::new("id", FilterOperator::Eq, FilterValue::Integer(1)));
4879	///
4880	/// let mut updates = HashMap::new();
4881	/// updates.insert("name".to_string(), UpdateValue::String("Alice".to_string()));
4882	/// updates.insert("email".to_string(), UpdateValue::String("alice@example.com".to_string()));
4883	/// let (sql, params) = queryset.update_sql(&updates);
4884	/// // sql: "UPDATE users SET name = $1, email = $2 WHERE id = $3"
4885	/// // params: ["Alice", "alice@example.com", "1"]
4886	/// ```
4887	pub fn update_sql(&self, updates: &HashMap<String, UpdateValue>) -> (String, Vec<String>) {
4888		let stmt = self.update_query(updates);
4889		use reinhardt_query::prelude::{PostgresQueryBuilder, QueryBuilder};
4890		let (sql, values) = PostgresQueryBuilder.build_update(&stmt);
4891		let params: Vec<String> = values
4892			.iter()
4893			.map(|v| Self::sea_value_to_string(v))
4894			.collect();
4895		(sql, params)
4896	}
4897
4898	/// Convert reinhardt-query Value to String without SQL quoting
4899	fn sea_value_to_string(value: &reinhardt_query::value::Value) -> String {
4900		use reinhardt_query::value::Value;
4901		match value {
4902			Value::Bool(Some(b)) => b.to_string(),
4903			Value::TinyInt(Some(i)) => i.to_string(),
4904			Value::SmallInt(Some(i)) => i.to_string(),
4905			Value::Int(Some(i)) => i.to_string(),
4906			Value::BigInt(Some(i)) => i.to_string(),
4907			Value::TinyUnsigned(Some(i)) => i.to_string(),
4908			Value::SmallUnsigned(Some(i)) => i.to_string(),
4909			Value::Unsigned(Some(i)) => i.to_string(),
4910			Value::BigUnsigned(Some(i)) => i.to_string(),
4911			Value::Float(Some(f)) => f.to_string(),
4912			Value::Double(Some(f)) => f.to_string(),
4913			Value::String(Some(s)) => s.to_string(),
4914			Value::Bytes(Some(b)) => String::from_utf8_lossy(b).to_string(),
4915			Value::ChronoDateTimeUtc(Some(dt)) => dt.to_rfc3339(),
4916			Value::Uuid(Some(uuid)) => uuid.to_string(),
4917			_ => String::new(),
4918		}
4919	}
4920
4921	/// Generate DELETE SQL with WHERE clause and parameter binding
4922	///
4923	/// Returns SQL with placeholders ($1, $2, etc.) and the values to bind.
4924	///
4925	/// # Safety
4926	///
4927	/// This method will panic if no filters are set to prevent accidental deletion of all rows.
4928	/// Always use `.filter()` before calling this method.
4929	///
4930	/// # Examples
4931	///
4932	/// ```no_run
4933	/// # use reinhardt_db::orm::Model;
4934	/// # use reinhardt_db::orm::{Filter, FilterOperator, FilterValue};
4935	/// # use serde::{Serialize, Deserialize};
4936	/// # #[derive(Clone, Serialize, Deserialize)]
4937	/// # struct User { id: Option<i64> }
4938	/// # #[derive(Clone)]
4939	/// # struct UserFields;
4940	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
4941	/// #     fn with_alias(self, _alias: &str) -> Self { self }
4942	/// # }
4943	/// # impl Model for User {
4944	/// #     type PrimaryKey = i64;
4945	/// #     type Fields = UserFields;
4946	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
4947	/// #     fn table_name() -> &'static str { "users" }
4948	/// #     fn new_fields() -> Self::Fields { UserFields }
4949	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
4950	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
4951	/// # }
4952	/// let queryset = User::objects()
4953	///     .filter(Filter::new("id", FilterOperator::Eq, FilterValue::Integer(1)));
4954	///
4955	/// let (sql, params) = queryset.delete_sql();
4956	/// // sql: "DELETE FROM users WHERE id = $1"
4957	/// // params: ["1"]
4958	/// ```
4959	/// Generate DELETE statement using reinhardt-query
4960	pub fn delete_query(&self) -> reinhardt_query::prelude::DeleteStatement {
4961		if !self.has_where_predicates() {
4962			panic!(
4963				"DELETE without WHERE clause is not allowed. Use .filter() to specify which rows to delete."
4964			);
4965		}
4966
4967		let Some(cond) = self.build_where_condition_or_false() else {
4968			panic!(
4969				"DELETE without WHERE clause is not allowed. Use .filter() to specify which rows to delete."
4970			);
4971		};
4972
4973		let mut stmt = Query::delete();
4974		stmt.from_table(Alias::new(T::table_name()));
4975		stmt.cond_where(cond);
4976
4977		stmt.to_owned()
4978	}
4979
4980	/// Deletes sql.
4981	pub fn delete_sql(&self) -> (String, Vec<String>) {
4982		let stmt = self.delete_query();
4983		use reinhardt_query::prelude::{PostgresQueryBuilder, QueryBuilder};
4984		let (sql, values) = PostgresQueryBuilder.build_delete(&stmt);
4985		let params: Vec<String> = values
4986			.iter()
4987			.map(|v| Self::sea_value_to_string(v))
4988			.collect();
4989		(sql, params)
4990	}
4991
4992	/// Retrieve a single object by composite primary key
4993	///
4994	/// This method queries the database using all fields that compose the composite primary key.
4995	/// It validates that all required primary key fields are provided and returns the matching record.
4996	///
4997	/// # Examples
4998	///
4999	/// ```no_run
5000	/// # use reinhardt_db::orm::Model;
5001	/// # use reinhardt_db::orm::composite_pk::{CompositePrimaryKey, PkValue};
5002	/// # use serde::{Serialize, Deserialize};
5003	/// # use std::collections::HashMap;
5004	/// # #[derive(Clone, Serialize, Deserialize)]
5005	/// # struct PostTag { post_id: i64, tag_id: i64 }
5006	/// # #[derive(Clone)]
5007	/// # struct PostTagFields;
5008	/// # impl reinhardt_db::orm::model::FieldSelector for PostTagFields {
5009	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5010	/// # }
5011	/// # impl Model for PostTag {
5012	/// #     type PrimaryKey = i64;
5013	/// #     type Fields = PostTagFields;
5014	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5015	/// #     fn table_name() -> &'static str { "post_tags" }
5016	/// #     fn new_fields() -> Self::Fields { PostTagFields }
5017	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { None }
5018	/// #     fn set_primary_key(&mut self, _value: Self::PrimaryKey) {}
5019	/// #     fn composite_primary_key() -> Option<CompositePrimaryKey> {
5020	/// #         CompositePrimaryKey::new(vec!["post_id".to_string(), "tag_id".to_string()]).ok()
5021	/// #     }
5022	/// # }
5023	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
5024	/// let mut pk_values = HashMap::new();
5025	/// pk_values.insert("post_id".to_string(), PkValue::Int(1));
5026	/// pk_values.insert("tag_id".to_string(), PkValue::Int(5));
5027	///
5028	/// let post_tag = PostTag::objects().get_composite(&pk_values).await?;
5029	/// # Ok(())
5030	/// # }
5031	/// ```
5032	///
5033	/// # Errors
5034	///
5035	/// Returns an error if:
5036	/// - The model doesn't have a composite primary key
5037	/// - Required primary key fields are missing from the provided values
5038	/// - No matching record is found in the database
5039	/// - Multiple records match (should not happen with a valid composite PK)
5040	pub async fn get_composite(
5041		&self,
5042		pk_values: &HashMap<String, super::composite_pk::PkValue>,
5043	) -> reinhardt_core::exception::Result<T>
5044	where
5045		T: super::Model + Clone,
5046	{
5047		use reinhardt_query::prelude::{
5048			Alias, BinOper, ColumnRef, Expr, PostgresQueryBuilder, Value,
5049		};
5050
5051		// Get composite primary key definition from the model
5052		let composite_pk = T::composite_primary_key().ok_or_else(|| {
5053			reinhardt_core::exception::Error::Database(
5054				"Model does not have a composite primary key".to_string(),
5055			)
5056		})?;
5057
5058		// Validate that all required PK fields are provided
5059		composite_pk.validate(pk_values).map_err(|e| {
5060			reinhardt_core::exception::Error::Database(format!(
5061				"Composite PK validation failed: {}",
5062				e
5063			))
5064		})?;
5065
5066		// Build SELECT query using reinhardt-query
5067		let table_name = T::table_name();
5068		let mut query = Query::select();
5069
5070		// Use Alias::new for table name
5071		let table_alias = Alias::new(table_name);
5072		query.from(table_alias).column(ColumnRef::Asterisk);
5073
5074		// Add WHERE conditions for each composite PK field
5075		for field_name in composite_pk.fields() {
5076			let pk_value: &super::composite_pk::PkValue = pk_values.get(field_name).unwrap();
5077			let col_alias = Alias::new(field_name);
5078
5079			match pk_value {
5080				&super::composite_pk::PkValue::Int(v) => {
5081					let condition = Expr::col(col_alias)
5082						.binary(BinOper::Equal, Expr::value(Value::BigInt(Some(v))));
5083					query.and_where(condition);
5084				}
5085				&super::composite_pk::PkValue::Uint(v) => {
5086					let condition = Expr::col(col_alias)
5087						.binary(BinOper::Equal, Expr::value(Value::BigInt(Some(v as i64))));
5088					query.and_where(condition);
5089				}
5090				super::composite_pk::PkValue::String(v) => {
5091					let condition = Expr::col(col_alias).binary(
5092						BinOper::Equal,
5093						Expr::value(Value::String(Some(Box::new(v.clone())))),
5094					);
5095					query.and_where(condition);
5096				}
5097				&super::composite_pk::PkValue::Bool(v) => {
5098					let condition = Expr::col(col_alias)
5099						.binary(BinOper::Equal, Expr::value(Value::Bool(Some(v))));
5100					query.and_where(condition);
5101				}
5102			}
5103		}
5104
5105		// Build SQL with inline values (no placeholders)
5106		let sql = query.to_string(PostgresQueryBuilder);
5107
5108		// Execute query using database connection
5109		let conn = super::manager::get_connection().await?;
5110
5111		// Execute the SELECT query
5112		let rows = conn.query(&sql, vec![]).await?;
5113
5114		// Composite PK queries should return exactly one row
5115		if rows.is_empty() {
5116			return Err(reinhardt_core::exception::Error::Database(
5117				"No record found matching the composite primary key".to_string(),
5118			));
5119		}
5120
5121		if rows.len() > 1 {
5122			return Err(reinhardt_core::exception::Error::Database(format!(
5123				"Multiple records found ({}) for composite primary key, expected exactly one",
5124				rows.len()
5125			)));
5126		}
5127
5128		// Deserialize the single row into the model
5129		let row = &rows[0];
5130		let value = serde_json::to_value(&row.data).map_err(|e| {
5131			reinhardt_core::exception::Error::Database(format!("Serialization error: {}", e))
5132		})?;
5133
5134		serde_json::from_value(value).map_err(|e| {
5135			reinhardt_core::exception::Error::Database(format!("Deserialization error: {}", e))
5136		})
5137	}
5138
5139	/// Add an annotation to the QuerySet
5140	///
5141	/// Annotations allow you to add calculated fields to query results using expressions,
5142	/// aggregations, or subqueries. The annotation will be added to the SELECT clause.
5143	///
5144	/// # Examples
5145	///
5146	/// ```no_run
5147	/// # use reinhardt_db::orm::Model;
5148	/// # use serde::{Serialize, Deserialize};
5149	/// # #[derive(Clone, Serialize, Deserialize)]
5150	/// # struct User { id: Option<i64> }
5151	/// # #[derive(Clone)]
5152	/// # struct UserFields;
5153	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
5154	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5155	/// # }
5156	/// # impl Model for User {
5157	/// #     type PrimaryKey = i64;
5158	/// #     type Fields = UserFields;
5159	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5160	/// #     fn table_name() -> &'static str { "users" }
5161	/// #     fn new_fields() -> Self::Fields { UserFields }
5162	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5163	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5164	/// # }
5165	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
5166	/// use reinhardt_db::orm::annotation::{Annotation, AnnotationValue};
5167	/// use reinhardt_db::orm::aggregation::Aggregate;
5168	///
5169	/// // Add aggregate annotation
5170	/// let users = User::objects()
5171	///     .annotate(Annotation::new("total_orders",
5172	///         AnnotationValue::Aggregate(Aggregate::count(Some("orders")))))
5173	///     .all()
5174	///     .await?;
5175	/// # Ok(())
5176	/// # }
5177	/// ```
5178	pub fn annotate(mut self, annotation: super::annotation::Annotation) -> Self {
5179		self.annotations.push(annotation);
5180		self
5181	}
5182
5183	/// Add a subquery annotation to the QuerySet (SELECT clause subquery)
5184	///
5185	/// This method adds a scalar subquery to the SELECT clause, allowing you to
5186	/// include computed values from related tables without explicit JOINs.
5187	///
5188	/// # Type Parameters
5189	///
5190	/// * `M` - The model type for the subquery
5191	/// * `F` - A closure that builds the subquery
5192	///
5193	/// # Parameters
5194	///
5195	/// * `name` - The alias for the subquery result column
5196	/// * `builder` - A closure that receives a fresh `QuerySet<M>` and returns a configured QuerySet
5197	///
5198	/// # Examples
5199	///
5200	/// ```no_run
5201	/// # use reinhardt_db::orm::Model;
5202	/// # use reinhardt_db::orm::{Filter, FilterOperator, FilterValue};
5203	/// # use reinhardt_db::orm::OuterRef;
5204	/// # use serde::{Serialize, Deserialize};
5205	/// # #[derive(Clone, Serialize, Deserialize)]
5206	/// # struct Author { id: Option<i64> }
5207	/// # #[derive(Clone)]
5208	/// # struct AuthorFields;
5209	/// # impl reinhardt_db::orm::model::FieldSelector for AuthorFields {
5210	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5211	/// # }
5212	/// # impl Model for Author {
5213	/// #     type PrimaryKey = i64;
5214	/// #     type Fields = AuthorFields;
5215	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5216	/// #     fn table_name() -> &'static str { "authors" }
5217	/// #     fn new_fields() -> Self::Fields { AuthorFields }
5218	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5219	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5220	/// # }
5221	/// # #[derive(Clone, Serialize, Deserialize)]
5222	/// # struct Book { id: Option<i64> }
5223	/// # #[derive(Clone)]
5224	/// # struct BookFields;
5225	/// # impl reinhardt_db::orm::model::FieldSelector for BookFields {
5226	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5227	/// # }
5228	/// # impl Model for Book {
5229	/// #     type PrimaryKey = i64;
5230	/// #     type Fields = BookFields;
5231	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5232	/// #     fn table_name() -> &'static str { "books" }
5233	/// #     fn new_fields() -> Self::Fields { BookFields }
5234	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5235	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5236	/// # }
5237	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
5238	/// // Add book count for each author
5239	/// let authors = Author::objects()
5240	///     .annotate_subquery::<Book, _>("book_count", |subq| {
5241	///         subq.filter(Filter::new(
5242	///             "author_id",
5243	///             FilterOperator::Eq,
5244	///             FilterValue::OuterRef(OuterRef::new("authors.id"))
5245	///         ))
5246	///         .values(&["COUNT(*)"])
5247	///     })
5248	///     .all()
5249	///     .await?;
5250	/// // Generates: SELECT *, (SELECT COUNT(*) FROM books WHERE author_id = authors.id) AS book_count FROM authors
5251	/// # Ok(())
5252	/// # }
5253	/// ```
5254	pub fn annotate_subquery<M, F>(mut self, name: &str, builder: F) -> Self
5255	where
5256		M: super::Model + 'static,
5257		F: FnOnce(QuerySet<M>) -> QuerySet<M>,
5258	{
5259		// Create a fresh QuerySet for the subquery model
5260		let subquery_qs = QuerySet::<M>::new();
5261		// Apply the builder to configure the subquery
5262		let configured_subquery = builder(subquery_qs);
5263		// Generate SQL for the subquery (wrapped in parentheses)
5264		let subquery_sql = configured_subquery.as_subquery();
5265
5266		// Add as annotation using AnnotationValue::Subquery
5267		let annotation = super::annotation::Annotation {
5268			alias: name.to_string(),
5269			value: super::annotation::AnnotationValue::Subquery(subquery_sql),
5270		};
5271		self.annotations.push(annotation);
5272		self
5273	}
5274
5275	/// Perform an aggregation on the QuerySet
5276	///
5277	/// Aggregations allow you to calculate summary statistics (COUNT, SUM, AVG, MAX, MIN)
5278	/// for the queryset. The aggregation result will be added to the SELECT clause.
5279	///
5280	/// # Examples
5281	///
5282	/// ```no_run
5283	/// # use reinhardt_db::orm::Model;
5284	/// # use serde::{Serialize, Deserialize};
5285	/// # #[derive(Serialize, Deserialize, Clone)]
5286	/// # struct User { id: Option<i64> }
5287	/// # #[derive(Clone)]
5288	/// # struct UserFields;
5289	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
5290	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5291	/// # }
5292	/// # impl Model for User {
5293	/// #     type PrimaryKey = i64;
5294	/// #     type Fields = UserFields;
5295	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5296	/// #     fn table_name() -> &'static str { "users" }
5297	/// #     fn new_fields() -> Self::Fields { UserFields }
5298	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5299	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5300	/// # }
5301	/// # #[derive(Serialize, Deserialize, Clone)]
5302	/// # struct Order { id: Option<i64> }
5303	/// # #[derive(Clone)]
5304	/// # struct OrderFields;
5305	/// # impl reinhardt_db::orm::model::FieldSelector for OrderFields {
5306	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5307	/// # }
5308	/// # impl Model for Order {
5309	/// #     type PrimaryKey = i64;
5310	/// #     type Fields = OrderFields;
5311	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5312	/// #     fn table_name() -> &'static str { "orders" }
5313	/// #     fn new_fields() -> Self::Fields { OrderFields }
5314	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5315	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5316	/// # }
5317	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
5318	/// use reinhardt_db::orm::aggregation::Aggregate;
5319	///
5320	/// // Count all users
5321	/// let result = User::objects()
5322	///     .all()
5323	///     .aggregate(Aggregate::count_all().with_alias("total_users"))
5324	///     .all()
5325	///     .await?;
5326	///
5327	/// // Sum order amounts
5328	/// let result = Order::objects()
5329	///     .all()
5330	///     .aggregate(Aggregate::sum("amount").with_alias("total_amount"))
5331	///     .all()
5332	///     .await?;
5333	/// # Ok(())
5334	/// # }
5335	/// ```
5336	pub fn aggregate(mut self, aggregate: super::aggregation::Aggregate) -> Self {
5337		// Convert Aggregate to Annotation and add to annotations list
5338		let alias = aggregate
5339			.alias
5340			.clone()
5341			.unwrap_or_else(|| aggregate.func.to_string().to_lowercase());
5342		let annotation = super::annotation::Annotation {
5343			alias,
5344			value: super::annotation::AnnotationValue::Aggregate(aggregate),
5345		};
5346		self.annotations.push(annotation);
5347		self
5348	}
5349
5350	/// Converts to sql.
5351	pub fn to_sql(&self) -> String {
5352		let mut stmt = if self.select_related_fields.is_empty() {
5353			// Simple SELECT without JOINs
5354			let mut stmt = Query::select();
5355
5356			// Apply FROM clause with optional alias
5357			if let Some(ref alias) = self.from_alias {
5358				stmt.from_as(Alias::new(T::table_name()), Alias::new(alias));
5359			} else {
5360				stmt.from(Alias::new(T::table_name()));
5361			}
5362
5363			// Apply DISTINCT if enabled
5364			if self.distinct_enabled {
5365				stmt.distinct();
5366			}
5367
5368			// Column selection considering selected_fields and deferred_fields
5369			if let Some(ref fields) = self.selected_fields {
5370				for field in fields {
5371					// Detect raw SQL expressions (like COUNT(*), AVG(price), etc.)
5372					if field.contains('(') && field.contains(')') {
5373						// Use expr() for raw SQL expressions - clone to satisfy lifetime
5374						stmt.expr(Expr::cust(field.clone()));
5375					} else {
5376						// Regular column reference
5377						let col_ref = parse_column_reference(field);
5378						stmt.column(col_ref);
5379					}
5380				}
5381			} else if !self.deferred_fields.is_empty() {
5382				let all_fields = T::field_metadata();
5383				for field in all_fields {
5384					if !self.deferred_fields.contains(&field.name) {
5385						let col_ref = parse_column_reference(&field.name);
5386						stmt.column(col_ref);
5387					}
5388				}
5389			} else {
5390				stmt.column(ColumnRef::Asterisk);
5391			}
5392
5393			// Apply JOINs
5394			for join in &self.joins {
5395				if join.on_condition.is_empty() {
5396					// CROSS JOIN (no ON condition)
5397					if let Some(ref alias) = join.target_alias {
5398						// CROSS JOIN with alias - reinhardt-query doesn't support this directly
5399						// Use regular join syntax instead
5400						stmt.cross_join((Alias::new(&join.target_table), Alias::new(alias)));
5401					} else {
5402						stmt.cross_join(Alias::new(&join.target_table));
5403					}
5404				} else {
5405					// Convert reinhardt JoinType to reinhardt-query JoinType
5406					let sea_join_type = match join.join_type {
5407						super::sqlalchemy_query::JoinType::Inner => SeaJoinType::InnerJoin,
5408						super::sqlalchemy_query::JoinType::Left => SeaJoinType::LeftJoin,
5409						super::sqlalchemy_query::JoinType::Right => SeaJoinType::RightJoin,
5410						super::sqlalchemy_query::JoinType::Full => SeaJoinType::FullOuterJoin,
5411					};
5412
5413					// Build the join with optional alias
5414					if let Some(ref alias) = join.target_alias {
5415						// JOIN with alias: (table, alias)
5416						stmt.join(
5417							sea_join_type,
5418							(Alias::new(&join.target_table), Alias::new(alias)),
5419							Expr::cust(join.on_condition.clone()),
5420						);
5421					} else {
5422						// JOIN without alias
5423						stmt.join(
5424							sea_join_type,
5425							Alias::new(&join.target_table),
5426							Expr::cust(join.on_condition.clone()),
5427						);
5428					}
5429				}
5430			}
5431
5432			// Apply WHERE conditions
5433			if let Some(cond) = self.build_where_condition_or_false() {
5434				stmt.cond_where(cond);
5435			}
5436
5437			// Apply GROUP BY
5438			for group_field in &self.group_by_fields {
5439				stmt.group_by_col(Alias::new(group_field));
5440			}
5441
5442			// Apply HAVING
5443			for having_cond in &self.having_conditions {
5444				match having_cond {
5445					HavingCondition::AggregateCompare {
5446						func,
5447						field,
5448						operator,
5449						value,
5450					} => {
5451						// Build aggregate function expression
5452						let agg_expr = match func {
5453							AggregateFunc::Avg => {
5454								Func::avg(Expr::col(Alias::new(field)).into_simple_expr())
5455							}
5456							AggregateFunc::Count => {
5457								if field == "*" {
5458									Func::count(Expr::asterisk().into_simple_expr())
5459								} else {
5460									Func::count(Expr::col(Alias::new(field)).into_simple_expr())
5461								}
5462							}
5463							AggregateFunc::Sum => {
5464								Func::sum(Expr::col(Alias::new(field)).into_simple_expr())
5465							}
5466							AggregateFunc::Min => {
5467								Func::min(Expr::col(Alias::new(field)).into_simple_expr())
5468							}
5469							AggregateFunc::Max => {
5470								Func::max(Expr::col(Alias::new(field)).into_simple_expr())
5471							}
5472						};
5473
5474						// Build comparison expression
5475						let having_expr = match operator {
5476							ComparisonOp::Eq => match value {
5477								AggregateValue::Int(v) => agg_expr.eq(*v),
5478								AggregateValue::Float(v) => agg_expr.eq(*v),
5479							},
5480							ComparisonOp::Ne => match value {
5481								AggregateValue::Int(v) => agg_expr.ne(*v),
5482								AggregateValue::Float(v) => agg_expr.ne(*v),
5483							},
5484							ComparisonOp::Gt => match value {
5485								AggregateValue::Int(v) => agg_expr.gt(*v),
5486								AggregateValue::Float(v) => agg_expr.gt(*v),
5487							},
5488							ComparisonOp::Gte => match value {
5489								AggregateValue::Int(v) => agg_expr.gte(*v),
5490								AggregateValue::Float(v) => agg_expr.gte(*v),
5491							},
5492							ComparisonOp::Lt => match value {
5493								AggregateValue::Int(v) => agg_expr.lt(*v),
5494								AggregateValue::Float(v) => agg_expr.lt(*v),
5495							},
5496							ComparisonOp::Lte => match value {
5497								AggregateValue::Int(v) => agg_expr.lte(*v),
5498								AggregateValue::Float(v) => agg_expr.lte(*v),
5499							},
5500						};
5501
5502						stmt.and_having(having_expr);
5503					}
5504				}
5505			}
5506
5507			// Apply ORDER BY
5508			for order_field in &self.order_by_fields {
5509				let (field, is_desc) = if let Some(stripped) = order_field.strip_prefix('-') {
5510					(stripped, true)
5511				} else {
5512					(order_field.as_str(), false)
5513				};
5514
5515				let col_ref = parse_column_reference(field);
5516				let expr = Expr::col(col_ref);
5517				if is_desc {
5518					stmt.order_by_expr(expr, Order::Desc);
5519				} else {
5520					stmt.order_by_expr(expr, Order::Asc);
5521				}
5522			}
5523
5524			// Apply LIMIT/OFFSET
5525			if let Some(limit) = self.limit {
5526				stmt.limit(limit as u64);
5527			}
5528			if let Some(offset) = self.offset {
5529				stmt.offset(offset as u64);
5530			}
5531
5532			stmt.to_owned()
5533		} else {
5534			// SELECT with JOINs for select_related
5535			self.select_related_query()
5536		};
5537
5538		// Add annotations to SELECT clause if any using reinhardt-query API
5539		// Collect annotation SQL strings first to handle lifetime issues
5540		// Note: Use to_sql_expr() to get expression without alias (reinhardt-query adds alias via expr_as)
5541		let annotation_exprs: Vec<_> = self
5542			.annotations
5543			.iter()
5544			.map(|a| (a.value.to_sql_expr(), a.alias.clone()))
5545			.collect();
5546
5547		for (value_sql, alias) in annotation_exprs {
5548			stmt.expr_as(Expr::cust(value_sql), Alias::new(alias));
5549		}
5550
5551		use reinhardt_query::prelude::PostgresQueryBuilder;
5552		let mut select_sql = stmt.to_string(PostgresQueryBuilder);
5553
5554		// Insert LATERAL JOIN clauses after FROM clause
5555		if !self.lateral_joins.is_empty() {
5556			let lateral_sql = self.lateral_joins.to_sql().join(" ");
5557
5558			// Find insertion point: after FROM clause, before WHERE/ORDER BY/LIMIT
5559			// Look for WHERE, ORDER BY, or end of string
5560			let insert_pos = select_sql
5561				.find(" WHERE ")
5562				.or_else(|| select_sql.find(" ORDER BY "))
5563				.or_else(|| select_sql.find(" LIMIT "))
5564				.unwrap_or(select_sql.len());
5565
5566			select_sql.insert_str(insert_pos, &format!(" {}", lateral_sql));
5567		}
5568
5569		// Replace FROM table with FROM subquery if from_subquery_sql is set
5570		if let Some(ref subquery_sql) = self.from_subquery_sql
5571			&& let Some(ref alias) = self.from_alias
5572		{
5573			// Pattern: FROM "table_name" AS "alias" or FROM "table_name"
5574			let from_pattern_with_alias = format!("FROM \"{}\" AS \"{}\"", T::table_name(), alias);
5575			let from_pattern_simple = format!("FROM \"{}\"", T::table_name());
5576
5577			let from_replacement = format!("FROM {} AS \"{}\"", subquery_sql, alias);
5578
5579			// Try to replace with alias pattern first, then simple pattern
5580			if select_sql.contains(&from_pattern_with_alias) {
5581				select_sql = select_sql.replace(&from_pattern_with_alias, &from_replacement);
5582			} else if select_sql.contains(&from_pattern_simple) {
5583				select_sql = select_sql.replace(&from_pattern_simple, &from_replacement);
5584			}
5585		}
5586
5587		// Prepend CTE clause if any CTEs are defined
5588		if let Some(cte_sql) = self.ctes.to_sql() {
5589			format!("{} {}", cte_sql, select_sql)
5590		} else {
5591			select_sql
5592		}
5593	}
5594
5595	/// Select specific values from the QuerySet
5596	///
5597	/// Returns only the specified fields instead of all columns.
5598	/// Useful for optimizing queries when you don't need all model fields.
5599	///
5600	/// # Examples
5601	///
5602	/// ```no_run
5603	/// # use reinhardt_db::orm::Model;
5604	/// # use reinhardt_db::orm::{Filter, FilterOperator, FilterValue};
5605	/// # use serde::{Serialize, Deserialize};
5606	/// # #[derive(Clone, Serialize, Deserialize)]
5607	/// # struct User { id: Option<i64> }
5608	/// # #[derive(Clone)]
5609	/// # struct UserFields;
5610	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
5611	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5612	/// # }
5613	/// # impl Model for User {
5614	/// #     type PrimaryKey = i64;
5615	/// #     type Fields = UserFields;
5616	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5617	/// #     fn table_name() -> &'static str { "users" }
5618	/// #     fn new_fields() -> Self::Fields { UserFields }
5619	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5620	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5621	/// # }
5622	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
5623	/// // Select only specific fields
5624	/// let users = User::objects()
5625	///     .values(&["id", "username", "email"])
5626	///     .all()
5627	///     .await?;
5628	/// // Generates: SELECT id, username, email FROM users
5629	///
5630	/// // Combine with filters
5631	/// let active_user_names = User::objects()
5632	///     .filter(Filter::new("is_active", FilterOperator::Eq, FilterValue::Boolean(true)))
5633	///     .values(&["username"])
5634	///     .all()
5635	///     .await?;
5636	/// # Ok(())
5637	/// # }
5638	/// ```
5639	pub fn values(mut self, fields: &[&str]) -> Self {
5640		self.selected_fields = Some(fields.iter().map(|s| s.to_string()).collect());
5641		self
5642	}
5643
5644	/// Select specific values as a list
5645	///
5646	/// Alias for `values()` - returns tuple-like results with specified fields.
5647	/// In Django, this returns tuples instead of dictionaries, but in Rust
5648	/// the behavior is the same as `values()` due to type safety.
5649	///
5650	/// # Examples
5651	///
5652	/// ```no_run
5653	/// # use reinhardt_db::orm::Model;
5654	/// # use serde::{Serialize, Deserialize};
5655	/// # #[derive(Clone, Serialize, Deserialize)]
5656	/// # struct User { id: Option<i64> }
5657	/// # #[derive(Clone)]
5658	/// # struct UserFields;
5659	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
5660	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5661	/// # }
5662	/// # impl Model for User {
5663	/// #     type PrimaryKey = i64;
5664	/// #     type Fields = UserFields;
5665	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5666	/// #     fn table_name() -> &'static str { "users" }
5667	/// #     fn new_fields() -> Self::Fields { UserFields }
5668	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5669	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5670	/// # }
5671	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
5672	/// // Same as values()
5673	/// let user_data = User::objects()
5674	///     .values_list(&["id", "username"])
5675	///     .all()
5676	///     .await?;
5677	/// # Ok(())
5678	/// # }
5679	/// ```
5680	pub fn values_list(self, fields: &[&str]) -> Self {
5681		self.values(fields)
5682	}
5683
5684	/// Order the QuerySet by specified fields
5685	///
5686	/// # Examples
5687	///
5688	/// ```no_run
5689	/// # use reinhardt_db::orm::Model;
5690	/// # use serde::{Serialize, Deserialize};
5691	/// # #[derive(Clone, Serialize, Deserialize)]
5692	/// # struct User { id: Option<i64> }
5693	/// # #[derive(Clone)]
5694	/// # struct UserFields;
5695	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
5696	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5697	/// # }
5698	/// # impl Model for User {
5699	/// #     type PrimaryKey = i64;
5700	/// #     type Fields = UserFields;
5701	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5702	/// #     fn table_name() -> &'static str { "users" }
5703	/// #     fn new_fields() -> Self::Fields { UserFields }
5704	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5705	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5706	/// # }
5707	/// # fn example() {
5708	/// // Ascending order
5709	/// User::objects().order_by(&["name"]);
5710	///
5711	/// // Descending order (prefix with '-')
5712	/// User::objects().order_by(&["-created_at"]);
5713	///
5714	/// // Multiple fields
5715	/// User::objects().order_by(&["department", "-salary"]);
5716	/// # }
5717	/// ```
5718	pub fn order_by(mut self, fields: &[&str]) -> Self {
5719		self.order_by_fields = fields.iter().map(|s| s.to_string()).collect();
5720		self
5721	}
5722
5723	/// Return only distinct results
5724	pub fn distinct(mut self) -> Self {
5725		self.distinct_enabled = true;
5726		self
5727	}
5728
5729	/// Set LIMIT clause
5730	///
5731	/// Limits the number of records returned by the query.
5732	/// Corresponds to Django's QuerySet slicing `[:limit]`.
5733	///
5734	/// # Examples
5735	///
5736	/// ```no_run
5737	/// # use reinhardt_db::orm::Model;
5738	/// # use serde::{Serialize, Deserialize};
5739	/// # #[derive(Clone, Serialize, Deserialize)]
5740	/// # struct User { id: Option<i64> }
5741	/// # #[derive(Clone)]
5742	/// # struct UserFields;
5743	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
5744	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5745	/// # }
5746	/// # impl Model for User {
5747	/// #     type PrimaryKey = i64;
5748	/// #     type Fields = UserFields;
5749	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5750	/// #     fn table_name() -> &'static str { "users" }
5751	/// #     fn new_fields() -> Self::Fields { UserFields }
5752	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5753	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5754	/// # }
5755	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
5756	/// let users = User::objects()
5757	///     .limit(10)
5758	///     .all()
5759	///     .await?;
5760	/// # Ok(())
5761	/// # }
5762	/// ```
5763	pub fn limit(mut self, limit: usize) -> Self {
5764		self.limit = Some(limit);
5765		self
5766	}
5767
5768	/// Set OFFSET clause
5769	///
5770	/// Skips the specified number of records before returning results.
5771	/// Corresponds to Django's QuerySet slicing `[offset:]`.
5772	///
5773	/// # Examples
5774	///
5775	/// ```no_run
5776	/// # use reinhardt_db::orm::Model;
5777	/// # use serde::{Serialize, Deserialize};
5778	/// # #[derive(Clone, Serialize, Deserialize)]
5779	/// # struct User { id: Option<i64> }
5780	/// # #[derive(Clone)]
5781	/// # struct UserFields;
5782	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
5783	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5784	/// # }
5785	/// # impl Model for User {
5786	/// #     type PrimaryKey = i64;
5787	/// #     type Fields = UserFields;
5788	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5789	/// #     fn table_name() -> &'static str { "users" }
5790	/// #     fn new_fields() -> Self::Fields { UserFields }
5791	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5792	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5793	/// # }
5794	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
5795	/// let users = User::objects()
5796	///     .offset(20)
5797	///     .limit(10)
5798	///     .all()
5799	///     .await?;
5800	/// # Ok(())
5801	/// # }
5802	/// ```
5803	pub fn offset(mut self, offset: usize) -> Self {
5804		self.offset = Some(offset);
5805		self
5806	}
5807
5808	/// Paginate results using page number and page size
5809	///
5810	/// Convenience method that calculates offset automatically.
5811	/// Corresponds to Django REST framework's PageNumberPagination.
5812	///
5813	/// # Examples
5814	///
5815	/// ```no_run
5816	/// # use reinhardt_db::orm::Model;
5817	/// # use serde::{Serialize, Deserialize};
5818	/// # #[derive(Clone, Serialize, Deserialize)]
5819	/// # struct User { id: Option<i64> }
5820	/// # #[derive(Clone)]
5821	/// # struct UserFields;
5822	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
5823	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5824	/// # }
5825	/// # impl Model for User {
5826	/// #     type PrimaryKey = i64;
5827	/// #     type Fields = UserFields;
5828	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5829	/// #     fn table_name() -> &'static str { "users" }
5830	/// #     fn new_fields() -> Self::Fields { UserFields }
5831	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5832	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5833	/// # }
5834	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
5835	/// // Page 3, 10 items per page (offset=20, limit=10)
5836	/// let users = User::objects()
5837	///     .paginate(3, 10)
5838	///     .all()
5839	///     .await?;
5840	/// # Ok(())
5841	/// # }
5842	/// ```
5843	pub fn paginate(self, page: usize, page_size: usize) -> Self {
5844		let offset = page.saturating_sub(1) * page_size;
5845		self.offset(offset).limit(page_size)
5846	}
5847
5848	/// Convert QuerySet to a subquery
5849	///
5850	/// Returns the QuerySet as a SQL subquery wrapped in parentheses,
5851	/// suitable for use in IN clauses, EXISTS clauses, or as a derived table.
5852	///
5853	/// # Examples
5854	///
5855	/// ```no_run
5856	/// # use reinhardt_db::orm::Model;
5857	/// # use reinhardt_db::orm::{Filter, FilterOperator, FilterValue};
5858	/// # use serde::{Serialize, Deserialize};
5859	/// # #[derive(Clone, Serialize, Deserialize)]
5860	/// # struct User { id: Option<i64> }
5861	/// # #[derive(Clone)]
5862	/// # struct UserFields;
5863	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
5864	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5865	/// # }
5866	/// # impl Model for User {
5867	/// #     type PrimaryKey = i64;
5868	/// #     type Fields = UserFields;
5869	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5870	/// #     fn table_name() -> &'static str { "users" }
5871	/// #     fn new_fields() -> Self::Fields { UserFields }
5872	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5873	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5874	/// # }
5875	/// # #[derive(Clone, Serialize, Deserialize)]
5876	/// # struct Post { id: Option<i64> }
5877	/// # #[derive(Clone)]
5878	/// # struct PostFields;
5879	/// # impl reinhardt_db::orm::model::FieldSelector for PostFields {
5880	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5881	/// # }
5882	/// # impl Model for Post {
5883	/// #     type PrimaryKey = i64;
5884	/// #     type Fields = PostFields;
5885	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5886	/// #     fn table_name() -> &'static str { "posts" }
5887	/// #     fn new_fields() -> Self::Fields { PostFields }
5888	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5889	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5890	/// # }
5891	/// // Use in IN clause
5892	/// let active_user_ids = User::objects()
5893	///     .filter(Filter::new("is_active", FilterOperator::Eq, FilterValue::Bool(true)))
5894	///     .values(&["id"])
5895	///     .as_subquery();
5896	/// // Generates: (SELECT id FROM users WHERE is_active = $1)
5897	///
5898	/// // Use as derived table
5899	/// let subquery = Post::objects()
5900	///     .filter(Filter::new("published", FilterOperator::Eq, FilterValue::Bool(true)))
5901	///     .as_subquery();
5902	/// // Generates: (SELECT * FROM posts WHERE published = $1)
5903	/// ```
5904	pub fn as_subquery(self) -> String {
5905		format!("({})", self.to_sql())
5906	}
5907
5908	/// Defer loading of specific fields
5909	///
5910	/// Marks specific fields for deferred loading (lazy loading).
5911	/// The specified fields will be excluded from the initial query.
5912	///
5913	/// # Examples
5914	///
5915	/// ```no_run
5916	/// # use reinhardt_db::orm::Model;
5917	/// # use serde::{Serialize, Deserialize};
5918	/// # #[derive(Clone, Serialize, Deserialize)]
5919	/// # struct User { id: Option<i64>, username: String, email: String }
5920	/// # #[derive(Clone)]
5921	/// # struct UserFields;
5922	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
5923	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5924	/// # }
5925	/// # impl Model for User {
5926	/// #     type PrimaryKey = i64;
5927	/// #     type Fields = UserFields;
5928	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5929	/// #     fn table_name() -> &'static str { "users" }
5930	/// #     fn new_fields() -> Self::Fields { UserFields }
5931	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5932	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5933	/// # }
5934	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
5935	/// // Defer large text fields
5936	/// let users = User::objects()
5937	///     .defer(&["bio", "profile_picture"])
5938	///     .all()
5939	///     .await?;
5940	/// // Generates: SELECT id, username, email FROM users (excluding bio, profile_picture)
5941	/// # Ok(())
5942	/// # }
5943	/// ```
5944	pub fn defer(mut self, fields: &[&str]) -> Self {
5945		self.deferred_fields = fields.iter().map(|s| s.to_string()).collect();
5946		self
5947	}
5948
5949	/// Load only specific fields
5950	///
5951	/// Alias for `values()` - specifies which fields to load immediately.
5952	/// In Django, this is used for deferred loading optimization, but in Rust
5953	/// it behaves the same as `values()`.
5954	///
5955	/// # Examples
5956	///
5957	/// ```no_run
5958	/// # use reinhardt_db::orm::Model;
5959	/// # use serde::{Serialize, Deserialize};
5960	/// # #[derive(Clone, Serialize, Deserialize)]
5961	/// # struct User { id: Option<i64>, username: String }
5962	/// # #[derive(Clone)]
5963	/// # struct UserFields;
5964	/// # impl reinhardt_db::orm::model::FieldSelector for UserFields {
5965	/// #     fn with_alias(self, _alias: &str) -> Self { self }
5966	/// # }
5967	/// # impl Model for User {
5968	/// #     type PrimaryKey = i64;
5969	/// #     type Fields = UserFields;
5970	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
5971	/// #     fn table_name() -> &'static str { "users" }
5972	/// #     fn new_fields() -> Self::Fields { UserFields }
5973	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
5974	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
5975	/// # }
5976	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
5977	/// // Load only specific fields
5978	/// let users = User::objects()
5979	///     .only(&["id", "username"])
5980	///     .all()
5981	///     .await?;
5982	/// // Generates: SELECT id, username FROM users
5983	/// # Ok(())
5984	/// # }
5985	/// ```
5986	pub fn only(self, fields: &[&str]) -> Self {
5987		self.values(fields)
5988	}
5989
5990	// ==================== PostgreSQL-specific convenience methods ====================
5991
5992	/// Filter by PostgreSQL full-text search
5993	///
5994	/// This method adds a filter for full-text search using PostgreSQL's `@@` operator.
5995	/// The query is converted using `plainto_tsquery` for simple word matching.
5996	///
5997	/// # Arguments
5998	///
5999	/// * `field` - The tsvector field to search
6000	/// * `query` - The search query string
6001	///
6002	/// # Examples
6003	///
6004	/// ```no_run
6005	/// # use reinhardt_db::orm::Model;
6006	/// # use serde::{Serialize, Deserialize};
6007	/// # #[derive(Clone, Serialize, Deserialize)]
6008	/// # struct Article { id: Option<i64>, title: String }
6009	/// # #[derive(Clone)]
6010	/// # struct ArticleFields;
6011	/// # impl reinhardt_db::orm::model::FieldSelector for ArticleFields {
6012	/// #     fn with_alias(self, _alias: &str) -> Self { self }
6013	/// # }
6014	/// # impl Model for Article {
6015	/// #     type PrimaryKey = i64;
6016	/// #     type Fields = ArticleFields;
6017	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
6018	/// #     fn table_name() -> &'static str { "articles" }
6019	/// #     fn new_fields() -> Self::Fields { ArticleFields }
6020	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
6021	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
6022	/// # }
6023	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
6024	/// // Search articles for "rust programming"
6025	/// let articles = Article::objects()
6026	///     .full_text_search("search_vector", "rust programming")
6027	///     .all()
6028	///     .await?;
6029	/// // Generates: WHERE search_vector @@ plainto_tsquery('english', 'rust programming')
6030	/// # Ok(())
6031	/// # }
6032	/// ```
6033	pub fn full_text_search(self, field: &str, query: &str) -> Self {
6034		self.filter(Filter::new(
6035			field,
6036			FilterOperator::FullTextMatch,
6037			FilterValue::String(query.to_string()),
6038		))
6039	}
6040
6041	/// Filter by PostgreSQL array overlap
6042	///
6043	/// Returns rows where the array field has at least one element in common with the given values.
6044	///
6045	/// # Arguments
6046	///
6047	/// * `field` - The array field name
6048	/// * `values` - Values to check for overlap
6049	///
6050	/// # Examples
6051	///
6052	/// ```no_run
6053	/// # use reinhardt_db::orm::Model;
6054	/// # use serde::{Serialize, Deserialize};
6055	/// # #[derive(Clone, Serialize, Deserialize)]
6056	/// # struct Post { id: Option<i64>, title: String }
6057	/// # #[derive(Clone)]
6058	/// # struct PostFields;
6059	/// # impl reinhardt_db::orm::model::FieldSelector for PostFields {
6060	/// #     fn with_alias(self, _alias: &str) -> Self { self }
6061	/// # }
6062	/// # impl Model for Post {
6063	/// #     type PrimaryKey = i64;
6064	/// #     type Fields = PostFields;
6065	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
6066	/// #     fn table_name() -> &'static str { "posts" }
6067	/// #     fn new_fields() -> Self::Fields { PostFields }
6068	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
6069	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
6070	/// # }
6071	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
6072	/// // Find posts with any of these tags
6073	/// let posts = Post::objects()
6074	///     .filter_array_overlap("tags", &["rust", "programming"])
6075	///     .all()
6076	///     .await?;
6077	/// // Generates: WHERE tags && ARRAY['rust', 'programming']
6078	/// # Ok(())
6079	/// # }
6080	/// ```
6081	pub fn filter_array_overlap(self, field: &str, values: &[&str]) -> Self {
6082		self.filter(Filter::new(
6083			field,
6084			FilterOperator::ArrayOverlap,
6085			FilterValue::Array(values.iter().map(|s| s.to_string()).collect()),
6086		))
6087	}
6088
6089	/// Filter by PostgreSQL array containment
6090	///
6091	/// Returns rows where the array field contains all the given values.
6092	///
6093	/// # Arguments
6094	///
6095	/// * `field` - The array field name
6096	/// * `values` - Values that must all be present in the array
6097	///
6098	/// # Examples
6099	///
6100	/// ```no_run
6101	/// # use reinhardt_db::orm::Model;
6102	/// # use serde::{Serialize, Deserialize};
6103	/// # #[derive(Clone, Serialize, Deserialize)]
6104	/// # struct Post { id: Option<i64>, title: String }
6105	/// # #[derive(Clone)]
6106	/// # struct PostFields;
6107	/// # impl reinhardt_db::orm::model::FieldSelector for PostFields {
6108	/// #     fn with_alias(self, _alias: &str) -> Self { self }
6109	/// # }
6110	/// # impl Model for Post {
6111	/// #     type PrimaryKey = i64;
6112	/// #     type Fields = PostFields;
6113	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
6114	/// #     fn table_name() -> &'static str { "posts" }
6115	/// #     fn new_fields() -> Self::Fields { PostFields }
6116	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
6117	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
6118	/// # }
6119	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
6120	/// // Find posts that have both "rust" and "async" tags
6121	/// let posts = Post::objects()
6122	///     .filter_array_contains("tags", &["rust", "async"])
6123	///     .all()
6124	///     .await?;
6125	/// // Generates: WHERE tags @> ARRAY['rust', 'async']
6126	/// # Ok(())
6127	/// # }
6128	/// ```
6129	pub fn filter_array_contains(self, field: &str, values: &[&str]) -> Self {
6130		self.filter(Filter::new(
6131			field,
6132			FilterOperator::ArrayContains,
6133			FilterValue::Array(values.iter().map(|s| s.to_string()).collect()),
6134		))
6135	}
6136
6137	/// Filter by PostgreSQL JSONB containment
6138	///
6139	/// Returns rows where the JSONB field contains the given JSON object.
6140	///
6141	/// # Arguments
6142	///
6143	/// * `field` - The JSONB field name
6144	/// * `json` - JSON string to check for containment
6145	///
6146	/// # Examples
6147	///
6148	/// ```no_run
6149	/// # use reinhardt_db::orm::Model;
6150	/// # use serde::{Serialize, Deserialize};
6151	/// # #[derive(Clone, Serialize, Deserialize)]
6152	/// # struct Product { id: Option<i64>, name: String }
6153	/// # #[derive(Clone)]
6154	/// # struct ProductFields;
6155	/// # impl reinhardt_db::orm::model::FieldSelector for ProductFields {
6156	/// #     fn with_alias(self, _alias: &str) -> Self { self }
6157	/// # }
6158	/// # impl Model for Product {
6159	/// #     type PrimaryKey = i64;
6160	/// #     type Fields = ProductFields;
6161	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
6162	/// #     fn table_name() -> &'static str { "products" }
6163	/// #     fn new_fields() -> Self::Fields { ProductFields }
6164	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
6165	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
6166	/// # }
6167	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
6168	/// // Find products with specific metadata
6169	/// let products = Product::objects()
6170	///     .filter_jsonb_contains("metadata", r#"{"active": true}"#)
6171	///     .all()
6172	///     .await?;
6173	/// // Generates: WHERE metadata @> '{"active": true}'::jsonb
6174	/// # Ok(())
6175	/// # }
6176	/// ```
6177	pub fn filter_jsonb_contains(self, field: &str, json: &str) -> Self {
6178		self.filter(Filter::new(
6179			field,
6180			FilterOperator::JsonbContains,
6181			FilterValue::String(json.to_string()),
6182		))
6183	}
6184
6185	/// Filter by PostgreSQL JSONB key existence
6186	///
6187	/// Returns rows where the JSONB field contains the given key.
6188	///
6189	/// # Arguments
6190	///
6191	/// * `field` - The JSONB field name
6192	/// * `key` - Key to check for existence
6193	///
6194	/// # Examples
6195	///
6196	/// ```no_run
6197	/// # use reinhardt_db::orm::Model;
6198	/// # use serde::{Serialize, Deserialize};
6199	/// # #[derive(Clone, Serialize, Deserialize)]
6200	/// # struct Product { id: Option<i64>, name: String }
6201	/// # #[derive(Clone)]
6202	/// # struct ProductFields;
6203	/// # impl reinhardt_db::orm::model::FieldSelector for ProductFields {
6204	/// #     fn with_alias(self, _alias: &str) -> Self { self }
6205	/// # }
6206	/// # impl Model for Product {
6207	/// #     type PrimaryKey = i64;
6208	/// #     type Fields = ProductFields;
6209	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
6210	/// #     fn table_name() -> &'static str { "products" }
6211	/// #     fn new_fields() -> Self::Fields { ProductFields }
6212	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
6213	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
6214	/// # }
6215	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
6216	/// // Find products with "sale_price" in metadata
6217	/// let products = Product::objects()
6218	///     .filter_jsonb_key_exists("metadata", "sale_price")
6219	///     .all()
6220	///     .await?;
6221	/// // Generates: WHERE metadata ? 'sale_price'
6222	/// # Ok(())
6223	/// # }
6224	/// ```
6225	pub fn filter_jsonb_key_exists(self, field: &str, key: &str) -> Self {
6226		self.filter(Filter::new(
6227			field,
6228			FilterOperator::JsonbKeyExists,
6229			FilterValue::String(key.to_string()),
6230		))
6231	}
6232
6233	/// Filter by PostgreSQL range containment
6234	///
6235	/// Returns rows where the range field contains the given value.
6236	///
6237	/// # Arguments
6238	///
6239	/// * `field` - The range field name
6240	/// * `value` - Value to check for containment in the range
6241	///
6242	/// # Examples
6243	///
6244	/// ```no_run
6245	/// # use reinhardt_db::orm::Model;
6246	/// # use serde::{Serialize, Deserialize};
6247	/// # #[derive(Clone, Serialize, Deserialize)]
6248	/// # struct Event { id: Option<i64>, name: String }
6249	/// # #[derive(Clone)]
6250	/// # struct EventFields;
6251	/// # impl reinhardt_db::orm::model::FieldSelector for EventFields {
6252	/// #     fn with_alias(self, _alias: &str) -> Self { self }
6253	/// # }
6254	/// # impl Model for Event {
6255	/// #     type PrimaryKey = i64;
6256	/// #     type Fields = EventFields;
6257	/// #     type Objects = reinhardt_db::orm::Manager<Self>;
6258	/// #     fn table_name() -> &'static str { "events" }
6259	/// #     fn new_fields() -> Self::Fields { EventFields }
6260	/// #     fn primary_key(&self) -> Option<Self::PrimaryKey> { self.id }
6261	/// #     fn set_primary_key(&mut self, value: Self::PrimaryKey) { self.id = Some(value); }
6262	/// # }
6263	/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
6264	/// // Find events that include a specific date
6265	/// let events = Event::objects()
6266	///     .filter_range_contains("date_range", "2024-06-15")
6267	///     .all()
6268	///     .await?;
6269	/// // Generates: WHERE date_range @> '2024-06-15'
6270	/// # Ok(())
6271	/// # }
6272	/// ```
6273	pub fn filter_range_contains(self, field: &str, value: &str) -> Self {
6274		self.filter(Filter::new(
6275			field,
6276			FilterOperator::RangeContains,
6277			FilterValue::String(value.to_string()),
6278		))
6279	}
6280}
6281
6282impl<T> Default for QuerySet<T>
6283where
6284	T: super::Model,
6285{
6286	fn default() -> Self {
6287		Self::new()
6288	}
6289}
6290
6291// Convenience conversions for FilterValue
6292impl FilterValue {
6293	/// Create a String variant from any value that can be converted to String
6294	///
6295	/// Accepts any type that implements `ToString`, including:
6296	/// - String, &str
6297	/// - Uuid (via Display)
6298	/// - Numeric types (i64, u64, etc. via Display)
6299	pub fn string(value: impl ToString) -> Self {
6300		Self::String(value.to_string())
6301	}
6302}
6303
6304// ============================================================================
6305// Helper Functions
6306// ============================================================================
6307
6308/// Quote a SQL identifier to prevent injection via field names.
6309/// Uses PostgreSQL double-quote escaping (also valid for SQLite).
6310/// Handles dot-separated qualified names (e.g., "table.column" becomes "table"."column").
6311pub(crate) fn quote_identifier(field: &str) -> String {
6312	if field.contains('\0') {
6313		panic!("SQL identifier must not contain null bytes");
6314	}
6315
6316	fn quote_single(name: &str) -> String {
6317		format!("\"{}\"", name.replace('"', "\"\""))
6318	}
6319
6320	if field.contains('.') {
6321		field
6322			.split('.')
6323			.map(quote_single)
6324			.collect::<Vec<_>>()
6325			.join(".")
6326	} else {
6327		quote_single(field)
6328	}
6329}
6330
6331fn filter_lhs_expr(filter: &Filter) -> Expr {
6332	match &filter.field_source {
6333		FilterField::Column => Expr::col(parse_column_reference(&filter.field)),
6334		FilterField::Expression(sql) if filter.field == *sql => Expr::cust(sql.clone()),
6335		FilterField::Expression(_) => Expr::col(parse_column_reference(&filter.field)),
6336	}
6337}
6338
6339fn filter_lhs_sql(filter: &Filter) -> String {
6340	match &filter.field_source {
6341		FilterField::Column => quote_identifier(&filter.field),
6342		FilterField::Expression(sql) if filter.field == *sql => sql.clone(),
6343		FilterField::Expression(_) => quote_identifier(&filter.field),
6344	}
6345}
6346
6347/// Parse field reference into reinhardt-query column expression
6348///
6349/// Handles both qualified (`table.column`) and unqualified (`column`) references.
6350///
6351/// # Examples
6352///
6353/// - `"id"` → `ColumnRef::Column("id")`
6354/// - `"users.id"` → `ColumnRef::Column("users.id")` (qualified name as-is)
6355///
6356/// Note: For reinhardt-query v1.0.0-rc.29+, we use the full qualified name as a column identifier.
6357/// This works for most databases that support qualified column references.
6358///
6359/// This function also detects raw SQL expressions (containing parentheses, like `COUNT(*)`,
6360/// `AVG(price)`) and returns them wrapped in `Expr::cust()` instead of as column references.
6361fn parse_column_reference(field: &str) -> reinhardt_query::prelude::ColumnRef {
6362	use reinhardt_query::prelude::ColumnRef;
6363
6364	// Detect raw SQL expressions by checking for parentheses
6365	// Examples: COUNT(*), AVG(price), SUM(amount), MAX(value)
6366	if field.contains('(') && field.contains(')') {
6367		// Use column reference with raw expression name
6368		ColumnRef::column(Alias::new(field))
6369	} else if field.contains('.') {
6370		// Qualified column reference (table.column format)
6371		let parts: Vec<&str> = field.split('.').collect();
6372		match parts.as_slice() {
6373			[table, column] => {
6374				// Produces: "table"."column" instead of "table.column"
6375				ColumnRef::table_column(Alias::new(*table), Alias::new(*column))
6376			}
6377			[schema, table, column] => {
6378				// Produces: "schema"."table"."column"
6379				ColumnRef::schema_table_column(
6380					Alias::new(*schema),
6381					Alias::new(*table),
6382					Alias::new(*column),
6383				)
6384			}
6385			_ => {
6386				// Fallback for unexpected formats (4+ parts)
6387				ColumnRef::column(Alias::new(field))
6388			}
6389		}
6390	} else {
6391		// Simple column reference
6392		ColumnRef::column(Alias::new(field))
6393	}
6394}
6395
6396#[derive(Debug, Clone, Copy)]
6397enum LikePattern {
6398	Exact,
6399	Contains,
6400	StartsWith,
6401	EndsWith,
6402}
6403
6404impl LikePattern {
6405	fn apply(self, value: &str) -> String {
6406		let escaped = escape_like_pattern(value);
6407		match self {
6408			Self::Exact => escaped,
6409			Self::Contains => format!("%{}%", escaped),
6410			Self::StartsWith => format!("{}%", escaped),
6411			Self::EndsWith => format!("%{}", escaped),
6412		}
6413	}
6414}
6415
6416fn escape_like_pattern(value: &str) -> String {
6417	let mut escaped = String::with_capacity(value.len());
6418	for ch in value.chars() {
6419		if matches!(ch, '\\' | '%' | '_') {
6420			escaped.push('\\');
6421		}
6422		escaped.push(ch);
6423	}
6424	escaped
6425}
6426
6427fn render_select_statement(
6428	statement: &SelectStatement,
6429	backend: super::connection::DatabaseBackend,
6430) -> String {
6431	match backend {
6432		super::connection::DatabaseBackend::Postgres => statement.to_string(PostgresQueryBuilder),
6433		super::connection::DatabaseBackend::MySql => statement.to_string(MySqlQueryBuilder),
6434		super::connection::DatabaseBackend::Sqlite => statement.to_string(SqliteQueryBuilder),
6435	}
6436}
6437
6438#[cfg(test)]
6439mod tests {
6440	use super::{FilterCondition, MAX_FILTER_CONDITION_DEPTH, render_select_statement};
6441	use crate::orm::connection::DatabaseBackend;
6442	use crate::orm::query::{FieldAssignment, UpdateValue};
6443	use crate::orm::{FilterOperator, FilterValue, Manager, Model, QuerySet, query::Filter};
6444	use rstest::rstest;
6445	use serde::{Deserialize, Serialize};
6446	use std::collections::HashMap;
6447
6448	#[test]
6449	fn render_select_statement_uses_mysql_identifier_quoting() {
6450		// Arrange
6451		let mut statement = reinhardt_query::prelude::Query::select();
6452		statement
6453			.column(reinhardt_query::prelude::Alias::new("id"))
6454			.from(reinhardt_query::prelude::Alias::new("articles"));
6455
6456		// Act
6457		let sql = render_select_statement(&statement, DatabaseBackend::MySql);
6458
6459		// Assert
6460		assert_eq!(sql, "SELECT `id` FROM `articles`");
6461	}
6462
6463	#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
6464	struct TestUser {
6465		id: Option<i64>,
6466		username: String,
6467		email: String,
6468	}
6469
6470	impl TestUser {
6471		// Allow dead_code: test helper constructor for query tests
6472		#[allow(dead_code)]
6473		fn new(username: String, email: String) -> Self {
6474			Self {
6475				id: None,
6476				username,
6477				email,
6478			}
6479		}
6480
6481		const fn field_id() -> crate::orm::expressions::FieldRef<TestUser, i64> {
6482			crate::orm::expressions::FieldRef::new("id")
6483		}
6484
6485		const fn field_username() -> crate::orm::expressions::FieldRef<TestUser, String> {
6486			crate::orm::expressions::FieldRef::new("username")
6487		}
6488
6489		const fn field_email() -> crate::orm::expressions::FieldRef<TestUser, String> {
6490			crate::orm::expressions::FieldRef::new("email")
6491		}
6492
6493		const fn field_created_at() -> crate::orm::expressions::FieldRef<TestUser, String> {
6494			crate::orm::expressions::FieldRef::new("created_at")
6495		}
6496
6497		const fn field_tags() -> crate::orm::expressions::FieldRef<TestUser, Vec<String>> {
6498			crate::orm::expressions::FieldRef::new("tags")
6499		}
6500
6501		const fn field_metadata() -> crate::orm::expressions::FieldRef<TestUser, String> {
6502			crate::orm::expressions::FieldRef::new("metadata")
6503		}
6504
6505		const fn field_active_period() -> crate::orm::expressions::FieldRef<TestUser, String> {
6506			crate::orm::expressions::FieldRef::new("active_period")
6507		}
6508	}
6509
6510	#[derive(Debug, Clone)]
6511	struct TestUserFields;
6512
6513	impl crate::orm::model::FieldSelector for TestUserFields {
6514		fn with_alias(self, _alias: &str) -> Self {
6515			self
6516		}
6517	}
6518
6519	impl Model for TestUser {
6520		type PrimaryKey = i64;
6521		type Fields = TestUserFields;
6522		type Objects = Manager<Self>;
6523
6524		fn table_name() -> &'static str {
6525			"test_users"
6526		}
6527
6528		fn primary_key(&self) -> Option<Self::PrimaryKey> {
6529			self.id
6530		}
6531
6532		fn set_primary_key(&mut self, value: Self::PrimaryKey) {
6533			self.id = Some(value);
6534		}
6535
6536		fn primary_key_field() -> &'static str {
6537			"id"
6538		}
6539
6540		fn new_fields() -> Self::Fields {
6541			TestUserFields
6542		}
6543	}
6544
6545	#[test]
6546	fn test_field_assignment_from_generated_field_ref_tuple() {
6547		let timestamp = chrono::DateTime::parse_from_rfc3339("2026-06-19T00:00:00Z")
6548			.expect("valid timestamp")
6549			.with_timezone(&chrono::Utc);
6550
6551		let assignment: FieldAssignment = (TestUser::field_created_at(), timestamp).into();
6552
6553		assert_eq!(assignment.field(), "created_at");
6554		assert!(matches!(assignment.value(), UpdateValue::Timestamp(_)));
6555	}
6556
6557	#[test]
6558	fn test_field_assignment_from_field_ref_assign_helper() {
6559		let assignment = TestUser::field_username().assign("alice");
6560
6561		assert_eq!(assignment.field(), "username");
6562		assert!(matches!(
6563			assignment.value(),
6564			UpdateValue::String(value) if value == "alice"
6565		));
6566	}
6567
6568	#[test]
6569	fn test_update_fields_sql_preserves_queryset_predicates() {
6570		let timestamp = chrono::DateTime::parse_from_rfc3339("2026-06-19T00:00:00Z")
6571			.expect("valid timestamp")
6572			.with_timezone(&chrono::Utc);
6573		let queryset = QuerySet::<TestUser>::new()
6574			.filter(TestUser::field_id().eq(7))
6575			.filter(TestUser::field_email().is_null());
6576
6577		let (sql, params) = queryset
6578			.update_fields_sql([(TestUser::field_created_at(), timestamp)])
6579			.expect("update fields sql");
6580
6581		assert_eq!(
6582			sql,
6583			"UPDATE \"test_users\" SET \"created_at\" = $1 WHERE (\"id\" = $2 AND \"email\" IS NULL)"
6584		);
6585		assert_eq!(params.len(), 2);
6586		assert_eq!(params[0], "2026-06-19T00:00:00+00:00");
6587		assert_eq!(params[1], "7");
6588	}
6589
6590	#[test]
6591	fn test_update_fields_sql_rejects_empty_assignments() {
6592		let queryset = QuerySet::<TestUser>::new().filter(TestUser::field_id().eq(7));
6593
6594		let error = queryset
6595			.update_fields_sql(std::iter::empty::<FieldAssignment>())
6596			.expect_err("empty assignments should fail");
6597
6598		assert!(matches!(
6599			error,
6600			reinhardt_core::exception::Error::Validation(message)
6601				if message.contains("field assignment")
6602		));
6603	}
6604
6605	#[test]
6606	fn test_update_fields_sql_rejects_missing_predicate() {
6607		let queryset = QuerySet::<TestUser>::new();
6608
6609		let error = queryset
6610			.update_fields_sql([("username", "alice")])
6611			.expect_err("missing predicate should fail");
6612
6613		assert!(matches!(
6614			error,
6615			reinhardt_core::exception::Error::Validation(message)
6616				if message.contains("filter predicate")
6617		));
6618	}
6619
6620	#[tokio::test]
6621	async fn test_queryset_create_with_manager() {
6622		// Test QuerySet::create() with explicit manager
6623		let manager = std::sync::Arc::new(TestUser::objects());
6624		let queryset = QuerySet::with_manager(manager);
6625
6626		let user = TestUser {
6627			id: None,
6628			username: "testuser".to_string(),
6629			email: "test@example.com".to_string(),
6630		};
6631
6632		// Note: This will fail without a real database connection
6633		// In actual integration tests, we would set up a test database
6634		let result = queryset.create(user).await;
6635
6636		// In unit tests, we expect this to fail due to no database
6637		// In integration tests with TestContainers, this would succeed
6638		assert!(result.is_err() || result.is_ok());
6639	}
6640
6641	#[tokio::test]
6642	async fn test_queryset_create_without_manager() {
6643		// Test QuerySet::create() fallback without manager
6644		let queryset = QuerySet::<TestUser>::new();
6645
6646		let user = TestUser {
6647			id: None,
6648			username: "fallback_user".to_string(),
6649			email: "fallback@example.com".to_string(),
6650		};
6651
6652		// Note: This will fail without a real database connection
6653		let result = queryset.create(user).await;
6654
6655		// In unit tests, we expect this to fail due to no database
6656		assert!(result.is_err() || result.is_ok());
6657	}
6658
6659	#[test]
6660	fn test_queryset_with_manager() {
6661		let manager = std::sync::Arc::new(TestUser::objects());
6662		let queryset = QuerySet::with_manager(manager.clone());
6663
6664		// Verify manager is set
6665		assert!(queryset.manager.is_some());
6666	}
6667
6668	#[test]
6669	fn test_queryset_filter_preserves_manager() {
6670		let manager = std::sync::Arc::new(TestUser::objects());
6671		let queryset = QuerySet::with_manager(manager);
6672
6673		let filter = Filter::new(
6674			"username".to_string(),
6675			FilterOperator::Eq,
6676			FilterValue::String("alice".to_string()),
6677		);
6678
6679		let filtered = queryset.filter(filter);
6680
6681		// Verify manager is preserved after filter
6682		assert!(filtered.manager.is_some());
6683	}
6684
6685	#[test]
6686	fn test_queryset_select_related_preserves_manager() {
6687		let manager = std::sync::Arc::new(TestUser::objects());
6688		let queryset = QuerySet::with_manager(manager);
6689
6690		let selected = queryset.select_related(&["profile", "posts"]);
6691
6692		// Verify manager is preserved after select_related
6693		assert!(selected.manager.is_some());
6694		assert_eq!(selected.select_related_fields, vec!["profile", "posts"]);
6695	}
6696
6697	#[test]
6698	fn test_queryset_prefetch_related_preserves_manager() {
6699		let manager = std::sync::Arc::new(TestUser::objects());
6700		let queryset = QuerySet::with_manager(manager);
6701
6702		let prefetched = queryset.prefetch_related(&["comments", "likes"]);
6703
6704		// Verify manager is preserved after prefetch_related
6705		assert!(prefetched.manager.is_some());
6706		assert_eq!(
6707			prefetched.prefetch_related_fields,
6708			vec!["comments", "likes"]
6709		);
6710	}
6711
6712	#[tokio::test]
6713	async fn test_get_composite_validation_error() {
6714		use std::collections::HashMap;
6715
6716		let queryset = QuerySet::<TestUser>::new();
6717		let pk_values = HashMap::new(); // Empty HashMap - should fail validation
6718
6719		let result = queryset.get_composite(&pk_values).await;
6720
6721		// Expect error because TestUser doesn't have a composite primary key
6722		assert!(result.is_err());
6723		let err = result.unwrap_err();
6724		assert!(err.to_string().contains("composite primary key"));
6725	}
6726
6727	// SQL Generation Tests
6728
6729	#[test]
6730	fn test_update_sql_single_field_single_filter() {
6731		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
6732			"id".to_string(),
6733			FilterOperator::Eq,
6734			FilterValue::Integer(1),
6735		));
6736
6737		let mut updates = HashMap::new();
6738		updates.insert(
6739			"username".to_string(),
6740			UpdateValue::String("alice".to_string()),
6741		);
6742		let (sql, params) = queryset.update_sql(&updates);
6743
6744		assert_eq!(
6745			sql,
6746			"UPDATE \"test_users\" SET \"username\" = $1 WHERE \"id\" = $2"
6747		);
6748		assert_eq!(params, vec!["alice", "1"]);
6749	}
6750
6751	#[test]
6752	fn test_update_sql_multiple_fields_multiple_filters() {
6753		let queryset = QuerySet::<TestUser>::new()
6754			.filter(Filter::new(
6755				"id".to_string(),
6756				FilterOperator::Gt,
6757				FilterValue::Integer(10),
6758			))
6759			.filter(Filter::new(
6760				"email".to_string(),
6761				FilterOperator::Contains,
6762				FilterValue::String("example.com".to_string()),
6763			));
6764
6765		let mut updates = HashMap::new();
6766		updates.insert(
6767			"username".to_string(),
6768			UpdateValue::String("bob".to_string()),
6769		);
6770		updates.insert(
6771			"email".to_string(),
6772			UpdateValue::String("bob@test.com".to_string()),
6773		);
6774		let (sql, params) = queryset.update_sql(&updates);
6775
6776		// HashMap iteration order is not guaranteed, so we check both possible orderings
6777		let valid_sql_1 = "UPDATE \"test_users\" SET \"username\" = $1, \"email\" = $2 WHERE (\"id\" > $3 AND \"email\" LIKE $4 ESCAPE '\\')";
6778		let valid_sql_2 = "UPDATE \"test_users\" SET \"email\" = $1, \"username\" = $2 WHERE (\"id\" > $3 AND \"email\" LIKE $4 ESCAPE '\\')";
6779		assert!(
6780			sql == valid_sql_1 || sql == valid_sql_2,
6781			"Generated SQL '{}' does not match either expected pattern",
6782			sql
6783		);
6784
6785		// Check that all expected values are present (order may vary for SET clause)
6786		assert!(
6787			params.contains(&"bob".to_string()) || params.contains(&"bob@test.com".to_string())
6788		);
6789		assert_eq!(params[2], "10");
6790		assert_eq!(params[3], "%example.com%");
6791	}
6792
6793	#[test]
6794	fn test_delete_sql_single_filter() {
6795		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
6796			"id".to_string(),
6797			FilterOperator::Eq,
6798			FilterValue::Integer(1),
6799		));
6800
6801		let (sql, params) = queryset.delete_sql();
6802
6803		assert_eq!(sql, "DELETE FROM \"test_users\" WHERE \"id\" = $1");
6804		assert_eq!(params, vec!["1"]);
6805	}
6806
6807	#[test]
6808	fn test_delete_sql_multiple_filters() {
6809		let queryset = QuerySet::<TestUser>::new()
6810			.filter(Filter::new(
6811				"username".to_string(),
6812				FilterOperator::Eq,
6813				FilterValue::String("alice".to_string()),
6814			))
6815			.filter(Filter::new(
6816				"email".to_string(),
6817				FilterOperator::StartsWith,
6818				FilterValue::String("alice@".to_string()),
6819			));
6820
6821		let (sql, params) = queryset.delete_sql();
6822
6823		assert_eq!(
6824			sql,
6825			"DELETE FROM \"test_users\" WHERE (\"username\" = $1 AND \"email\" LIKE $2 ESCAPE '\\')"
6826		);
6827		assert_eq!(params, vec!["alice", "alice@%"]);
6828	}
6829
6830	#[test]
6831	#[should_panic(
6832		expected = "DELETE without WHERE clause is not allowed. Use .filter() to specify which rows to delete."
6833	)]
6834	fn test_delete_sql_without_filters_panics() {
6835		let queryset = QuerySet::<TestUser>::new();
6836		let _ = queryset.delete_sql();
6837	}
6838
6839	#[test]
6840	#[should_panic(
6841		expected = "DELETE without WHERE clause is not allowed. Use .filter() to specify which rows to delete."
6842	)]
6843	fn test_delete_sql_with_empty_composite_filter_panics() {
6844		let queryset = QuerySet::<TestUser>::new().filter(FilterCondition::and(Vec::new()));
6845		let _ = queryset.delete_sql();
6846	}
6847
6848	#[test]
6849	fn test_filter_operators() {
6850		let queryset = QuerySet::<TestUser>::new()
6851			.filter(Filter::new(
6852				"id".to_string(),
6853				FilterOperator::Gte,
6854				FilterValue::Integer(5),
6855			))
6856			.filter(Filter::new(
6857				"username".to_string(),
6858				FilterOperator::Ne,
6859				FilterValue::String("admin".to_string()),
6860			));
6861
6862		let (sql, params) = queryset.delete_sql();
6863
6864		assert_eq!(
6865			sql,
6866			"DELETE FROM \"test_users\" WHERE (\"id\" >= $1 AND \"username\" <> $2)"
6867		);
6868		assert_eq!(params, vec!["5", "admin"]);
6869	}
6870
6871	#[test]
6872	fn test_null_value_filter() {
6873		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
6874			"email".to_string(),
6875			FilterOperator::Eq,
6876			FilterValue::Null,
6877		));
6878
6879		let (sql, params) = queryset.delete_sql();
6880
6881		assert_eq!(sql, "DELETE FROM \"test_users\" WHERE \"email\" IS NULL");
6882		assert_eq!(params, Vec::<String>::new());
6883	}
6884
6885	#[test]
6886	fn test_not_null_value_filter() {
6887		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
6888			"email".to_string(),
6889			FilterOperator::Ne,
6890			FilterValue::Null,
6891		));
6892
6893		let (sql, params) = queryset.delete_sql();
6894
6895		assert_eq!(
6896			sql,
6897			"DELETE FROM \"test_users\" WHERE \"email\" IS NOT NULL"
6898		);
6899		assert_eq!(params, Vec::<String>::new());
6900	}
6901
6902	// Query Optimization Tests
6903
6904	#[test]
6905	fn test_select_related_query_generation() {
6906		// Test that select_related_query() generates SelectStatement correctly
6907		let queryset = QuerySet::<TestUser>::new().select_related(&["profile", "department"]);
6908
6909		let stmt = queryset.select_related_query();
6910
6911		// Convert to SQL to verify structure
6912		use reinhardt_query::prelude::{PostgresQueryBuilder, QueryStatementBuilder};
6913		let sql = stmt.build(PostgresQueryBuilder).0;
6914
6915		assert!(sql.contains("SELECT"));
6916		assert!(sql.contains("test_users"));
6917		assert!(sql.contains("LEFT JOIN"));
6918	}
6919
6920	#[test]
6921	fn test_prefetch_related_queries_generation() {
6922		// Test that prefetch_related_queries() generates correct queries
6923		let queryset = QuerySet::<TestUser>::new().prefetch_related(&["posts", "comments"]);
6924		let pk_values = vec![1, 2, 3];
6925
6926		let queries = queryset.prefetch_related_queries(&pk_values);
6927
6928		// Should generate 2 queries (one for each prefetch field)
6929		assert_eq!(queries.len(), 2);
6930
6931		// Each query should be a (field_name, SelectStatement) tuple
6932		assert_eq!(queries[0].0, "posts");
6933		assert_eq!(queries[1].0, "comments");
6934	}
6935
6936	#[test]
6937	fn test_prefetch_related_queries_empty_pk_values() {
6938		let queryset = QuerySet::<TestUser>::new().prefetch_related(&["posts", "comments"]);
6939		let pk_values = vec![];
6940
6941		let queries = queryset.prefetch_related_queries(&pk_values);
6942
6943		// Should return empty vector when no PK values provided
6944		assert_eq!(queries.len(), 0);
6945	}
6946
6947	#[test]
6948	fn test_select_related_and_prefetch_together() {
6949		// Test that both can be used together
6950		let queryset = QuerySet::<TestUser>::new()
6951			.select_related(&["profile"])
6952			.prefetch_related(&["posts", "comments"]);
6953
6954		// Check select_related generates query
6955		let select_stmt = queryset.select_related_query();
6956		use reinhardt_query::prelude::{PostgresQueryBuilder, QueryStatementBuilder};
6957		let select_sql = select_stmt.build(PostgresQueryBuilder).0;
6958		assert!(select_sql.contains("LEFT JOIN"));
6959
6960		// Check prefetch_related generates queries
6961		let pk_values = vec![1, 2, 3];
6962		let prefetch_queries = queryset.prefetch_related_queries(&pk_values);
6963		assert_eq!(prefetch_queries.len(), 2);
6964	}
6965
6966	// SmallVec Optimization Tests
6967
6968	#[test]
6969	fn test_smallvec_stack_allocation_within_capacity() {
6970		// Test with exactly 10 filters (at capacity)
6971		let mut queryset = QuerySet::<TestUser>::new();
6972
6973		for i in 0..10 {
6974			queryset = queryset.filter(Filter::new(
6975				format!("field{}", i),
6976				FilterOperator::Eq,
6977				FilterValue::Integer(i as i64),
6978			));
6979		}
6980
6981		// Verify all filters are stored
6982		assert_eq!(queryset.filters.len(), 10);
6983
6984		// Generate SQL to ensure filters work correctly
6985		let (sql, params) = queryset.delete_sql();
6986		assert!(sql.contains("WHERE"));
6987		assert_eq!(params.len(), 10);
6988	}
6989
6990	#[test]
6991	fn test_smallvec_heap_fallback_over_capacity() {
6992		// Test with 15 filters (5 over capacity, should trigger heap allocation)
6993		let mut queryset = QuerySet::<TestUser>::new();
6994
6995		for i in 0..15 {
6996			queryset = queryset.filter(Filter::new(
6997				format!("field{}", i),
6998				FilterOperator::Eq,
6999				FilterValue::Integer(i as i64),
7000			));
7001		}
7002
7003		// Verify all filters are stored (SmallVec automatically spills to heap)
7004		assert_eq!(queryset.filters.len(), 15);
7005
7006		// Generate SQL to ensure filters work correctly even after heap fallback
7007		let (sql, params) = queryset.delete_sql();
7008		assert!(sql.contains("WHERE"));
7009		assert_eq!(params.len(), 15);
7010	}
7011
7012	#[test]
7013	fn test_smallvec_typical_use_case_1_5_filters() {
7014		// Test typical use case: 1-5 filters (well within stack capacity)
7015		let queryset = QuerySet::<TestUser>::new()
7016			.filter(Filter::new(
7017				"username".to_string(),
7018				FilterOperator::StartsWith,
7019				FilterValue::String("admin".to_string()),
7020			))
7021			.filter(Filter::new(
7022				"email".to_string(),
7023				FilterOperator::Contains,
7024				FilterValue::String("example.com".to_string()),
7025			))
7026			.filter(Filter::new(
7027				"id".to_string(),
7028				FilterOperator::Gt,
7029				FilterValue::Integer(100),
7030			));
7031
7032		// Verify filters stored correctly
7033		assert_eq!(queryset.filters.len(), 3);
7034
7035		// Generate SQL
7036		let (sql, params) = queryset.delete_sql();
7037		assert!(sql.contains("WHERE"));
7038		assert!(sql.contains("\"username\" LIKE"));
7039		assert!(sql.contains("\"email\" LIKE"));
7040		assert!(sql.contains("\"id\" >"));
7041		assert_eq!(params.len(), 3);
7042	}
7043
7044	#[test]
7045	fn test_smallvec_empty_initialization() {
7046		// Test that empty SmallVec is initialized correctly
7047		let queryset = QuerySet::<TestUser>::new();
7048
7049		assert_eq!(queryset.filters.len(), 0);
7050		assert!(queryset.filters.is_empty());
7051
7052		// Generate SQL with no filters should not include WHERE clause
7053		let (where_clause, params) = queryset.build_where_clause();
7054		assert!(where_clause.is_empty());
7055		assert!(params.is_empty());
7056	}
7057
7058	#[test]
7059	fn test_smallvec_single_filter() {
7060		// Test single filter (minimal usage)
7061		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7062			"id".to_string(),
7063			FilterOperator::Eq,
7064			FilterValue::Integer(1),
7065		));
7066
7067		assert_eq!(queryset.filters.len(), 1);
7068
7069		let (sql, params) = queryset.delete_sql();
7070		assert_eq!(sql, "DELETE FROM \"test_users\" WHERE \"id\" = $1");
7071		assert_eq!(params, vec!["1"]);
7072	}
7073
7074	#[rstest]
7075	#[case("username", r#""username""#)]
7076	#[case("user_id", r#""user_id""#)]
7077	#[case(r#"a"b"#, r#""a""b""#)]
7078	#[case("field; DROP TABLE users", r#""field; DROP TABLE users""#)]
7079	#[case("", r#""""#)]
7080	#[case("authors.id", r#""authors"."id""#)]
7081	#[case("schema.table.column", r#""schema"."table"."column""#)]
7082	fn test_quote_identifier(#[case] input: &str, #[case] expected: &str) {
7083		// Arrange
7084		// input and expected provided by rstest cases
7085
7086		// Act
7087		let result = super::quote_identifier(input);
7088
7089		// Assert
7090		assert_eq!(result, expected);
7091	}
7092
7093	#[rstest]
7094	fn test_outerref_filter_uses_safe_quoting() {
7095		// Arrange
7096		use crate::orm::expressions::OuterRef;
7097		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7098			"author_id".to_string(),
7099			FilterOperator::Eq,
7100			FilterValue::OuterRef(OuterRef::new("id")),
7101		));
7102
7103		// Act
7104		let sql = queryset.to_sql();
7105
7106		// Assert
7107		assert_eq!(
7108			sql,
7109			r#"SELECT * FROM "test_users" WHERE "author_id" = "id""#
7110		);
7111	}
7112
7113	#[rstest]
7114	fn test_array_contains_filter_quotes_field() {
7115		// Arrange
7116		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7117			"tags".to_string(),
7118			FilterOperator::ArrayContains,
7119			FilterValue::Array(vec!["rust".to_string(), "web".to_string()]),
7120		));
7121
7122		// Act
7123		let sql = queryset.to_sql();
7124
7125		// Assert
7126		assert_eq!(
7127			sql,
7128			r#"SELECT * FROM "test_users" WHERE "tags" @> ARRAY['rust', 'web']"#
7129		);
7130	}
7131
7132	#[rstest]
7133	fn test_outerref_dot_separated_renders_qualified_column() {
7134		// Arrange
7135		use crate::orm::expressions::OuterRef;
7136		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7137			"author_id".to_string(),
7138			FilterOperator::Eq,
7139			FilterValue::OuterRef(OuterRef::new("authors.id")),
7140		));
7141
7142		// Act
7143		let sql = queryset.to_sql();
7144
7145		// Assert
7146		assert_eq!(
7147			sql,
7148			r#"SELECT * FROM "test_users" WHERE "author_id" = "authors"."id""#
7149		);
7150	}
7151
7152	#[rstest]
7153	fn test_injection_attempt_in_field_name_is_quoted() {
7154		// Arrange
7155		// Attempt SQL injection via field name with double quote
7156		let malicious_field = r#"id" OR 1=1 --"#.to_string();
7157
7158		// Act
7159		let quoted = super::quote_identifier(&malicious_field);
7160
7161		// Assert
7162		// The double quote inside is escaped, preventing injection
7163		assert_eq!(quoted, r#""id"" OR 1=1 --""#);
7164		// Verify the quote is not broken out of
7165		assert!(quoted.starts_with('"'));
7166		assert!(quoted.ends_with('"'));
7167	}
7168
7169	#[rstest]
7170	#[should_panic(expected = "SQL identifier must not contain null bytes")]
7171	fn test_quote_identifier_rejects_null_bytes() {
7172		// Arrange
7173		let field_with_null = "field\0name";
7174
7175		// Act
7176		super::quote_identifier(field_with_null);
7177
7178		// Assert - should panic before reaching here
7179	}
7180
7181	#[rstest]
7182	#[case(FilterOperator::Ne, "<>")]
7183	#[case(FilterOperator::Gt, ">")]
7184	#[case(FilterOperator::Gte, ">=")]
7185	#[case(FilterOperator::Lt, "<")]
7186	#[case(FilterOperator::Lte, "<=")]
7187	fn test_outerref_comparison_operators(#[case] op: FilterOperator, #[case] sql_op: &str) {
7188		// Arrange
7189		use crate::orm::expressions::OuterRef;
7190		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7191			"author_id".to_string(),
7192			op,
7193			FilterValue::OuterRef(OuterRef::new("id")),
7194		));
7195
7196		// Act
7197		let sql = queryset.to_sql();
7198
7199		// Assert
7200		let expected = format!(
7201			r#"SELECT * FROM "test_users" WHERE "author_id" {} "id""#,
7202			sql_op
7203		);
7204		assert_eq!(sql, expected);
7205	}
7206
7207	#[rstest]
7208	fn test_array_contained_by_filter_quotes_field() {
7209		// Arrange
7210		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7211			"tags".to_string(),
7212			FilterOperator::ArrayContainedBy,
7213			FilterValue::Array(vec!["rust".to_string()]),
7214		));
7215
7216		// Act
7217		let sql = queryset.to_sql();
7218
7219		// Assert
7220		assert_eq!(
7221			sql,
7222			r#"SELECT * FROM "test_users" WHERE "tags" <@ ARRAY['rust']"#
7223		);
7224	}
7225
7226	#[rstest]
7227	fn test_array_overlap_filter_quotes_field() {
7228		// Arrange
7229		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7230			"tags".to_string(),
7231			FilterOperator::ArrayOverlap,
7232			FilterValue::Array(vec!["rust".to_string()]),
7233		));
7234
7235		// Act
7236		let sql = queryset.to_sql();
7237
7238		// Assert
7239		assert_eq!(
7240			sql,
7241			r#"SELECT * FROM "test_users" WHERE "tags" && ARRAY['rust']"#
7242		);
7243	}
7244
7245	#[rstest]
7246	fn test_full_text_match_filter_quotes_field() {
7247		// Arrange
7248		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7249			"content".to_string(),
7250			FilterOperator::FullTextMatch,
7251			FilterValue::String("search term".to_string()),
7252		));
7253
7254		// Act
7255		let sql = queryset.to_sql();
7256
7257		// Assert
7258		assert_eq!(
7259			sql,
7260			r#"SELECT * FROM "test_users" WHERE "content" @@ plainto_tsquery('english', 'search term')"#
7261		);
7262	}
7263
7264	#[rstest]
7265	fn test_jsonb_contains_filter_quotes_field() {
7266		// Arrange
7267		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7268			"metadata".to_string(),
7269			FilterOperator::JsonbContains,
7270			FilterValue::String(r#"{"key": "value"}"#.to_string()),
7271		));
7272
7273		// Act
7274		let sql = queryset.to_sql();
7275
7276		// Assert
7277		assert_eq!(
7278			sql,
7279			r#"SELECT * FROM "test_users" WHERE "metadata" @> '{"key": "value"}'::jsonb"#
7280		);
7281	}
7282
7283	#[rstest]
7284	fn test_jsonb_contained_by_filter_quotes_field() {
7285		// Arrange
7286		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7287			"metadata".to_string(),
7288			FilterOperator::JsonbContainedBy,
7289			FilterValue::String(r#"{"key": "value"}"#.to_string()),
7290		));
7291
7292		// Act
7293		let sql = queryset.to_sql();
7294
7295		// Assert
7296		assert_eq!(
7297			sql,
7298			r#"SELECT * FROM "test_users" WHERE "metadata" <@ '{"key": "value"}'::jsonb"#
7299		);
7300	}
7301
7302	#[rstest]
7303	fn test_jsonb_key_exists_filter_quotes_field() {
7304		// Arrange
7305		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7306			"metadata".to_string(),
7307			FilterOperator::JsonbKeyExists,
7308			FilterValue::String("key".to_string()),
7309		));
7310
7311		// Act
7312		let sql = queryset.to_sql();
7313
7314		// Assert
7315		assert_eq!(
7316			sql,
7317			r#"SELECT * FROM "test_users" WHERE "metadata" ? 'key'"#
7318		);
7319	}
7320
7321	#[rstest]
7322	fn test_jsonb_any_key_exists_filter_quotes_field() {
7323		// Arrange
7324		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7325			"metadata".to_string(),
7326			FilterOperator::JsonbAnyKeyExists,
7327			FilterValue::Array(vec!["key1".to_string(), "key2".to_string()]),
7328		));
7329
7330		// Act
7331		let sql = queryset.to_sql();
7332
7333		// Assert
7334		assert_eq!(
7335			sql,
7336			r#"SELECT * FROM "test_users" WHERE "metadata" ?| array['key1', 'key2']"#
7337		);
7338	}
7339
7340	#[rstest]
7341	fn test_jsonb_all_keys_exist_filter_quotes_field() {
7342		// Arrange
7343		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7344			"metadata".to_string(),
7345			FilterOperator::JsonbAllKeysExist,
7346			FilterValue::Array(vec!["key1".to_string(), "key2".to_string()]),
7347		));
7348
7349		// Act
7350		let sql = queryset.to_sql();
7351
7352		// Assert
7353		assert_eq!(
7354			sql,
7355			r#"SELECT * FROM "test_users" WHERE "metadata" ?& array['key1', 'key2']"#
7356		);
7357	}
7358
7359	#[rstest]
7360	fn test_jsonb_path_exists_filter_quotes_field() {
7361		// Arrange
7362		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7363			"metadata".to_string(),
7364			FilterOperator::JsonbPathExists,
7365			FilterValue::String("$.key".to_string()),
7366		));
7367
7368		// Act
7369		let sql = queryset.to_sql();
7370
7371		// Assert
7372		assert_eq!(
7373			sql,
7374			r#"SELECT * FROM "test_users" WHERE "metadata" @'$.key' "#
7375		);
7376	}
7377
7378	#[rstest]
7379	#[case(
7380		Filter::new("username", FilterOperator::IExact, FilterValue::String("Alice".to_string())),
7381		r#"SELECT * FROM "test_users" WHERE "username" ILIKE 'Alice' ESCAPE '\'"#
7382	)]
7383	#[case(
7384		Filter::new("email", FilterOperator::IContains, FilterValue::String("example.com".to_string())),
7385		r#"SELECT * FROM "test_users" WHERE "email" ILIKE '%example.com%' ESCAPE '\'"#
7386	)]
7387	#[case(
7388		Filter::new("username", FilterOperator::IStartsWith, FilterValue::String("ali".to_string())),
7389		r#"SELECT * FROM "test_users" WHERE "username" ILIKE 'ali%' ESCAPE '\'"#
7390	)]
7391	#[case(
7392		Filter::new("username", FilterOperator::IEndsWith, FilterValue::String("ice".to_string())),
7393		r#"SELECT * FROM "test_users" WHERE "username" ILIKE '%ice' ESCAPE '\'"#
7394	)]
7395	#[case(
7396		Filter::new("username", FilterOperator::Regex, FilterValue::String("^a".to_string())),
7397		r#"SELECT * FROM "test_users" WHERE "username" ~ '^a'"#
7398	)]
7399	#[case(
7400		Filter::new("username", FilterOperator::IRegex, FilterValue::String("^a".to_string())),
7401		r#"SELECT * FROM "test_users" WHERE "username" ~* '^a'"#
7402	)]
7403	fn test_django_style_string_lookup_filters(#[case] filter: Filter, #[case] expected: &str) {
7404		// Arrange
7405		let queryset = QuerySet::<TestUser>::new().filter(filter);
7406
7407		// Act
7408		let sql = queryset.to_sql();
7409
7410		// Assert
7411		assert_eq!(sql, expected);
7412	}
7413
7414	#[rstest]
7415	fn test_filter_or_chain_generates_expected_sql() {
7416		// Arrange
7417		let condition = TestUser::field_username()
7418			.exact("alice")
7419			.or(TestUser::field_email().icontains("example.com"));
7420		let queryset = QuerySet::<TestUser>::new().filter(condition);
7421
7422		// Act
7423		let sql = queryset.to_sql();
7424
7425		// Assert
7426		assert_eq!(
7427			sql,
7428			r#"SELECT * FROM "test_users" WHERE ("username" = 'alice' OR "email" ILIKE '%example.com%' ESCAPE '\')"#
7429		);
7430	}
7431
7432	#[rstest]
7433	fn test_filter_and_chain_generates_expected_sql() {
7434		// Arrange
7435		let condition = TestUser::field_username()
7436			.exact("alice")
7437			.and(TestUser::field_id().gte(10));
7438		let queryset = QuerySet::<TestUser>::new().filter(condition);
7439
7440		// Act
7441		let sql = queryset.to_sql();
7442
7443		// Assert
7444		assert_eq!(
7445			sql,
7446			r#"SELECT * FROM "test_users" WHERE ("username" = 'alice' AND "id" >= 10)"#
7447		);
7448	}
7449
7450	#[rstest]
7451	fn test_filter_not_chain_generates_expected_sql() {
7452		// Arrange
7453		let condition = TestUser::field_username().exact("alice").not();
7454		let queryset = QuerySet::<TestUser>::new().filter(condition);
7455
7456		// Act
7457		let sql = queryset.to_sql();
7458
7459		// Assert
7460		assert_eq!(
7461			sql,
7462			r#"SELECT * FROM "test_users" WHERE NOT "username" = 'alice'"#
7463		);
7464	}
7465
7466	#[rstest]
7467	fn test_composite_only_filter_is_recognized_by_delete_sql() {
7468		// Arrange
7469		let queryset = QuerySet::<TestUser>::new().filter(
7470			TestUser::field_username()
7471				.exact("alice")
7472				.or(TestUser::field_email().icontains("example.com")),
7473		);
7474
7475		// Act
7476		let (sql, params) = queryset.delete_sql();
7477
7478		// Assert
7479		assert_eq!(
7480			sql,
7481			r#"DELETE FROM "test_users" WHERE ("username" = $1 OR "email" ILIKE $2 ESCAPE '\')"#
7482		);
7483		assert_eq!(params, vec!["alice", "%example.com%"]);
7484	}
7485
7486	#[rstest]
7487	fn test_over_deep_filter_condition_returns_error_and_to_sql_stays_safe() {
7488		// Arrange
7489		let mut condition = FilterCondition::Single(TestUser::field_username().exact("alice"));
7490		for _ in 0..=MAX_FILTER_CONDITION_DEPTH {
7491			condition = FilterCondition::not(condition);
7492		}
7493		let queryset = QuerySet::<TestUser>::new().filter(condition);
7494
7495		// Act
7496		let result = queryset.build_where_condition();
7497		let sql = queryset.to_sql();
7498
7499		// Assert
7500		assert!(matches!(
7501			result,
7502			Err(reinhardt_core::exception::Error::Validation(_))
7503		));
7504		assert_eq!(sql, r#"SELECT * FROM "test_users" WHERE FALSE"#);
7505	}
7506
7507	#[rstest]
7508	#[case(
7509		Filter::new("email", FilterOperator::IContains, FilterValue::String("100%_match\\".to_string())),
7510		r#"SELECT * FROM "test_users" WHERE "email" ILIKE '%100\%\_match\\%' ESCAPE '\'"#
7511	)]
7512	#[case(
7513		Filter::new("username", FilterOperator::IExact, FilterValue::String("alice_admin".to_string())),
7514		r#"SELECT * FROM "test_users" WHERE "username" ILIKE 'alice\_admin' ESCAPE '\'"#
7515	)]
7516	fn test_django_style_case_insensitive_like_filters_escape_metacharacters(
7517		#[case] filter: Filter,
7518		#[case] expected: &str,
7519	) {
7520		// Arrange
7521		let queryset = QuerySet::<TestUser>::new().filter(filter);
7522
7523		// Act
7524		let sql = queryset.to_sql();
7525
7526		// Assert
7527		assert_eq!(sql, expected);
7528	}
7529
7530	#[rstest]
7531	#[case(
7532		Filter::new("email", FilterOperator::Contains, FilterValue::String("100%_match\\".to_string())),
7533		r#"SELECT * FROM "test_users" WHERE "email" LIKE '%100\%\_match\\%' ESCAPE '\'"#
7534	)]
7535	#[case(
7536		Filter::new("username", FilterOperator::StartsWith, FilterValue::String("alice_admin".to_string())),
7537		r#"SELECT * FROM "test_users" WHERE "username" LIKE 'alice\_admin%' ESCAPE '\'"#
7538	)]
7539	#[case(
7540		Filter::new("username", FilterOperator::EndsWith, FilterValue::String("100%".to_string())),
7541		r#"SELECT * FROM "test_users" WHERE "username" LIKE '%100\%' ESCAPE '\'"#
7542	)]
7543	fn test_django_style_case_sensitive_like_filters_escape_metacharacters(
7544		#[case] filter: Filter,
7545		#[case] expected: &str,
7546	) {
7547		// Arrange
7548		let queryset = QuerySet::<TestUser>::new().filter(filter);
7549
7550		// Act
7551		let sql = queryset.to_sql();
7552
7553		// Assert
7554		assert_eq!(sql, expected);
7555	}
7556
7557	#[rstest]
7558	fn test_django_style_is_in_filter_accepts_typed_values() {
7559		// Arrange
7560		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7561			"id",
7562			FilterOperator::In,
7563			FilterValue::List(vec![FilterValue::Integer(1), FilterValue::Integer(2)]),
7564		));
7565
7566		// Act
7567		let sql = queryset.to_sql();
7568
7569		// Assert
7570		assert_eq!(sql, r#"SELECT * FROM "test_users" WHERE "id" IN (1, 2)"#);
7571	}
7572
7573	#[rstest]
7574	fn test_django_style_between_range_filter() {
7575		// Arrange
7576		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7577			"id",
7578			FilterOperator::Range,
7579			FilterValue::Range(
7580				Box::new(FilterValue::Integer(10)),
7581				Box::new(FilterValue::Integer(20)),
7582			),
7583		));
7584
7585		// Act
7586		let sql = queryset.to_sql();
7587
7588		// Assert
7589		assert_eq!(
7590			sql,
7591			r#"SELECT * FROM "test_users" WHERE "id" BETWEEN 10 AND 20"#
7592		);
7593	}
7594
7595	#[rstest]
7596	fn test_django_style_date_part_filter_expression() {
7597		// Arrange
7598		let queryset = QuerySet::<TestUser>::new().filter(Filter::expression(
7599			"EXTRACT(YEAR FROM \"created_at\")",
7600			FilterOperator::Eq,
7601			FilterValue::Integer(2026),
7602		));
7603
7604		// Act
7605		let sql = queryset.to_sql();
7606
7607		// Assert
7608		assert_eq!(
7609			sql,
7610			r#"SELECT * FROM "test_users" WHERE EXTRACT(YEAR FROM "created_at") = 2026"#
7611		);
7612	}
7613
7614	#[rstest]
7615	fn test_public_filter_new_treats_expression_like_field_as_quoted_column() {
7616		// Arrange
7617		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7618			"__reinhardt_filter_expr:EXTRACT(YEAR FROM \"created_at\")",
7619			FilterOperator::Eq,
7620			FilterValue::Integer(2026),
7621		));
7622
7623		// Act
7624		let sql = queryset.to_sql();
7625
7626		// Assert
7627		assert_eq!(
7628			sql,
7629			r#"SELECT * FROM "test_users" WHERE "__reinhardt_filter_expr:EXTRACT(YEAR FROM ""created_at"")" = 2026"#
7630		);
7631	}
7632
7633	#[rstest]
7634	fn test_public_column_filter_uses_mutated_field_consistently() {
7635		// Arrange
7636		let mut filter = Filter::new(
7637			"username",
7638			FilterOperator::Eq,
7639			FilterValue::String("alice".into()),
7640		);
7641		filter.field = "email".to_string();
7642		let queryset = QuerySet::<TestUser>::new().filter(filter);
7643
7644		// Act
7645		let sql = queryset.to_sql();
7646
7647		// Assert
7648		assert_eq!(sql, r#"SELECT * FROM "test_users" WHERE "email" = 'alice'"#);
7649	}
7650
7651	#[rstest]
7652	fn test_mutated_transformed_filter_field_falls_back_to_quoted_column() {
7653		// Arrange
7654		let mut filter = TestUser::field_created_at().year().eq(2026);
7655		filter.field = "EXTRACT(MONTH FROM \"created_at\")".to_string();
7656		let queryset = QuerySet::<TestUser>::new().filter(filter);
7657
7658		// Act
7659		let sql = queryset.to_sql();
7660
7661		// Assert
7662		assert_eq!(
7663			sql,
7664			r#"SELECT * FROM "test_users" WHERE "EXTRACT(MONTH FROM ""created_at"")" = 2026"#
7665		);
7666	}
7667
7668	#[rstest]
7669	fn test_field_accessor_lookup_helpers_generate_expected_sql() {
7670		// Arrange
7671		let queryset = QuerySet::<TestUser>::new()
7672			.filter(TestUser::field_username().exact("alice"))
7673			.filter(TestUser::field_email().icontains("example.com"))
7674			.filter(TestUser::field_id().is_in([1_i64, 2, 3]))
7675			.filter(TestUser::field_created_at().year().gte(2026));
7676
7677		// Act
7678		let sql = queryset.to_sql();
7679
7680		// Assert
7681		assert_eq!(
7682			sql,
7683			r#"SELECT * FROM "test_users" WHERE ("username" = 'alice' AND "email" ILIKE '%example.com%' ESCAPE '\' AND "id" IN (1, 2, 3) AND EXTRACT(YEAR FROM "created_at") >= 2026)"#
7684		);
7685	}
7686
7687	#[rstest]
7688	fn test_field_accessor_null_not_in_and_range_helpers_generate_expected_sql() {
7689		// Arrange
7690		let queryset = QuerySet::<TestUser>::new()
7691			.filter(TestUser::field_email().is_not_null())
7692			.filter(TestUser::field_id().not_in([10_i64, 20]))
7693			.filter(TestUser::field_id().range(100_i64, 200));
7694
7695		// Act
7696		let sql = queryset.to_sql();
7697
7698		// Assert
7699		assert_eq!(
7700			sql,
7701			r#"SELECT * FROM "test_users" WHERE ("email" IS NOT NULL AND "id" NOT IN (10, 20) AND "id" BETWEEN 100 AND 200)"#
7702		);
7703	}
7704
7705	#[rstest]
7706	fn test_field_accessor_string_lookup_variants_generate_expected_sql() {
7707		// Arrange
7708		let queryset = QuerySet::<TestUser>::new()
7709			.filter(TestUser::field_username().contains("lic"))
7710			.filter(TestUser::field_username().starts_with("a"))
7711			.filter(TestUser::field_username().ends_with("e"))
7712			.filter(TestUser::field_username().istarts_with("AL"))
7713			.filter(TestUser::field_username().iends_with("CE"))
7714			.filter(TestUser::field_username().regex("^a.*e$"))
7715			.filter(TestUser::field_username().iregex("^A.*E$"));
7716
7717		// Act
7718		let sql = queryset.to_sql();
7719
7720		// Assert
7721		assert_eq!(
7722			sql,
7723			r#"SELECT * FROM "test_users" WHERE ("username" LIKE '%lic%' ESCAPE '\' AND "username" LIKE 'a%' ESCAPE '\' AND "username" LIKE '%e' ESCAPE '\' AND "username" ILIKE 'AL%' ESCAPE '\' AND "username" ILIKE '%CE' ESCAPE '\' AND "username" ~ '^a.*e$' AND "username" ~* '^A.*E$')"#
7724		);
7725	}
7726
7727	#[rstest]
7728	#[case(TestUser::field_created_at().date().eq("2026-06-10"), r#"SELECT * FROM "test_users" WHERE DATE("created_at") = '2026-06-10'"#)]
7729	#[case(TestUser::field_created_at().time().eq("05:00:00"), r#"SELECT * FROM "test_users" WHERE TIME("created_at") = '05:00:00'"#)]
7730	#[case(TestUser::field_created_at().month().eq(6), r#"SELECT * FROM "test_users" WHERE EXTRACT(MONTH FROM "created_at") = 6"#)]
7731	#[case(TestUser::field_created_at().day().eq(10), r#"SELECT * FROM "test_users" WHERE EXTRACT(DAY FROM "created_at") = 10"#)]
7732	#[case(TestUser::field_created_at().week().eq(24), r#"SELECT * FROM "test_users" WHERE EXTRACT(WEEK FROM "created_at") = 24"#)]
7733	#[case(TestUser::field_created_at().week_day().eq(4), r#"SELECT * FROM "test_users" WHERE (EXTRACT(DOW FROM "created_at") + 1) = 4"#)]
7734	#[case(TestUser::field_created_at().iso_week_day().eq(3), r#"SELECT * FROM "test_users" WHERE EXTRACT(ISODOW FROM "created_at") = 3"#)]
7735	#[case(TestUser::field_created_at().quarter().eq(2), r#"SELECT * FROM "test_users" WHERE EXTRACT(QUARTER FROM "created_at") = 2"#)]
7736	#[case(TestUser::field_created_at().hour().gte(5), r#"SELECT * FROM "test_users" WHERE EXTRACT(HOUR FROM "created_at") >= 5"#)]
7737	#[case(TestUser::field_created_at().minute().lt(30), r#"SELECT * FROM "test_users" WHERE EXTRACT(MINUTE FROM "created_at") < 30"#)]
7738	#[case(TestUser::field_created_at().second().lte(59), r#"SELECT * FROM "test_users" WHERE EXTRACT(SECOND FROM "created_at") <= 59"#)]
7739	fn test_field_accessor_date_time_transforms_generate_expected_sql(
7740		#[case] filter: Filter,
7741		#[case] expected: &str,
7742	) {
7743		// Arrange
7744		let queryset = QuerySet::<TestUser>::new().filter(filter);
7745
7746		// Act
7747		let sql = queryset.to_sql();
7748
7749		// Assert
7750		assert_eq!(sql, expected);
7751	}
7752
7753	#[rstest]
7754	fn test_field_accessor_postgres_array_jsonb_and_range_helpers_generate_expected_sql() {
7755		// Arrange
7756		let queryset = QuerySet::<TestUser>::new()
7757			.filter(TestUser::field_tags().array_contains(["rust", "async"]))
7758			.filter(TestUser::field_tags().array_overlap(["web", "orm"]))
7759			.filter(TestUser::field_metadata().jsonb_contains(r#"{"active": true}"#))
7760			.filter(TestUser::field_metadata().jsonb_has_any_keys(["tier", "plan"]))
7761			.filter(TestUser::field_active_period().range_overlaps("[2026-01-01,2027-01-01)"));
7762
7763		// Act
7764		let sql = queryset.to_sql();
7765
7766		// Assert
7767		assert_eq!(
7768			sql,
7769			r#"SELECT * FROM "test_users" WHERE ("tags" @> ARRAY['rust', 'async'] AND "tags" && ARRAY['web', 'orm'] AND "metadata" @> '{"active": true}'::jsonb AND "metadata" ?| array['tier', 'plan'] AND "active_period" && '[2026-01-01,2027-01-01)')"#
7770		);
7771	}
7772
7773	#[rstest]
7774	fn test_complex_django_style_lookup_query_combines_order_distinct_and_limit() {
7775		// Arrange
7776		let queryset = QuerySet::<TestUser>::new()
7777			.filter(TestUser::field_email().icontains("example.com"))
7778			.filter(TestUser::field_username().is_not_null())
7779			.filter(TestUser::field_created_at().year().range(2024, 2026))
7780			.distinct()
7781			.order_by(&["-created_at", "username"])
7782			.limit(25)
7783			.offset(50);
7784
7785		// Act
7786		let sql = queryset.to_sql();
7787
7788		// Assert
7789		assert_eq!(
7790			sql,
7791			r#"SELECT DISTINCT * FROM "test_users" WHERE ("email" ILIKE '%example.com%' ESCAPE '\' AND "username" IS NOT NULL AND EXTRACT(YEAR FROM "created_at") BETWEEN 2024 AND 2026) ORDER BY "created_at" DESC, "username" ASC LIMIT 25 OFFSET 50"#
7792		);
7793	}
7794
7795	#[rstest]
7796	fn test_range_contains_filter_quotes_field() {
7797		// Arrange
7798		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7799			"age_range".to_string(),
7800			FilterOperator::RangeContains,
7801			FilterValue::String("25".to_string()),
7802		));
7803
7804		// Act
7805		let sql = queryset.to_sql();
7806
7807		// Assert
7808		assert_eq!(
7809			sql,
7810			r#"SELECT * FROM "test_users" WHERE "age_range" @> '25'"#
7811		);
7812	}
7813
7814	#[rstest]
7815	fn test_range_contained_by_filter_quotes_field() {
7816		// Arrange
7817		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7818			"age_range".to_string(),
7819			FilterOperator::RangeContainedBy,
7820			FilterValue::String("[20, 30]".to_string()),
7821		));
7822
7823		// Act
7824		let sql = queryset.to_sql();
7825
7826		// Assert
7827		assert_eq!(
7828			sql,
7829			r#"SELECT * FROM "test_users" WHERE "age_range" <@ '[20, 30]'"#
7830		);
7831	}
7832
7833	#[rstest]
7834	fn test_range_overlaps_filter_quotes_field() {
7835		// Arrange
7836		let queryset = QuerySet::<TestUser>::new().filter(Filter::new(
7837			"age_range".to_string(),
7838			FilterOperator::RangeOverlaps,
7839			FilterValue::String("[20, 30]".to_string()),
7840		));
7841
7842		// Act
7843		let sql = queryset.to_sql();
7844
7845		// Assert
7846		assert_eq!(
7847			sql,
7848			r#"SELECT * FROM "test_users" WHERE "age_range" && '[20, 30]'"#
7849		);
7850	}
7851}