sea_query/backend/postgres/
index.rs1use super::*;
2
3impl IndexBuilder for PostgresQueryBuilder {
4 fn prepare_table_index_expression(
7 &self,
8 create: &IndexCreateStatement,
9 sql: &mut dyn SqlWriter,
10 ) {
11 if let Some(name) = &create.index.name {
12 write!(
13 sql,
14 "CONSTRAINT {}{}{} ",
15 self.quote().left(),
16 name,
17 self.quote().right()
18 )
19 .unwrap();
20 }
21
22 self.prepare_index_prefix(create, sql);
23
24 if create.nulls_not_distinct {
25 write!(sql, "NULLS NOT DISTINCT ").unwrap();
26 }
27
28 self.prepare_index_columns(&create.index.columns, sql);
29
30 if !create.include_columns.is_empty() {
31 write!(sql, " ").unwrap();
32 self.prepare_include_columns(&create.include_columns, sql);
33 }
34 }
35
36 fn prepare_index_create_statement(
37 &self,
38 create: &IndexCreateStatement,
39 sql: &mut dyn SqlWriter,
40 ) {
41 write!(sql, "CREATE ").unwrap();
42 self.prepare_index_prefix(create, sql);
43 write!(sql, "INDEX ").unwrap();
44
45 if create.if_not_exists {
46 write!(sql, "IF NOT EXISTS ").unwrap();
47 }
48
49 if let Some(name) = &create.index.name {
50 write!(
51 sql,
52 "{}{}{}",
53 self.quote().left(),
54 name,
55 self.quote().right()
56 )
57 .unwrap();
58 }
59
60 write!(sql, " ON ").unwrap();
61 if let Some(table) = &create.table {
62 self.prepare_table_ref_index_stmt(table, sql);
63 }
64
65 self.prepare_index_type(&create.index_type, sql);
66 write!(sql, " ").unwrap();
67 self.prepare_index_columns(&create.index.columns, sql);
68
69 if !create.include_columns.is_empty() {
70 write!(sql, " ").unwrap();
71 self.prepare_include_columns(&create.include_columns, sql);
72 }
73
74 if create.nulls_not_distinct {
75 write!(sql, " NULLS NOT DISTINCT").unwrap();
76 }
77 self.prepare_filter(&create.r#where, sql);
78 }
79
80 fn prepare_table_ref_index_stmt(&self, table_ref: &TableRef, sql: &mut dyn SqlWriter) {
81 match table_ref {
82 TableRef::Table(_) | TableRef::SchemaTable(_, _) => {
83 self.prepare_table_ref_iden(table_ref, sql)
84 }
85 _ => panic!("Not supported"),
86 }
87 }
88
89 fn prepare_index_drop_statement(&self, drop: &IndexDropStatement, sql: &mut dyn SqlWriter) {
90 write!(sql, "DROP INDEX ").unwrap();
91
92 if drop.if_exists {
93 write!(sql, "IF EXISTS ").unwrap();
94 }
95
96 if let Some(table) = &drop.table {
97 match table {
98 TableRef::Table(_) => {}
99 TableRef::SchemaTable(schema, _) => {
100 schema.prepare(sql.as_writer(), self.quote());
101 write!(sql, ".").unwrap();
102 }
103 _ => panic!("Not supported"),
104 }
105 }
106 if let Some(name) = &drop.index.name {
107 write!(
108 sql,
109 "{}{}{}",
110 self.quote().left(),
111 name,
112 self.quote().right()
113 )
114 .unwrap();
115 }
116 }
117
118 fn prepare_index_type(&self, col_index_type: &Option<IndexType>, sql: &mut dyn SqlWriter) {
119 if let Some(index_type) = col_index_type {
120 write!(
121 sql,
122 " USING {}",
123 match index_type {
124 IndexType::BTree => "BTREE".to_owned(),
125 IndexType::FullText => "GIN".to_owned(),
126 IndexType::Hash => "HASH".to_owned(),
127 IndexType::Custom(custom) => custom.to_string(),
128 }
129 )
130 .unwrap();
131 }
132 }
133
134 fn prepare_index_prefix(&self, create: &IndexCreateStatement, sql: &mut dyn SqlWriter) {
135 if create.primary {
136 write!(sql, "PRIMARY KEY ").unwrap();
137 }
138 if create.unique {
139 write!(sql, "UNIQUE ").unwrap();
140 }
141 }
142
143 fn prepare_filter(&self, condition: &ConditionHolder, sql: &mut dyn SqlWriter) {
144 self.prepare_condition(condition, "WHERE", sql);
145 }
146}
147
148impl PostgresQueryBuilder {
149 fn prepare_include_columns(&self, columns: &[SeaRc<dyn Iden>], sql: &mut dyn SqlWriter) {
150 write!(sql, "INCLUDE (").unwrap();
151 columns.iter().fold(true, |first, col| {
152 if !first {
153 write!(sql, ", ").unwrap();
154 }
155 col.prepare(sql.as_writer(), self.quote());
156 false
157 });
158 write!(sql, ")").unwrap();
159 }
160}