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 sql.write_str("CONSTRAINT ").unwrap();
13 sql.write_char(self.quote().left()).unwrap();
14 sql.write_str(name).unwrap();
15 sql.write_char(self.quote().right()).unwrap();
16 sql.write_str(" ").unwrap();
17 }
18
19 self.prepare_index_prefix(create, sql);
20
21 if create.nulls_not_distinct {
22 sql.write_str("NULLS NOT DISTINCT ").unwrap();
23 }
24
25 self.prepare_index_columns(&create.index.columns, sql);
26
27 if !create.include_columns.is_empty() {
28 sql.write_str(" ").unwrap();
29 self.prepare_include_columns(&create.include_columns, sql);
30 }
31 }
32
33 fn prepare_index_create_statement(
34 &self,
35 create: &IndexCreateStatement,
36 sql: &mut dyn SqlWriter,
37 ) {
38 sql.write_str("CREATE ").unwrap();
39 self.prepare_index_prefix(create, sql);
40 sql.write_str("INDEX ").unwrap();
41
42 if create.if_not_exists {
43 sql.write_str("IF NOT EXISTS ").unwrap();
44 }
45
46 if let Some(name) = &create.index.name {
47 sql.write_char(self.quote().left()).unwrap();
48 sql.write_str(name).unwrap();
49 sql.write_char(self.quote().right()).unwrap();
50 }
51
52 sql.write_str(" ON ").unwrap();
53 if let Some(table) = &create.table {
54 self.prepare_table_ref_index_stmt(table, sql);
55 }
56
57 self.prepare_index_type(&create.index_type, sql);
58 sql.write_str(" ").unwrap();
59 self.prepare_index_columns(&create.index.columns, sql);
60
61 if !create.include_columns.is_empty() {
62 sql.write_str(" ").unwrap();
63 self.prepare_include_columns(&create.include_columns, sql);
64 }
65
66 if create.nulls_not_distinct {
67 sql.write_str(" NULLS NOT DISTINCT").unwrap();
68 }
69 self.prepare_filter(&create.r#where, sql);
70 }
71
72 fn prepare_table_ref_index_stmt(&self, table_ref: &TableRef, sql: &mut dyn SqlWriter) {
73 let TableRef::Table(table_name, None) = table_ref else {
76 panic!("Not supported");
77 };
78 match table_name.as_iden_tuple() {
79 (Some(_db), _schema, _table) => panic!("Not supported"),
80 (None, _schema, _table) => self.prepare_table_ref_iden(table_ref, sql),
81 }
82 }
83
84 fn prepare_index_drop_statement(&self, drop: &IndexDropStatement, sql: &mut dyn SqlWriter) {
85 sql.write_str("DROP INDEX ").unwrap();
86
87 if drop.if_exists {
88 sql.write_str("IF EXISTS ").unwrap();
89 }
90
91 if let Some(table) = &drop.table {
92 let TableRef::Table(table_name, None) = table else {
95 panic!("Not supported");
96 };
97 match table_name.as_iden_tuple() {
98 (None, None, _table) => {}
99 (None, Some(schema), _table) => {
100 self.prepare_iden(schema, sql);
101 sql.write_str(".").unwrap();
102 }
103 (Some(_db), _schema, _table) => panic!("Not supported"),
104 }
105 }
106 if let Some(name) = &drop.index.name {
107 sql.write_char(self.quote().left()).unwrap();
108 sql.write_str(name).unwrap();
109 sql.write_char(self.quote().right()).unwrap();
110 }
111 }
112
113 fn prepare_index_type(&self, col_index_type: &Option<IndexType>, sql: &mut dyn SqlWriter) {
114 if let Some(index_type) = col_index_type {
115 sql.write_str(" USING ").unwrap();
116 match index_type {
117 IndexType::BTree => sql.write_str("BTREE"),
118 IndexType::FullText => sql.write_str("GIN"),
119 IndexType::Hash => sql.write_str("HASH"),
120 IndexType::Custom(custom) => sql.write_str(&custom.0),
121 }
122 .unwrap()
123 }
124 }
125
126 fn prepare_index_prefix(&self, create: &IndexCreateStatement, sql: &mut dyn SqlWriter) {
127 if create.primary {
128 sql.write_str("PRIMARY KEY ").unwrap();
129 }
130 if create.unique {
131 sql.write_str("UNIQUE ").unwrap();
132 }
133 }
134
135 fn prepare_index_columns(&self, columns: &[IndexColumn], sql: &mut dyn SqlWriter) {
136 sql.write_str("(").unwrap();
137
138 let mut cols = columns.iter();
139 join_io!(
140 cols,
141 col,
142 join {
143 sql.write_str(", ").unwrap();
144 },
145 do {
146 match col {
147 IndexColumn::TableColumn(column) => {
148 self.prepare_index_column_with_table_column(column, sql);
149 }
150 IndexColumn::Expr(column) => {
151 sql.write_str("(").unwrap();
152 self.prepare_simple_expr(&column.expr, sql);
153 sql.write_str(")").unwrap();
154 if let Some(order) = &column.order {
155 match order {
156 IndexOrder::Asc => sql.write_str(" ASC").unwrap(),
157 IndexOrder::Desc => sql.write_str(" DESC").unwrap(),
158 }
159 }
160 }
161 }
162 }
163 );
164
165 sql.write_str(")").unwrap();
166 }
167
168 fn prepare_filter(&self, condition: &ConditionHolder, sql: &mut dyn SqlWriter) {
169 self.prepare_condition(condition, "WHERE", sql);
170 }
171}
172
173impl PostgresQueryBuilder {
174 fn prepare_include_columns(&self, columns: &[DynIden], sql: &mut dyn SqlWriter) {
175 sql.write_str("INCLUDE (").unwrap();
176
177 let mut cols = columns.iter();
178 join_io!(
179 cols,
180 col,
181 join {
182 sql.write_str(", ").unwrap();
183 },
184 do {
185 self.prepare_iden(col, sql);
186 }
187 );
188
189 sql.write_str(")").unwrap();
190 }
191}