1use super::*;
2use crate::extension::mysql::*;
3
4impl QueryBuilder for MysqlQueryBuilder {
5 fn values_list_tuple_prefix(&self) -> &str {
6 "ROW"
7 }
8
9 fn prepare_select_distinct(&self, select_distinct: &SelectDistinct, sql: &mut dyn SqlWriter) {
10 match select_distinct {
11 SelectDistinct::All => sql.write_str("ALL").unwrap(),
12 SelectDistinct::Distinct => sql.write_str("DISTINCT").unwrap(),
13 SelectDistinct::DistinctRow => sql.write_str("DISTINCTROW").unwrap(),
14 _ => {}
15 };
16 }
17
18 fn prepare_index_hints(&self, select: &SelectStatement, sql: &mut dyn SqlWriter) {
19 if !select.index_hints.is_empty() {
20 sql.write_str(" ").unwrap();
21 }
22
23 let mut hints = select.index_hints.iter();
24
25 join_io!(
26 hints,
27 hint,
28 join {
29 sql.write_str(" ").unwrap();
30 },
31 do {
32 match hint.r#type {
33 IndexHintType::Use => {
34 sql.write_str("USE INDEX ").unwrap();
35 self.prepare_index_hint_scope(&hint.scope, sql);
36 sql.write_str("(").unwrap();
37 self.prepare_iden(&hint.index, sql);
38 }
39 IndexHintType::Ignore => {
40 sql.write_str("IGNORE INDEX ").unwrap();
41 self.prepare_index_hint_scope(&hint.scope, sql);
42 sql.write_str("(").unwrap();
43 self.prepare_iden(&hint.index, sql);
44 }
45 IndexHintType::Force => {
46 sql.write_str("FORCE INDEX ").unwrap();
47 self.prepare_index_hint_scope(&hint.scope, sql);
48 sql.write_str("(").unwrap();
49 self.prepare_iden(&hint.index, sql);
50 }
51 }
52 sql.write_str(")").unwrap();
53 }
54 );
55 }
56
57 fn prepare_query_statement(&self, query: &SubQueryStatement, sql: &mut dyn SqlWriter) {
58 query.prepare_statement(self, sql);
59 }
60
61 fn prepare_with_clause_recursive_options(&self, _: &WithClause, _: &mut dyn SqlWriter) {
62 }
64
65 fn prepare_with_query_clause_materialization(
66 &self,
67 _: &CommonTableExpression,
68 _: &mut dyn SqlWriter,
69 ) {
70 }
72
73 fn prepare_update_join(
74 &self,
75 from: &[TableRef],
76 condition: &ConditionHolder,
77 sql: &mut dyn SqlWriter,
78 ) {
79 if from.is_empty() {
80 return;
81 }
82
83 sql.write_str(" JOIN ").unwrap();
84
85 self.prepare_table_ref(&from[0], sql);
87
88 self.prepare_condition(condition, "ON", sql);
89 }
90
91 fn prepare_update_from(&self, _: &[TableRef], _: &mut dyn SqlWriter) {}
92
93 fn prepare_update_column(
94 &self,
95 table: &Option<Box<TableRef>>,
96 from: &[TableRef],
97 column: &DynIden,
98 sql: &mut dyn SqlWriter,
99 ) {
100 use std::ops::Deref;
101
102 if !from.is_empty() {
103 if let Some(table) = table {
104 if let TableRef::Table(TableName(None, table), None) = table.deref() {
106 let column_name = ColumnName::from((table.clone(), column.clone()));
107 self.prepare_column_ref(&ColumnRef::Column(column_name), sql);
108 return;
109 }
110 }
111 }
112 self.prepare_iden(column, sql)
113 }
114
115 fn prepare_update_condition(
116 &self,
117 from: &[TableRef],
118 condition: &ConditionHolder,
119 sql: &mut dyn SqlWriter,
120 ) {
121 if !from.is_empty() {
122 return;
123 }
124 self.prepare_condition(condition, "WHERE", sql);
125 }
126
127 fn prepare_join_type(&self, join_type: &JoinType, sql: &mut dyn SqlWriter) {
128 match join_type {
129 JoinType::FullOuterJoin => panic!("Mysql does not support FULL OUTER JOIN"),
130 _ => self.prepare_join_type_common(join_type, sql),
131 }
132 }
133
134 fn prepare_order_expr(&self, order_expr: &OrderExpr, sql: &mut dyn SqlWriter) {
135 match order_expr.nulls {
136 None => (),
137 Some(NullOrdering::Last) => {
138 self.prepare_simple_expr(&order_expr.expr, sql);
139 sql.write_str(" IS NULL ASC, ").unwrap()
140 }
141 Some(NullOrdering::First) => {
142 self.prepare_simple_expr(&order_expr.expr, sql);
143 sql.write_str(" IS NULL DESC, ").unwrap()
144 }
145 }
146 if !matches!(order_expr.order, Order::Field(_)) {
147 self.prepare_simple_expr(&order_expr.expr, sql);
148 }
149 self.prepare_order(order_expr, sql);
150 }
151
152 fn prepare_value(&self, value: Value, sql: &mut dyn SqlWriter) {
153 sql.push_param(value, self as _);
154 }
155
156 fn prepare_on_conflict_target(&self, _: &[OnConflictTarget], _: &mut dyn SqlWriter) {
157 }
159
160 fn prepare_on_conflict_action(
161 &self,
162 on_conflict_action: &Option<OnConflictAction>,
163 sql: &mut dyn SqlWriter,
164 ) {
165 match on_conflict_action {
166 Some(OnConflictAction::DoNothing(pk_cols)) => {
167 if !pk_cols.is_empty() {
168 self.prepare_on_conflict_do_update_keywords(sql);
169 let mut pk_cols_iter = pk_cols.iter();
170 join_io!(
171 pk_cols_iter,
172 pk_col,
173 join {
174 sql.write_str(", ").unwrap();
175 },
176 do {
177 self.prepare_iden(pk_col, sql);
178 sql.write_str(" = ").unwrap();
179 self.prepare_iden(pk_col, sql);
180 }
181 );
182 } else {
183 sql.write_str(" IGNORE").unwrap();
184 }
185 }
186 _ => self.prepare_on_conflict_action_common(on_conflict_action, sql),
187 }
188 }
189
190 fn prepare_on_conflict_keywords(&self, sql: &mut dyn SqlWriter) {
191 sql.write_str(" ON DUPLICATE KEY").unwrap();
192 }
193
194 fn prepare_on_conflict_do_update_keywords(&self, sql: &mut dyn SqlWriter) {
195 sql.write_str(" UPDATE ").unwrap();
196 }
197
198 fn prepare_on_conflict_excluded_table(&self, col: &DynIden, sql: &mut dyn SqlWriter) {
199 sql.write_str("VALUES(").unwrap();
200 self.prepare_iden(col, sql);
201 sql.write_str(")").unwrap();
202 }
203
204 fn prepare_on_conflict_condition(&self, _: &ConditionHolder, _: &mut dyn SqlWriter) {}
205
206 fn prepare_returning(&self, _returning: &Option<ReturningClause>, _sql: &mut dyn SqlWriter) {}
207
208 fn random_function(&self) -> &str {
209 "RAND"
210 }
211
212 fn insert_default_keyword(&self) -> &str {
213 "()"
214 }
215}
216
217impl MysqlQueryBuilder {
218 fn prepare_index_hint_scope(&self, index_hint_scope: &IndexHintScope, sql: &mut dyn SqlWriter) {
219 match index_hint_scope {
220 IndexHintScope::Join => {
221 sql.write_str("FOR JOIN ").unwrap();
222 }
223 IndexHintScope::OrderBy => {
224 sql.write_str("FOR ORDER BY ").unwrap();
225 }
226 IndexHintScope::GroupBy => {
227 sql.write_str("FOR GROUP BY ").unwrap();
228 }
229 IndexHintScope::All => {}
230 }
231 }
232}