Skip to main content

reinhardt_db/orm/
query.rs

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