Qail

Struct Qail 

Source
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: bool

Whether 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

Source

pub fn column_expr(self, expr: Expr) -> Self

Source

pub fn columns_expr<I>(self, exprs: I) -> Self
where I: IntoIterator<Item = Expr>,

Source

pub fn distinct_on<I, S>(self, cols: I) -> Self
where I: IntoIterator<Item = S>, S: AsRef<str>,

Source

pub fn distinct_on_expr<I>(self, exprs: I) -> Self
where I: IntoIterator<Item = Expr>,

Source

pub fn filter_cond(self, condition: Condition) -> Self

Source

pub fn having_cond(self, condition: Condition) -> Self

Source

pub fn having_conds( self, conditions: impl IntoIterator<Item = Condition>, ) -> Self

Source

pub fn with_ctes(self, ctes: Vec<CTEDef>) -> Self

Source

pub fn update_from<I, S>(self, tables: I) -> Self
where I: IntoIterator<Item = S>, S: AsRef<str>,

Source

pub fn delete_using<I, S>(self, tables: I) -> Self
where I: IntoIterator<Item = S>, S: AsRef<str>,

Source

pub fn for_update(self) -> Self

Source

pub fn for_no_key_update(self) -> Self

Source

pub fn for_share(self) -> Self

Source

pub fn for_key_share(self) -> Self

Source

pub fn fetch_first(self, count: u64) -> Self

Source

pub fn fetch_with_ties(self, count: u64) -> Self

Source

pub fn default_values(self) -> Self

Source

pub fn overriding_system_value(self) -> Self

Source

pub fn overriding_user_value(self) -> Self

Source

pub fn tablesample_bernoulli(self, percent: f64) -> Self

Source

pub fn tablesample_system(self, percent: f64) -> Self

Source

pub fn repeatable(self, seed: u64) -> Self

Source

pub fn only(self) -> Self

Source

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

Source

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

Source

pub fn table_alias(self, alias: impl AsRef<str>) -> Self

Source

pub fn order_by_expr(self, expr: Expr, order: SortOrder) -> Self

Source

pub fn group_by_expr<I>(self, exprs: I) -> Self
where I: IntoIterator<Item = Expr>,

Source§

impl Qail

Source

pub fn get(table: impl Into<String>) -> Self

Examples found in repository?
examples/whatsapp_insights.rs (line 13)
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

pub fn raw_sql(sql: impl Into<String>) -> Self

Source

pub fn set(table: impl Into<String>) -> Self

Source

pub fn del(table: impl Into<String>) -> Self

Source

pub fn add(table: impl Into<String>) -> Self

Source

pub fn put(table: impl Into<String>) -> Self

Source

pub fn export(table: impl Into<String>) -> Self

Source

pub fn make(table: impl Into<String>) -> Self

Source

pub fn truncate(table: impl Into<String>) -> Self

Source

pub fn explain(table: impl Into<String>) -> Self

Source

pub fn explain_analyze(table: impl Into<String>) -> Self

Source

pub fn lock(table: impl Into<String>) -> Self

Source

pub fn create_materialized_view(name: impl Into<String>, query: Qail) -> Self

Source

pub fn refresh_materialized_view(name: impl Into<String>) -> Self

Source

pub fn drop_materialized_view(name: impl Into<String>) -> Self

Source

pub fn redis_get(key: impl Into<String>) -> Self

Create a Redis GET command.

Qail::redis_get("session:123")
Source

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)
Source

pub fn redis_del(key: impl Into<String>) -> Self

Create a Redis DEL command.

Source

pub fn redis_incr(key: impl Into<String>) -> Self

Create a Redis INCR command.

Source

pub fn redis_decr(key: impl Into<String>) -> Self

Create a Redis DECR command.

Source

pub fn redis_ttl(key: impl Into<String>) -> Self

Create a Redis TTL command.

Source

pub fn redis_expire(key: impl Into<String>, seconds: i64) -> Self

Create a Redis EXPIRE command.

Source

pub fn redis_exists(key: impl Into<String>) -> Self

Create a Redis EXISTS command.

Source

pub fn redis_ping() -> Self

Create a Redis PING command.

Source§

impl Qail

Source

pub fn to_cte(self, name: impl Into<String>) -> CTEDef

Examples found in repository?
examples/whatsapp_insights.rs (line 131)
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

pub fn with(self, name: impl Into<String>, query: Qail) -> Self

Source

pub fn as_cte(self, name: impl Into<String>) -> Self

👎Deprecated since 0.13.0: Use .to_cte() for reusable CTEDef or .with() for inline CTE
Source

pub fn recursive(self, recursive_part: Qail) -> Self

Source

pub fn from_cte(self, cte_name: impl Into<String>) -> Self

Source

pub fn select_from_cte(self, columns: &[&str]) -> Self

Source

pub fn with_cte(self, cte: CTEDef) -> Self

Examples found in repository?
examples/whatsapp_insights.rs (line 134)
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

Source

pub fn limit(self, n: i64) -> Self

Source

pub fn sort_asc(self, column: &str) -> Self

👎Deprecated since 0.11.0: Use .order_asc(column) instead
Source

pub fn select_all(self) -> Self

Source

pub fn columns<I, S>(self, cols: I) -> Self
where I: IntoIterator<Item = S>, S: AsRef<str>,

