sea_query/backend/mysql/
index.rs

1use super::*;
2
3impl IndexBuilder for MysqlQueryBuilder {
4    fn prepare_table_index_expression(
5        &self,
6        create: &IndexCreateStatement,
7        sql: &mut dyn SqlWriter,
8    ) {
9        self.prepare_index_prefix(create, sql);
10        sql.write_str("KEY ").unwrap();
11
12        if let Some(name) = &create.index.name {
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_type(&create.index_type, sql);
20        if matches!(create.index_type, Some(IndexType::FullText)) {
21            sql.write_str(" ").unwrap();
22        }
23
24        self.prepare_index_columns(&create.index.columns, sql);
25    }
26
27    fn prepare_index_create_statement(
28        &self,
29        create: &IndexCreateStatement,
30        sql: &mut dyn SqlWriter,
31    ) {
32        sql.write_str("CREATE ").unwrap();
33        self.prepare_index_prefix(create, sql);
34        sql.write_str("INDEX ").unwrap();
35
36        if let Some(name) = &create.index.name {
37            sql.write_char(self.quote().left()).unwrap();
38            sql.write_str(name).unwrap();
39            sql.write_char(self.quote().right()).unwrap();
40        }
41
42        sql.write_str(" ON ").unwrap();
43        if let Some(table) = &create.table {
44            self.prepare_table_ref_index_stmt(table, sql);
45        }
46        sql.write_str(" ").unwrap();
47        self.prepare_index_columns(&create.index.columns, sql);
48
49        self.prepare_index_type(&create.index_type, sql);
50    }
51
52    fn prepare_table_ref_index_stmt(&self, table_ref: &TableRef, sql: &mut dyn SqlWriter) {
53        match table_ref {
54            // Support only "naked" table names with no schema or alias.
55            TableRef::Table(TableName(None, _), None) => {
56                self.prepare_table_ref_iden(table_ref, sql)
57            }
58            _ => panic!("Not supported"),
59        }
60    }
61    fn prepare_index_drop_statement(&self, drop: &IndexDropStatement, sql: &mut dyn SqlWriter) {
62        sql.write_str("DROP INDEX ").unwrap();
63
64        if drop.if_exists {
65            panic!("Mysql does not support IF EXISTS for DROP INDEX")
66        }
67
68        if let Some(name) = &drop.index.name {
69            sql.write_char(self.quote().left()).unwrap();
70            sql.write_str(name).unwrap();
71            sql.write_char(self.quote().right()).unwrap();
72        }
73
74        sql.write_str(" ON ").unwrap();
75        if let Some(table) = &drop.table {
76            self.prepare_table_ref_index_stmt(table, sql);
77        }
78    }
79
80    fn prepare_index_type(&self, col_index_type: &Option<IndexType>, sql: &mut dyn SqlWriter) {
81        if let Some(index_type) = col_index_type {
82            if !matches!(index_type, IndexType::FullText) {
83                sql.write_str(" USING ").unwrap();
84                sql.write_str(match index_type {
85                    IndexType::BTree => "BTREE",
86                    IndexType::FullText => unreachable!(),
87                    IndexType::Hash => "HASH",
88                    IndexType::Custom(custom) => &custom.0,
89                })
90                .unwrap();
91            }
92        }
93    }
94
95    fn prepare_index_prefix(&self, create: &IndexCreateStatement, sql: &mut dyn SqlWriter) {
96        if create.primary {
97            sql.write_str("PRIMARY ").unwrap();
98        }
99        if create.unique {
100            sql.write_str("UNIQUE ").unwrap();
101        }
102        if matches!(create.index_type, Some(IndexType::FullText)) {
103            sql.write_str("FULLTEXT ").unwrap();
104        }
105    }
106
107    fn prepare_index_columns(&self, columns: &[IndexColumn], sql: &mut dyn SqlWriter) {
108        macro_rules! prepare {
109            ($i:ident) => {
110                match $i {
111                    IndexColumn::TableColumn(column) => {
112                        self.prepare_index_column_with_table_column(column, sql);
113                    }
114                    IndexColumn::Expr(column) => {
115                        sql.write_str("(").unwrap();
116                        self.prepare_simple_expr(&column.expr, sql);
117                        sql.write_str(")").unwrap();
118                        if let Some(order) = &column.order {
119                            match order {
120                                IndexOrder::Asc => sql.write_str(" ASC").unwrap(),
121                                IndexOrder::Desc => sql.write_str(" DESC").unwrap(),
122                            }
123                        }
124                    }
125                }
126            };
127        }
128
129        sql.write_str("(").unwrap();
130
131        let mut cols = columns.iter();
132
133        if let Some(col) = cols.next() {
134            prepare!(col)
135        }
136
137        for col in cols {
138            sql.write_str(", ").unwrap();
139            prepare!(col)
140        }
141
142        sql.write_str(")").unwrap();
143    }
144}