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 {
15 Self
16 }
17}
18
19impl SqlGenerator for PostgresGenerator {
20 fn quote_identifier(&self, name: &str) -> String {
21 escape_identifier(name)
22 }
23
24 fn placeholder(&self, index: usize) -> String {
25 format!("${}", index)
26 }
27
28 fn fuzzy_operator(&self) -> &str {
29 "ILIKE"
30 }
31
32 fn bool_literal(&self, val: bool) -> String {
33 if val {
34 "true".to_string()
35 } else {
36 "false".to_string()
37 }
38 }
39
40 fn string_concat(&self, parts: &[&str]) -> String {
41 parts.join(" || ")
42 }
43
44 fn limit_offset(&self, limit: Option<usize>, offset: Option<usize>) -> String {
45 let mut sql = String::new();
46 if let Some(n) = limit {
47 sql.push_str(&format!(" LIMIT {}", n));
48 }
49 if let Some(n) = offset {
50 sql.push_str(&format!(" OFFSET {}", n));
51 }
52 sql
53 }
54
55 fn json_access(&self, col: &str, path: &[&str]) -> String {
56 let mut sql = self.quote_identifier(col);
57
58 for (i, key) in path.iter().enumerate() {
59 let is_last = i == path.len() - 1;
60 let op = if is_last { "->>" } else { "->" };
64 sql.push_str(&format!("{}'{}'", op, key));
65 }
66 sql
67 }
68}