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