pub struct Qail {Show 39 fields
pub action: Action,
pub table: String,
pub columns: Vec<Expr>,
pub joins: Vec<Join>,
pub cages: Vec<Cage>,
pub distinct: bool,
pub index_def: Option<IndexDef>,
pub table_constraints: Vec<TableConstraint>,
pub set_ops: Vec<(SetOp, Box<Qail>)>,
pub having: Vec<Condition>,
pub group_by_mode: GroupByMode,
pub ctes: Vec<CTEDef>,
pub distinct_on: Vec<Expr>,
pub returning: Option<Vec<Expr>>,
pub on_conflict: Option<OnConflict>,
pub source_query: Option<Box<Qail>>,
pub channel: Option<String>,
pub payload: Option<String>,
pub savepoint_name: Option<String>,
pub from_tables: Vec<String>,
pub using_tables: Vec<String>,
pub lock_mode: Option<LockMode>,
pub fetch: Option<(u64, bool)>,
pub default_values: bool,
pub overriding: Option<OverridingKind>,
pub sample: Option<(SampleMethod, f64, Option<u64>)>,
pub only_table: bool,
pub vector: Option<Vec<f32>>,
pub score_threshold: Option<f32>,
pub vector_name: Option<String>,
pub with_vector: bool,
pub vector_size: Option<u64>,
pub distance: Option<Distance>,
pub on_disk: Option<bool>,
pub function_def: Option<FunctionDef>,
pub trigger_def: Option<TriggerDef>,
pub raw_value: Option<Vec<u8>>,
pub redis_ttl: Option<i64>,
pub redis_set_condition: Option<String>,
}Fields§
§action: Action§table: String§columns: Vec<Expr>§joins: Vec<Join>§cages: Vec<Cage>§distinct: bool§index_def: Option<IndexDef>§table_constraints: Vec<TableConstraint>§set_ops: Vec<(SetOp, Box<Qail>)>§having: Vec<Condition>§group_by_mode: GroupByMode§ctes: Vec<CTEDef>§distinct_on: Vec<Expr>§returning: Option<Vec<Expr>>§on_conflict: Option<OnConflict>§source_query: Option<Box<Qail>>§channel: Option<String>§payload: Option<String>§savepoint_name: Option<String>§from_tables: Vec<String>§using_tables: Vec<String>§lock_mode: Option<LockMode>§fetch: Option<(u64, bool)>§default_values: bool§overriding: Option<OverridingKind>§sample: Option<(SampleMethod, f64, Option<u64>)>§only_table: bool§vector: Option<Vec<f32>>Vector embedding for similarity search
score_threshold: Option<f32>Minimum similarity score threshold
vector_name: Option<String>Named vector field (for collections with multiple vectors)
with_vector: boolWhether to return vectors in search results
vector_size: Option<u64>Vector dimensions (e.g., 1536)
distance: Option<Distance>Distance metric (Cosine, Euclid, Dot)
on_disk: Option<bool>Storage optimized for disk (mmap)
function_def: Option<FunctionDef>Function definition (CREATE FUNCTION)
trigger_def: Option<TriggerDef>Trigger definition (CREATE TRIGGER)
raw_value: Option<Vec<u8>>Raw binary value for Redis SET
redis_ttl: Option<i64>TTL in seconds for Redis operations
redis_set_condition: Option<String>SET condition (NX = only if not exists, XX = only if exists)
Implementations§
Source§impl Qail
impl Qail
pub fn column_expr(self, expr: Expr) -> Self
pub fn columns_expr<I>(self, exprs: I) -> Selfwhere
I: IntoIterator<Item = Expr>,
pub fn distinct_on<I, S>(self, cols: I) -> Self
pub fn distinct_on_expr<I>(self, exprs: I) -> Selfwhere
I: IntoIterator<Item = Expr>,
pub fn filter_cond(self, condition: Condition) -> Self
pub fn having_cond(self, condition: Condition) -> Self
pub fn having_conds( self, conditions: impl IntoIterator<Item = Condition>, ) -> Self
pub fn with_ctes(self, ctes: Vec<CTEDef>) -> Self
pub fn update_from<I, S>(self, tables: I) -> Self
pub fn delete_using<I, S>(self, tables: I) -> Self
pub fn for_update(self) -> Self
pub fn for_no_key_update(self) -> Self
pub fn fetch_first(self, count: u64) -> Self
pub fn fetch_with_ties(self, count: u64) -> Self
pub fn default_values(self) -> Self
pub fn overriding_system_value(self) -> Self
pub fn overriding_user_value(self) -> Self
pub fn tablesample_bernoulli(self, percent: f64) -> Self
pub fn tablesample_system(self, percent: f64) -> Self
pub fn repeatable(self, seed: u64) -> Self
pub fn only(self) -> Self
pub fn left_join_as( self, table: impl AsRef<str>, alias: impl AsRef<str>, left_col: impl AsRef<str>, right_col: impl AsRef<str>, ) -> Self
pub fn inner_join_as( self, table: impl AsRef<str>, alias: impl AsRef<str>, left_col: impl AsRef<str>, right_col: impl AsRef<str>, ) -> Self
pub fn table_alias(self, alias: impl AsRef<str>) -> Self
pub fn order_by_expr(self, expr: Expr, order: SortOrder) -> Self
pub fn group_by_expr<I>(self, exprs: I) -> Selfwhere
I: IntoIterator<Item = Expr>,
Source§impl Qail
impl Qail
Sourcepub fn get(table: impl Into<String>) -> Self
pub fn get(table: impl Into<String>) -> Self
Examples found in repository?
11fn main() {
12 // Build the stats CTE subquery
13 let mut stats_query = Qail::get("whatsapp_messages");
14
15 // COUNT(DISTINCT phone_number) AS total_contacts
16 stats_query.columns.push(Expr::Aggregate {
17 col: "phone_number".to_string(),
18 func: AggregateFunc::Count,
19 distinct: true,
20 filter: None,
21 alias: Some("total_contacts".to_string()),
22 });
23
24 // COUNT(*) AS total_messages
25 stats_query.columns.push(Expr::Aggregate {
26 col: "*".to_string(),
27 func: AggregateFunc::Count,
28 distinct: false,
29 filter: None,
30 alias: Some("total_messages".to_string()),
31 });
32
33 // COUNT(*) FILTER (WHERE direction = 'outbound' AND created_at > NOW() - INTERVAL '24 hours') AS messages_sent_24h
34 stats_query.columns.push(Expr::Aggregate {
35 col: "*".to_string(),
36 func: AggregateFunc::Count,
37 distinct: false,
38 filter: Some(vec![
39 Condition {
40 left: Expr::Named("direction".to_string()),
41 op: Operator::Eq,
42 value: Value::String("outbound".to_string()),
43 is_array_unnest: false,
44 },
45 Condition {
46 left: Expr::Named("created_at".to_string()),
47 op: Operator::Gt,
48 value: Value::Function("NOW() - INTERVAL '24 hours'".to_string()),
49 is_array_unnest: false,
50 },
51 ]),
52 alias: Some("messages_sent_24h".to_string()),
53 });
54
55 // COUNT(*) FILTER (WHERE direction = 'inbound' AND created_at > NOW() - INTERVAL '24 hours') AS messages_received_24h
56 stats_query.columns.push(Expr::Aggregate {
57 col: "*".to_string(),
58 func: AggregateFunc::Count,
59 distinct: false,
60 filter: Some(vec![
61 Condition {
62 left: Expr::Named("direction".to_string()),
63 op: Operator::Eq,
64 value: Value::String("inbound".to_string()),
65 is_array_unnest: false,
66 },
67 Condition {
68 left: Expr::Named("created_at".to_string()),
69 op: Operator::Gt,
70 value: Value::Function("NOW() - INTERVAL '24 hours'".to_string()),
71 is_array_unnest: false,
72 },
73 ]),
74 alias: Some("messages_received_24h".to_string()),
75 });
76
77 // COUNT(*) FILTER (WHERE direction = 'inbound' AND status = 'received') AS unread_messages
78 stats_query.columns.push(Expr::Aggregate {
79 col: "*".to_string(),
80 func: AggregateFunc::Count,
81 distinct: false,
82 filter: Some(vec![
83 Condition {
84 left: Expr::Named("direction".to_string()),
85 op: Operator::Eq,
86 value: Value::String("inbound".to_string()),
87 is_array_unnest: false,
88 },
89 Condition {
90 left: Expr::Named("status".to_string()),
91 op: Operator::Eq,
92 value: Value::String("received".to_string()),
93 is_array_unnest: false,
94 },
95 ]),
96 alias: Some("unread_messages".to_string()),
97 });
98
99 // COUNT(*) FILTER (WHERE direction = 'outbound' AND created_at > NOW() - INTERVAL '24 hours' AND status IN ('delivered', 'read')) AS successful_deliveries_24h
100 stats_query.columns.push(Expr::Aggregate {
101 col: "*".to_string(),
102 func: AggregateFunc::Count,
103 distinct: false,
104 filter: Some(vec![
105 Condition {
106 left: Expr::Named("direction".to_string()),
107 op: Operator::Eq,
108 value: Value::String("outbound".to_string()),
109 is_array_unnest: false,
110 },
111 Condition {
112 left: Expr::Named("created_at".to_string()),
113 op: Operator::Gt,
114 value: Value::Function("NOW() - INTERVAL '24 hours'".to_string()),
115 is_array_unnest: false,
116 },
117 Condition {
118 left: Expr::Named("status".to_string()),
119 op: Operator::In,
120 value: Value::Array(vec![
121 Value::String("delivered".to_string()),
122 Value::String("read".to_string()),
123 ]),
124 is_array_unnest: false,
125 },
126 ]),
127 alias: Some("successful_deliveries_24h".to_string()),
128 });
129
130 // Create CTE definition (using new API)
131 let stats_cte = stats_query.to_cte("stats");
132
133 // Build final SELECT from CTE with CASE expression for delivery_rate
134 let mut final_query = Qail::get("stats").with_cte(stats_cte);
135 final_query.columns = vec![
136 Expr::Named("total_contacts".to_string()),
137 Expr::Named("total_messages".to_string()),
138 Expr::Named("messages_sent_24h".to_string()),
139 Expr::Named("messages_received_24h".to_string()),
140 Expr::Named("unread_messages".to_string()),
141 Expr::Case {
142 when_clauses: vec![(
143 Condition {
144 left: Expr::Named("messages_sent_24h".to_string()),
145 op: Operator::Gt,
146 value: Value::Int(0),
147 is_array_unnest: false,
148 },
149 Box::new(Expr::Binary {
150 left: Box::new(Expr::Binary {
151 left: Box::new(Expr::Cast {
152 expr: Box::new(Expr::Named("successful_deliveries_24h".to_string())),
153 target_type: "float8".to_string(),
154 alias: None,
155 }),
156 op: BinaryOp::Div,
157 right: Box::new(Expr::Cast {
158 expr: Box::new(Expr::Named("messages_sent_24h".to_string())),
159 target_type: "float8".to_string(),
160 alias: None,
161 }),
162 alias: None,
163 }),
164 op: BinaryOp::Mul,
165 right: Box::new(Expr::Named("100.0".to_string())),
166 alias: None,
167 }),
168 )],
169 else_value: Some(Box::new(Expr::Named("0.0".to_string()))),
170 alias: Some("delivery_rate_24h".to_string()),
171 },
172 ];
173
174 // Generate SQL
175 let sql = final_query.to_sql();
176 println!("Generated SQL:\n{}", sql);
177}pub fn raw_sql(sql: impl Into<String>) -> Self
pub fn set(table: impl Into<String>) -> Self
pub fn del(table: impl Into<String>) -> Self
pub fn add(table: impl Into<String>) -> Self
pub fn put(table: impl Into<String>) -> Self
pub fn export(table: impl Into<String>) -> Self
pub fn make(table: impl Into<String>) -> Self
pub fn truncate(table: impl Into<String>) -> Self
pub fn explain(table: impl Into<String>) -> Self
pub fn explain_analyze(table: impl Into<String>) -> Self
pub fn lock(table: impl Into<String>) -> Self
pub fn create_materialized_view(name: impl Into<String>, query: Qail) -> Self
pub fn refresh_materialized_view(name: impl Into<String>) -> Self
pub fn drop_materialized_view(name: impl Into<String>) -> Self
Sourcepub fn redis_get(key: impl Into<String>) -> Self
pub fn redis_get(key: impl Into<String>) -> Self
Create a Redis GET command.
Qail::redis_get("session:123")Sourcepub fn redis_set(key: impl Into<String>, value: impl Into<Vec<u8>>) -> Self
pub fn redis_set(key: impl Into<String>, value: impl Into<Vec<u8>>) -> Self
Create a Redis SET command.
Use .redis_ex() or .redis_px() to add TTL.
Qail::redis_set("key", "value").redis_ex(3600)Sourcepub fn redis_incr(key: impl Into<String>) -> Self
pub fn redis_incr(key: impl Into<String>) -> Self
Create a Redis INCR command.
Sourcepub fn redis_decr(key: impl Into<String>) -> Self
pub fn redis_decr(key: impl Into<String>) -> Self
Create a Redis DECR command.
Sourcepub fn redis_expire(key: impl Into<String>, seconds: i64) -> Self
pub fn redis_expire(key: impl Into<String>, seconds: i64) -> Self
Create a Redis EXPIRE command.
Sourcepub fn redis_exists(key: impl Into<String>) -> Self
pub fn redis_exists(key: impl Into<String>) -> Self
Create a Redis EXISTS command.
Sourcepub fn redis_ping() -> Self
pub fn redis_ping() -> Self
Create a Redis PING command.
Source§impl Qail
impl Qail
Sourcepub fn to_cte(self, name: impl Into<String>) -> CTEDef
pub fn to_cte(self, name: impl Into<String>) -> CTEDef
Examples found in repository?
11fn main() {
12 // Build the stats CTE subquery
13 let mut stats_query = Qail::get("whatsapp_messages");
14
15 // COUNT(DISTINCT phone_number) AS total_contacts
16 stats_query.columns.push(Expr::Aggregate {
17 col: "phone_number".to_string(),
18 func: AggregateFunc::Count,
19 distinct: true,
20 filter: None,
21 alias: Some("total_contacts".to_string()),
22 });
23
24 // COUNT(*) AS total_messages
25 stats_query.columns.push(Expr::Aggregate {
26 col: "*".to_string(),
27 func: AggregateFunc::Count,
28 distinct: false,
29 filter: None,
30 alias: Some("total_messages".to_string()),
31 });
32
33 // COUNT(*) FILTER (WHERE direction = 'outbound' AND created_at > NOW() - INTERVAL '24 hours') AS messages_sent_24h
34 stats_query.columns.push(Expr::Aggregate {
35 col: "*".to_string(),
36 func: AggregateFunc::Count,
37 distinct: false,
38 filter: Some(vec![
39 Condition {
40 left: Expr::Named("direction".to_string()),
41 op: Operator::Eq,
42 value: Value::String("outbound".to_string()),
43 is_array_unnest: false,
44 },
45 Condition {
46 left: Expr::Named("created_at".to_string()),
47 op: Operator::Gt,
48 value: Value::Function("NOW() - INTERVAL '24 hours'".to_string()),
49 is_array_unnest: false,
50 },
51 ]),
52 alias: Some("messages_sent_24h".to_string()),
53 });
54
55 // COUNT(*) FILTER (WHERE direction = 'inbound' AND created_at > NOW() - INTERVAL '24 hours') AS messages_received_24h
56 stats_query.columns.push(Expr::Aggregate {
57 col: "*".to_string(),
58 func: AggregateFunc::Count,
59 distinct: false,
60 filter: Some(vec![
61 Condition {
62 left: Expr::Named("direction".to_string()),
63 op: Operator::Eq,
64 value: Value::String("inbound".to_string()),
65 is_array_unnest: false,
66 },
67 Condition {
68 left: Expr::Named("created_at".to_string()),
69 op: Operator::Gt,
70 value: Value::Function("NOW() - INTERVAL '24 hours'".to_string()),
71 is_array_unnest: false,
72 },
73 ]),
74 alias: Some("messages_received_24h".to_string()),
75 });
76
77 // COUNT(*) FILTER (WHERE direction = 'inbound' AND status = 'received') AS unread_messages
78 stats_query.columns.push(Expr::Aggregate {
79 col: "*".to_string(),
80 func: AggregateFunc::Count,
81 distinct: false,
82 filter: Some(vec![
83 Condition {
84 left: Expr::Named("direction".to_string()),
85 op: Operator::Eq,
86 value: Value::String("inbound".to_string()),
87 is_array_unnest: false,
88 },
89 Condition {
90 left: Expr::Named("status".to_string()),
91 op: Operator::Eq,
92 value: Value::String("received".to_string()),
93 is_array_unnest: false,
94 },
95 ]),
96 alias: Some("unread_messages".to_string()),
97 });
98
99 // COUNT(*) FILTER (WHERE direction = 'outbound' AND created_at > NOW() - INTERVAL '24 hours' AND status IN ('delivered', 'read')) AS successful_deliveries_24h
100 stats_query.columns.push(Expr::Aggregate {
101 col: "*".to_string(),
102 func: AggregateFunc::Count,
103 distinct: false,
104 filter: Some(vec![
105 Condition {
106 left: Expr::Named("direction".to_string()),
107 op: Operator::Eq,
108 value: Value::String("outbound".to_string()),
109 is_array_unnest: false,
110 },
111 Condition {
112 left: Expr::Named("created_at".to_string()),
113 op: Operator::Gt,
114 value: Value::Function("NOW() - INTERVAL '24 hours'".to_string()),
115 is_array_unnest: false,
116 },
117 Condition {
118 left: Expr::Named("status".to_string()),
119 op: Operator::In,
120 value: Value::Array(vec![
121 Value::String("delivered".to_string()),
122 Value::String("read".to_string()),
123 ]),
124 is_array_unnest: false,
125 },
126 ]),
127 alias: Some("successful_deliveries_24h".to_string()),
128 });
129
130 // Create CTE definition (using new API)
131 let stats_cte = stats_query.to_cte("stats");
132
133 // Build final SELECT from CTE with CASE expression for delivery_rate
134 let mut final_query = Qail::get("stats").with_cte(stats_cte);
135 final_query.columns = vec![
136 Expr::Named("total_contacts".to_string()),
137 Expr::Named("total_messages".to_string()),
138 Expr::Named("messages_sent_24h".to_string()),
139 Expr::Named("messages_received_24h".to_string()),
140 Expr::Named("unread_messages".to_string()),
141 Expr::Case {
142 when_clauses: vec![(
143 Condition {
144 left: Expr::Named("messages_sent_24h".to_string()),
145 op: Operator::Gt,
146 value: Value::Int(0),
147 is_array_unnest: false,
148 },
149 Box::new(Expr::Binary {
150 left: Box::new(Expr::Binary {
151 left: Box::new(Expr::Cast {
152 expr: Box::new(Expr::Named("successful_deliveries_24h".to_string())),
153 target_type: "float8".to_string(),
154 alias: None,
155 }),
156 op: BinaryOp::Div,
157 right: Box::new(Expr::Cast {
158 expr: Box::new(Expr::Named("messages_sent_24h".to_string())),
159 target_type: "float8".to_string(),
160 alias: None,
161 }),
162 alias: None,
163 }),
164 op: BinaryOp::Mul,
165 right: Box::new(Expr::Named("100.0".to_string())),
166 alias: None,
167 }),
168 )],
169 else_value: Some(Box::new(Expr::Named("0.0".to_string()))),
170 alias: Some("delivery_rate_24h".to_string()),
171 },
172 ];
173
174 // Generate SQL
175 let sql = final_query.to_sql();
176 println!("Generated SQL:\n{}", sql);
177}pub fn with(self, name: impl Into<String>, query: Qail) -> Self
pub fn as_cte(self, name: impl Into<String>) -> Self
pub fn recursive(self, recursive_part: Qail) -> Self
pub fn from_cte(self, cte_name: impl Into<String>) -> Self
pub fn select_from_cte(self, columns: &[&str]) -> Self
Sourcepub fn with_cte(self, cte: CTEDef) -> Self
pub fn with_cte(self, cte: CTEDef) -> Self
Examples found in repository?
11fn main() {
12 // Build the stats CTE subquery
13 let mut stats_query = Qail::get("whatsapp_messages");
14
15 // COUNT(DISTINCT phone_number) AS total_contacts
16 stats_query.columns.push(Expr::Aggregate {
17 col: "phone_number".to_string(),
18 func: AggregateFunc::Count,
19 distinct: true,
20 filter: None,
21 alias: Some("total_contacts".to_string()),
22 });
23
24 // COUNT(*) AS total_messages
25 stats_query.columns.push(Expr::Aggregate {
26 col: "*".to_string(),
27 func: AggregateFunc::Count,
28 distinct: false,
29 filter: None,
30 alias: Some("total_messages".to_string()),
31 });
32
33 // COUNT(*) FILTER (WHERE direction = 'outbound' AND created_at > NOW() - INTERVAL '24 hours') AS messages_sent_24h
34 stats_query.columns.push(Expr::Aggregate {
35 col: "*".to_string(),
36 func: AggregateFunc::Count,
37 distinct: false,
38 filter: Some(vec![
39 Condition {
40 left: Expr::Named("direction".to_string()),
41 op: Operator::Eq,
42 value: Value::String("outbound".to_string()),
43 is_array_unnest: false,
44 },
45 Condition {
46 left: Expr::Named("created_at".to_string()),
47 op: Operator::Gt,
48 value: Value::Function("NOW() - INTERVAL '24 hours'".to_string()),
49 is_array_unnest: false,
50 },
51 ]),
52 alias: Some("messages_sent_24h".to_string()),
53 });
54
55 // COUNT(*) FILTER (WHERE direction = 'inbound' AND created_at > NOW() - INTERVAL '24 hours') AS messages_received_24h
56 stats_query.columns.push(Expr::Aggregate {
57 col: "*".to_string(),
58 func: AggregateFunc::Count,
59 distinct: false,
60 filter: Some(vec![
61 Condition {
62 left: Expr::Named("direction".to_string()),
63 op: Operator::Eq,
64 value: Value::String("inbound".to_string()),
65 is_array_unnest: false,
66 },
67 Condition {
68 left: Expr::Named("created_at".to_string()),
69 op: Operator::Gt,
70 value: Value::Function("NOW() - INTERVAL '24 hours'".to_string()),
71 is_array_unnest: false,
72 },
73 ]),
74 alias: Some("messages_received_24h".to_string()),
75 });
76
77 // COUNT(*) FILTER (WHERE direction = 'inbound' AND status = 'received') AS unread_messages
78 stats_query.columns.push(Expr::Aggregate {
79 col: "*".to_string(),
80 func: AggregateFunc::Count,
81 distinct: false,
82 filter: Some(vec![
83 Condition {
84 left: Expr::Named("direction".to_string()),
85 op: Operator::Eq,
86 value: Value::String("inbound".to_string()),
87 is_array_unnest: false,
88 },
89 Condition {
90 left: Expr::Named("status".to_string()),
91 op: Operator::Eq,
92 value: Value::String("received".to_string()),
93 is_array_unnest: false,
94 },
95 ]),
96 alias: Some("unread_messages".to_string()),
97 });
98
99 // COUNT(*) FILTER (WHERE direction = 'outbound' AND created_at > NOW() - INTERVAL '24 hours' AND status IN ('delivered', 'read')) AS successful_deliveries_24h
100 stats_query.columns.push(Expr::Aggregate {
101 col: "*".to_string(),
102 func: AggregateFunc::Count,
103 distinct: false,
104 filter: Some(vec![
105 Condition {
106 left: Expr::Named("direction".to_string()),
107 op: Operator::Eq,
108 value: Value::String("outbound".to_string()),
109 is_array_unnest: false,
110 },
111 Condition {
112 left: Expr::Named("created_at".to_string()),
113 op: Operator::Gt,
114 value: Value::Function("NOW() - INTERVAL '24 hours'".to_string()),
115 is_array_unnest: false,
116 },
117 Condition {
118 left: Expr::Named("status".to_string()),
119 op: Operator::In,
120 value: Value::Array(vec![
121 Value::String("delivered".to_string()),
122 Value::String("read".to_string()),
123 ]),
124 is_array_unnest: false,
125 },
126 ]),
127 alias: Some("successful_deliveries_24h".to_string()),
128 });
129
130 // Create CTE definition (using new API)
131 let stats_cte = stats_query.to_cte("stats");
132
133 // Build final SELECT from CTE with CASE expression for delivery_rate
134 let mut final_query = Qail::get("stats").with_cte(stats_cte);
135 final_query.columns = vec![
136 Expr::Named("total_contacts".to_string()),
137 Expr::Named("total_messages".to_string()),
138 Expr::Named("messages_sent_24h".to_string()),
139 Expr::Named("messages_received_24h".to_string()),
140 Expr::Named("unread_messages".to_string()),
141 Expr::Case {
142 when_clauses: vec![(
143 Condition {
144 left: Expr::Named("messages_sent_24h".to_string()),
145 op: Operator::Gt,
146 value: Value::Int(0),
147 is_array_unnest: false,
148 },
149 Box::new(Expr::Binary {
150 left: Box::new(Expr::Binary {
151 left: Box::new(Expr::Cast {
152 expr: Box::new(Expr::Named("successful_deliveries_24h".to_string())),
153 target_type: "float8".to_string(),
154 alias: None,
155 }),
156 op: BinaryOp::Div,
157 right: Box::new(Expr::Cast {
158 expr: Box::new(Expr::Named("messages_sent_24h".to_string())),
159 target_type: "float8".to_string(),
160 alias: None,
161 }),
162 alias: None,
163 }),
164 op: BinaryOp::Mul,
165 right: Box::new(Expr::Named("100.0".to_string())),
166 alias: None,
167 }),
168 )],
169 else_value: Some(Box::new(Expr::Named("0.0".to_string()))),
170 alias: Some("delivery_rate_24h".to_string()),
171 },
172 ];
173
174 // Generate SQL
175 let sql = final_query.to_sql();
176 println!("Generated SQL:\n{}", sql);
177}Source§impl Qail
impl Qail
pub fn limit(self, n: i64) -> Self
pub fn sort_asc(self, column: &str) -> Self
pub fn select_all(self) -> Self
pub fn columns<I, S>(self, cols: I) -> Self
pub fn column(self, col: impl AsRef<str>) -> Self
pub fn filter( self, column: impl AsRef<str>, op: Operator, value: impl Into<Value>, ) -> Self
pub fn or_filter( self, column: impl AsRef<str>, op: Operator, value: impl Into<Value>, ) -> Self
pub fn where_eq(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self
Sourcepub fn eq(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self
pub fn eq(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self
Filter: column = value (shorter alias for where_eq)
Sourcepub fn ne(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self
pub fn ne(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self
Filter: column != value
Sourcepub fn gt(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self
pub fn gt(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self
Filter: column > value
Sourcepub fn gte(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self
pub fn gte(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self
Filter: column >= value
Sourcepub fn lt(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self
pub fn lt(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self
Filter: column < value
Sourcepub fn lte(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self
pub fn lte(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self
Filter: column <= value
Sourcepub fn is_not_null(self, column: impl AsRef<str>) -> Self
pub fn is_not_null(self, column: impl AsRef<str>) -> Self
Filter: column IS NOT NULL
Sourcepub fn like(self, column: impl AsRef<str>, pattern: impl Into<Value>) -> Self
pub fn like(self, column: impl AsRef<str>, pattern: impl Into<Value>) -> Self
Filter: column LIKE pattern
Sourcepub fn ilike(self, column: impl AsRef<str>, pattern: impl Into<Value>) -> Self
pub fn ilike(self, column: impl AsRef<str>, pattern: impl Into<Value>) -> Self
Filter: column ILIKE pattern (case-insensitive)
Sourcepub fn in_vals<I, V>(self, column: impl AsRef<str>, values: I) -> Self
pub fn in_vals<I, V>(self, column: impl AsRef<str>, values: I) -> Self
Filter: column IN (values)
pub fn order_by(self, column: impl AsRef<str>, order: SortOrder) -> Self
pub fn order_desc(self, column: impl AsRef<str>) -> Self
pub fn order_asc(self, column: impl AsRef<str>) -> Self
pub fn offset(self, n: i64) -> Self
pub fn group_by<I, S>(self, cols: I) -> Self
pub fn distinct_on_all(self) -> Self
pub fn join( self, kind: JoinKind, table: impl AsRef<str>, left_col: impl AsRef<str>, right_col: impl AsRef<str>, ) -> Self
pub fn left_join( self, table: impl AsRef<str>, left_col: impl AsRef<str>, right_col: impl AsRef<str>, ) -> Self
pub fn inner_join( self, table: impl AsRef<str>, left_col: impl AsRef<str>, right_col: impl AsRef<str>, ) -> Self
pub fn returning<I, S>(self, cols: I) -> Self
pub fn returning_all(self) -> Self
pub fn values<I, V>(self, vals: I) -> Self
pub fn set_value(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self
Source§impl Qail
impl Qail
Sourcepub fn vector(self, embedding: Vec<f32>) -> Self
pub fn vector(self, embedding: Vec<f32>) -> Self
Set the query vector for similarity search.
§Example
use qail_core::prelude::*;
let embedding = vec![0.1, 0.2, 0.3, 0.4];
let cmd = Qail::search("products").vector(embedding);
assert!(cmd.vector.is_some());Sourcepub fn score_threshold(self, threshold: f32) -> Self
pub fn score_threshold(self, threshold: f32) -> Self
Set minimum similarity score threshold.
Points with similarity below this threshold will be filtered out.
§Example
use qail_core::prelude::*;
let cmd = Qail::search("products")
.vector(vec![0.1, 0.2])
.score_threshold(0.8);
assert_eq!(cmd.score_threshold, Some(0.8));Sourcepub fn vector_name(self, name: &str) -> Self
pub fn vector_name(self, name: &str) -> Self
Specify which named vector to search (for multi-vector collections).
§Example
use qail_core::prelude::*;
// Collection with separate "title" and "content" vectors
let title_embedding = vec![0.1, 0.2, 0.3];
let cmd = Qail::search("articles")
.vector_name("title")
.vector(title_embedding);Sourcepub fn with_vectors(self) -> Self
pub fn with_vectors(self) -> Self
Include vectors in search results.
§Example
use qail_core::prelude::*;
let embedding = vec![0.1, 0.2, 0.3];
let cmd = Qail::search("products")
.vector(embedding)
.with_vectors();
assert!(cmd.with_vector);