Source

pub fn column(self, col: impl AsRef<str>) -> Self

Source

pub fn filter( self, column: impl AsRef<str>, op: Operator, value: impl Into<Value>, ) -> Self

Source

pub fn or_filter( self, column: impl AsRef<str>, op: Operator, value: impl Into<Value>, ) -> Self

Source

pub fn where_eq(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self

Source

pub fn eq(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self

Filter: column = value (shorter alias for where_eq)

Source

pub fn ne(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self

Filter: column != value

Source

pub fn gt(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self

Filter: column > value

Source

pub fn gte(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self

Filter: column >= value

Source

pub fn lt(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self

Filter: column < value

Source

pub fn lte(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self

Filter: column <= value

Source

pub fn is_null(self, column: impl AsRef<str>) -> Self

Filter: column IS NULL

Source

pub fn is_not_null(self, column: impl AsRef<str>) -> Self

Filter: column IS NOT NULL

Source

pub fn like(self, column: impl AsRef<str>, pattern: impl Into<Value>) -> Self

Filter: column LIKE pattern

Source

pub fn ilike(self, column: impl AsRef<str>, pattern: impl Into<Value>) -> Self

Filter: column ILIKE pattern (case-insensitive)

Source

pub fn in_vals<I, V>(self, column: impl AsRef<str>, values: I) -> Self
where I: IntoIterator<Item = V>, V: Into<Value>,

Filter: column IN (values)

Source

pub fn order_by(self, column: impl AsRef<str>, order: SortOrder) -> Self

Source

pub fn order_desc(self, column: impl AsRef<str>) -> Self

Source

pub fn order_asc(self, column: impl AsRef<str>) -> Self

Source

pub fn offset(self, n: i64) -> Self

Source

pub fn group_by<I, S>(self, cols: I) -> Self
where I: IntoIterator<Item = S>, S: AsRef<str>,

Source

pub fn distinct_on_all(self) -> Self

Source

pub fn join( self, kind: JoinKind, table: impl AsRef<str>, left_col: impl AsRef<str>, right_col: impl AsRef<str>, ) -> Self

Source

pub fn left_join( self, table: impl AsRef<str>, left_col: impl AsRef<str>, right_col: impl AsRef<str>, ) -> Self

Source

pub fn inner_join( self, table: impl AsRef<str>, left_col: impl AsRef<str>, right_col: impl AsRef<str>, ) -> Self

Source

pub fn returning<I, S>(self, cols: I) -> Self
where I: IntoIterator<Item = S>, S: AsRef<str>,

Source

pub fn returning_all(self) -> Self

Source

pub fn values<I, V>(self, vals: I) -> Self
where I: IntoIterator<Item = V>, V: Into<Value>,

Source

pub fn set_value(self, column: impl AsRef<str>, value: impl Into<Value>) -> Self

Source

pub fn set_opt<T>(self, column: impl AsRef<str>, value: Option<T>) -> Self
where T: Into<Value>,

Set value only if Some, skip entirely if None This is ergonomic for optional fields - the column is not included in the INSERT at all if None

Source§

impl Qail

Source

pub fn search(collection: &str) -> Self

Create a vector similarity search command.

§Example
use qail_core::prelude::*;

let cmd = Qail::search("products")
    .vector(vec![0.1, 0.2, 0.3])
    .limit(10);
Source

pub fn upsert(collection: &str) -> Self

Create a vector upsert command (insert or update points).

§Example
let cmd = Qail::upsert("products");
Source

pub fn scroll(collection: &str) -> Self

Create a scroll command for paginated iteration.

§Example
let cmd = Qail::scroll("products").limit(100);
Source

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());
Source

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));
Source

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);
Source

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);
Source§

impl Qail

Source

pub fn hook(self, cols: &[&str]) -> Self

👎Deprecated since 0.11.0: Use .columns([…]) instead
Source

pub fn cage(self, column: &str, value: impl Into<Value>) -> Self

👎Deprecated since 0.11.0: Use .filter(column, Operator::Eq, value) or .where_eq(column, value) instead

Trait Implementations§

Source§

impl Clone for Qail

Source§

fn clone(&self) -> Qail

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Qail

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Qail

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for Qail

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for Qail

Source§

fn eq(&self, other: &Qail) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for Qail

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl ToDynamo for Qail

Source§

impl ToMongo for Qail

Source§

impl ToQdrant for Qail

Source§

impl ToSql for Qail

Source§

fn to_sql_with_dialect(&self, dialect: Dialect) -> String

Convert this node to a SQL string with specific dialect.
Source§

fn to_sql(&self) -> String

Convert this node to a SQL string using default dialect.
Source§

impl ToSqlParameterized for Qail

Source§

fn to_sql_parameterized_with_dialect(&self, dialect: Dialect) -> TranspileResult

Convert to SQL with extracted parameters for specific dialect.
Source§

fn to_sql_parameterized(&self) -> TranspileResult

Convert to SQL with extracted parameters (default dialect).
Source§

impl StructuralPartialEq for Qail

Auto Trait Implementations§

§

impl Freeze for Qail

§

impl RefUnwindSafe for Qail

§

impl Send for Qail

§

impl Sync for Qail

§

impl Unpin for Qail

§

impl UnwindSafe for Qail

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,