clickhouse_orm/
query_builder.rs1use sea_query::{BinOper, EscapeBuilder, QueryBuilder, QuotedBuilder, SelectDistinct, SqlWriter, SubQueryStatement, TableRefBuilder, Value};
2use sea_query::extension::postgres::PgBinOper;
3use sea_query::Write;
4
5pub struct ClickHouseQueryBuilder;
6
7impl QuotedBuilder for ClickHouseQueryBuilder {
8 fn quote(&self) -> char {
9 '"'
10 }
11}
12
13impl EscapeBuilder for ClickHouseQueryBuilder {}
14
15impl TableRefBuilder for ClickHouseQueryBuilder {}
16
17impl QueryBuilder for ClickHouseQueryBuilder {
18 fn placeholder(&self) -> (&str, bool) {
19 ("$", true)
20 }
21
22 fn prepare_select_distinct(&self, select_distinct: &SelectDistinct, sql: &mut dyn SqlWriter) {
23 match select_distinct {
24 SelectDistinct::All => write!(sql, "ALL").unwrap(),
25 SelectDistinct::Distinct => write!(sql, "DISTINCT").unwrap(),
26 SelectDistinct::DistinctOn(cols) => {
27 write!(sql, "DISTINCT ON (").unwrap();
28 cols.iter().fold(true, |first, column_ref| {
29 if !first {
30 write!(sql, ", ").unwrap();
31 }
32 self.prepare_column_ref(column_ref, sql);
33 false
34 });
35 write!(sql, ")").unwrap();
36 }
37 _ => {}
38 };
39 }
40
41 fn prepare_bin_oper(&self, bin_oper: &BinOper, sql: &mut dyn SqlWriter) {
42 match bin_oper {
43 BinOper::PgOperator(oper) => write!(
44 sql,
45 "{}",
46 match oper {
47 PgBinOper::ILike => "ILIKE",
48 PgBinOper::NotILike => "NOT ILIKE",
49 PgBinOper::Matches => "@@",
50 PgBinOper::Contains => "@>",
51 PgBinOper::Contained => "<@",
52 PgBinOper::Concatenate => "||",
53 PgBinOper::Similarity => "%",
54 PgBinOper::WordSimilarity => "<%",
55 PgBinOper::StrictWordSimilarity => "<<%",
56 PgBinOper::SimilarityDistance => "<->",
57 PgBinOper::WordSimilarityDistance => "<<->",
58 PgBinOper::StrictWordSimilarityDistance => "<<<->",
59 }
60 )
61 .unwrap(),
62 _ => self.prepare_bin_oper_common(bin_oper, sql),
63 }
64 }
65
66 fn prepare_query_statement(&self, _: &SubQueryStatement, _: &mut dyn SqlWriter) {}
67
68 fn prepare_value(&self, value: &Value, sql: &mut dyn SqlWriter) {
82 sql.push_param(value.clone(), self as _);
83 }
84
85 fn write_string_quoted(&self, string: &str, buffer: &mut String) {
86 let escaped = self.escape_string(string);
87 let string = if escaped.find('\\').is_some() {
88 "E'".to_owned() + &escaped + "'"
89 } else {
90 "'".to_owned() + &escaped + "'"
91 };
92 write!(buffer, "{}", string).unwrap()
93 }
94
95 fn if_null_function(&self) -> &str {
96 "COALESCE"
97 }
98}