qail_core/transpiler/sql/
postgres.rs1use crate::transpiler::escape_identifier;
2use crate::transpiler::traits::SqlGenerator;
3
4pub struct PostgresGenerator;
6
7impl Default for PostgresGenerator {
8 fn default() -> Self {
9 Self::new()
10 }
11}
12
13impl PostgresGenerator {
14 pub fn new() -> Self {
16 Self
17 }
18}
19
20impl SqlGenerator for PostgresGenerator {
21 fn quote_identifier(&self, name: &str) -> String {
22 escape_identifier(name)
23 }
24
25 fn placeholder(&self, index: usize) -> String {
26 format!("${}", index)
27 }
28
29 fn fuzzy_operator(&self) -> &str {
30 "ILIKE"
31 }
32
33 fn bool_literal(&self, val: bool) -> String {
34 if val {
35 "true".to_string()
36 } else {
37 "false".to_string()
38 }
39 }
40
41 fn string_concat(&self, parts: &[&str]) -> String {
42 parts.join(" || ")
43 }
44
45 fn limit_offset(&self, limit: Option<usize>, offset: Option<usize>) -> String {
46 let mut sql = String::new();
47 if let Some(n) = limit {
48 sql.push_str(&format!(" LIMIT {}", n));
49 }
50 if let Some(n) = offset {
51 sql.push_str(&format!(" OFFSET {}", n));
52 }
53 sql
54 }
55
56 fn json_access(&self, col: &str, path: &[&str]) -> String {
57 let mut sql = self.quote_identifier(col);
58
59 for (i, key) in path.iter().enumerate() {
60 let is_last = i == path.len() - 1;
61 let op = if is_last { "->>" } else { "->" };
65 sql.push_str(&format!("{}'{}'", op, key.replace('\'', "''")));
66 }
67 sql
68 }
69}