sea_query/backend/postgres/
index.rs

1use super::*;
2
3impl IndexBuilder for PostgresQueryBuilder {
4    // Overriden due to different "NULLS NOT UNIQUE" position in table index expression
5    // (as opposed to the regular index expression)
6    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}