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