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