Merge lp:~laurynas-biveinis/percona-server/bug1208371 into lp:percona-server/5.6
- bug1208371
- Merge into 5.6
Status: | Merged |
---|---|
Approved by: | Laurynas Biveinis |
Approved revision: | no longer in the source branch. |
Merged at revision: | 643 |
Proposed branch: | lp:~laurynas-biveinis/percona-server/bug1208371 |
Merge into: | lp:percona-server/5.6 |
Diff against target: |
1997 lines (+459/-572) 23 files modified
client/sql_string.cc (+0/-44) client/sql_string.h (+0/-10) mysql-test/suite/rpl/r/rpl_mdev382.result (+0/-2) sql/binlog.cc (+8/-6) sql/ha_ndbcluster_binlog.cc (+31/-17) sql/item.cc (+0/-16) sql/item.h (+0/-4) sql/item_func.cc (+2/-2) sql/item_func.h (+1/-1) sql/log_event.cc (+225/-260) sql/log_event.h (+25/-28) sql/log_event_old.cc (+1/-1) sql/log_event_old.h (+1/-1) sql/sql_base.cc (+15/-31) sql/sql_db.cc (+42/-21) sql/sql_load.cc (+43/-32) sql/sql_select.cc (+0/-1) sql/sql_show.cc (+39/-7) sql/sql_show.h (+1/-1) sql/sql_string.cc (+10/-61) sql/sql_string.h (+0/-10) sql/sql_truncate.cc (+14/-15) sql/sql_yacc.yy (+1/-1) |
To merge this branch: | bzr merge lp:~laurynas-biveinis/percona-server/bug1208371 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Laurynas Biveinis (community) | Approve | ||
Review via email: mp+229062@code.launchpad.net |
Commit message
Description of the change
Fix
- bug 1208371 (Revert our fixes for bug 1049871, bug 1175519, bug
1223196, and bug 1277351) and
- bug 1350386 (Restore MySQL 5.6.10 change for "15847447").
The former fix is a straightforward revert of MariaDB patch for
MDEV-382, while keeping a testcase. Since the Oracle fix for the same
issue is not complete yet (bug 1277351 /
http://
it in the same commit by passing the file name through String::print
in Load_log_
The MariaDB patch revert also uncovers and together with a testcase
re-record fixes bug 1350386, which is a MySQL 5.6.10 merge
regression.
Even though it's a large patch, there's only one non-revert bit:
@ -5852,7 +5895,8 @@
return
//the DB name may double if we escape the quote character
5 + 2*db_len + 3 +
- 18 + fname_len + 2 + // "LOAD DATA INFILE 'file''"
+ // Likewise for the fname
+ 18 + 2 * fname_len + 2 + // "LOAD DATA INFILE 'file''"
11 + // "CONCURRENT "
7 + // LOCAL
9 + // " REPLACE or IGNORE "
@@ -5899,8 +5943,10 @@
if (check_
pos= strmov(pos, "LOCAL ");
pos= strmov(pos, "INFILE '");
- memcpy(pos, fname, fname_len);
- pos= strmov(
+ String quoted_fname;
+ String(fname, fname_len, NULL).print(
+ memcpy(pos, quoted_fname.ptr(), quoted_
+ pos= strmov(pos + quoted_
if (sql_ex.opt_flags & REPLACE_FLAG)
pos= strmov(pos, "REPLACE ");
http://
Laurynas Biveinis (laurynas-biveinis) : | # |
Preview Diff
1 | === modified file 'client/sql_string.cc' |
2 | --- client/sql_string.cc 2013-08-14 03:57:21 +0000 |
3 | +++ client/sql_string.cc 2014-07-31 14:56:03 +0000 |
4 | @@ -479,50 +479,6 @@ |
5 | return FALSE; |
6 | } |
7 | |
8 | -bool String::append_identifier(const char *name, |
9 | - uint length, |
10 | - const CHARSET_INFO *ci, |
11 | - int quote_char) |
12 | -{ |
13 | - const char *name_end; |
14 | - char q= (char)quote_char; |
15 | - const CHARSET_INFO *lci = ci ? ci : charset(); |
16 | - |
17 | - if (quote_char == EOF) |
18 | - return append(name, length, charset()); |
19 | - |
20 | - /* |
21 | - The identifier must be quoted as it includes a quote character or |
22 | - it's a keyword |
23 | - */ |
24 | - |
25 | - (void)reserve(length*2 + 2); |
26 | - if (append(&q, 1, lci)) |
27 | - return true; |
28 | - |
29 | - for (name_end= name+length ; name < name_end ; name+= length) |
30 | - { |
31 | - uchar chr= (uchar) *name; |
32 | - length= my_mbcharlen(lci, chr); |
33 | - /* |
34 | - my_mbcharlen can return 0 on a wrong multibyte |
35 | - sequence. It is possible when upgrading from 4.0, |
36 | - and identifier contains some accented characters. |
37 | - The manual says it does not work. So we'll just |
38 | - change length to 1 not to hang in the endless loop. |
39 | - */ |
40 | - if (!length) |
41 | - length= 1; |
42 | - if (length == 1 && chr == (uchar) q && |
43 | - append(&q, 1, lci)) |
44 | - return true; |
45 | - if (append(name, length, lci)) |
46 | - return true; |
47 | - } |
48 | - return append(&q, 1, lci); |
49 | -} |
50 | - |
51 | - |
52 | uint32 String::numchars() const |
53 | { |
54 | return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length); |
55 | |
56 | === modified file 'client/sql_string.h' |
57 | --- client/sql_string.h 2013-08-14 03:57:21 +0000 |
58 | +++ client/sql_string.h 2014-07-31 14:56:03 +0000 |
59 | @@ -21,12 +21,6 @@ |
60 | #include "m_ctype.h" |
61 | #include "my_sys.h" |
62 | |
63 | -#define QUOTED_IDENTIFIER(str_name, buf_size, q, cs, id_name, id_size) \ |
64 | - char buf_##str_name[(buf_size)]; \ |
65 | - String str_name((buf_##str_name), (buf_size), (cs)); \ |
66 | - str_name.length(0); \ |
67 | - str_name.append_identifier((id_name), (id_size), (cs), (q)); |
68 | - |
69 | class String; |
70 | int sortcmp(const String *a,const String *b, const CHARSET_INFO *cs); |
71 | String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); |
72 | @@ -263,10 +257,6 @@ |
73 | bool append(IO_CACHE* file, uint32 arg_length); |
74 | bool append_with_prefill(const char *s, uint32 arg_length, |
75 | uint32 full_length, char fill_char); |
76 | - bool append_identifier(const char *name, |
77 | - uint length, |
78 | - const CHARSET_INFO *ci, |
79 | - int quote_char); |
80 | int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 |
81 | int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 |
82 | bool replace(uint32 offset,uint32 arg_length,const char *to,uint32 length); |
83 | |
84 | === modified file 'mysql-test/suite/rpl/r/rpl_mdev382.result' |
85 | --- mysql-test/suite/rpl/r/rpl_mdev382.result 2014-07-28 15:17:28 +0000 |
86 | +++ mysql-test/suite/rpl/r/rpl_mdev382.result 2014-07-31 14:56:03 +0000 |
87 | @@ -318,9 +318,7 @@ |
88 | # The DELETE statement should be correctly quoted |
89 | include/show_binlog_events.inc |
90 | Log_name Pos Event_type Server_id End_log_pos Info |
91 | -master-bin.000002 # Query # # BEGIN |
92 | master-bin.000002 # Query # # use `test`; DELETE FROM `db1``; select 'oops!'`.`t``1` |
93 | -master-bin.000002 # Query # # COMMIT |
94 | include/start_slave.inc |
95 | # The table should be empty on the slave also. |
96 | SELECT * FROM `db1``; select 'oops!'`.`t``1`; |
97 | |
98 | === modified file 'sql/binlog.cc' |
99 | --- sql/binlog.cc 2014-07-28 12:15:33 +0000 |
100 | +++ sql/binlog.cc 2014-07-31 14:56:03 +0000 |
101 | @@ -1836,10 +1836,11 @@ |
102 | int error= 1; |
103 | |
104 | String log_query; |
105 | - if (log_query.append(STRING_WITH_LEN("SAVEPOINT ")) || |
106 | - append_identifier(thd, &log_query, thd->lex->ident.str, |
107 | - thd->lex->ident.length)) |
108 | + if (log_query.append(STRING_WITH_LEN("SAVEPOINT "))) |
109 | DBUG_RETURN(error); |
110 | + else |
111 | + append_identifier(thd, &log_query, thd->lex->ident.str, |
112 | + thd->lex->ident.length); |
113 | |
114 | int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); |
115 | Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(), |
116 | @@ -1879,8 +1880,9 @@ |
117 | { |
118 | String log_query; |
119 | if (log_query.append(STRING_WITH_LEN("ROLLBACK TO ")) || |
120 | - append_identifier(thd, &log_query, thd->lex->ident.str, |
121 | - thd->lex->ident.length)) |
122 | + log_query.append("`") || |
123 | + log_query.append(thd->lex->ident.str, thd->lex->ident.length) || |
124 | + log_query.append("`")) |
125 | DBUG_RETURN(1); |
126 | int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); |
127 | Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(), |
128 | @@ -2449,7 +2451,7 @@ |
129 | description_event->checksum_alg= ev->checksum_alg; |
130 | |
131 | if (event_count >= limit_start && |
132 | - ev->net_send(thd, protocol, linfo.log_file_name, pos)) |
133 | + ev->net_send(protocol, linfo.log_file_name, pos)) |
134 | { |
135 | errmsg = "Net error"; |
136 | delete ev; |
137 | |
138 | === modified file 'sql/ha_ndbcluster_binlog.cc' |
139 | --- sql/ha_ndbcluster_binlog.cc 2013-12-16 08:45:31 +0000 |
140 | +++ sql/ha_ndbcluster_binlog.cc 2014-07-31 14:56:03 +0000 |
141 | @@ -1828,9 +1828,12 @@ |
142 | DBUG_RETURN(0); |
143 | } |
144 | |
145 | - char tmp_buf2_mem[FN_REFLEN]; |
146 | - String tmp_buf2(tmp_buf2_mem, sizeof(tmp_buf2_mem), system_charset_info); |
147 | - tmp_buf2.length(0); |
148 | + char tmp_buf2[FN_REFLEN]; |
149 | + char quoted_table1[2 + 2 * FN_REFLEN + 1]; |
150 | + char quoted_db1[2 + 2 * FN_REFLEN + 1]; |
151 | + char quoted_db2[2 + 2 * FN_REFLEN + 1]; |
152 | + char quoted_table2[2 + 2 * FN_REFLEN + 1]; |
153 | + int id_length= 0; |
154 | const char *type_str; |
155 | int also_internal= 0; |
156 | uint32 log_type= (uint32)type; |
157 | @@ -1841,10 +1844,15 @@ |
158 | if (thd->lex->sql_command == SQLCOM_DROP_DB) |
159 | DBUG_RETURN(0); |
160 | /* redo the drop table query as is may contain several tables */ |
161 | - tmp_buf2.append(STRING_WITH_LEN("drop table ")); |
162 | - append_identifier(thd, &tmp_buf2, table_name, strlen(table_name)); |
163 | - query= tmp_buf2.c_ptr_safe(); |
164 | - query_length= tmp_buf2.length(); |
165 | + query= tmp_buf2; |
166 | + id_length= my_strmov_quoted_identifier (thd, (char *) quoted_table1, |
167 | + table_name, 0); |
168 | + quoted_table1[id_length]= '\0'; |
169 | + id_length= my_strmov_quoted_identifier (thd, (char *) quoted_db1, |
170 | + db, 0); |
171 | + quoted_db1[id_length]= '\0'; |
172 | + query_length= (uint) (strxmov(tmp_buf2, "drop table ", quoted_db1, ".", |
173 | + quoted_table1, NullS) - tmp_buf2); |
174 | type_str= "drop table"; |
175 | break; |
176 | case SOT_RENAME_TABLE_PREPARE: |
177 | @@ -1853,16 +1861,22 @@ |
178 | break; |
179 | case SOT_RENAME_TABLE: |
180 | /* redo the rename table query as is may contain several tables */ |
181 | - tmp_buf2.append(STRING_WITH_LEN("rename table ")); |
182 | - append_identifier(thd, &tmp_buf2, db, strlen(db)); |
183 | - tmp_buf2.append(STRING_WITH_LEN(".")); |
184 | - append_identifier(thd, &tmp_buf2, table_name, strlen(table_name)); |
185 | - tmp_buf2.append(STRING_WITH_LEN(" to ")); |
186 | - append_identifier(thd, &tmp_buf2, new_db, strlen(new_db)); |
187 | - tmp_buf2.append(STRING_WITH_LEN(".")); |
188 | - append_identifier(thd, &tmp_buf2, new_table_name, strlen(new_table_name)); |
189 | - query= tmp_buf2.c_ptr_safe(); |
190 | - query_length= tmp_buf2.length(); |
191 | + query= tmp_buf2; |
192 | + id_length= my_strmov_quoted_identifier (thd, (char *) quoted_db1, |
193 | + db, 0); |
194 | + quoted_db1[id_length]= '\0'; |
195 | + id_length= my_strmov_quoted_identifier (thd, (char *) quoted_table1, |
196 | + table_name, 0); |
197 | + quoted_table1[id_length]= '\0'; |
198 | + id_length= my_strmov_quoted_identifier (thd, (char *) quoted_db2, |
199 | + new_db, 0); |
200 | + quoted_db2[id_length]= '\0'; |
201 | + id_length= my_strmov_quoted_identifier (thd, (char *) quoted_table2, |
202 | + new_table_name, 0); |
203 | + quoted_table2[id_length]= '\0'; |
204 | + query_length= (uint) (strxmov(tmp_buf2, "rename table ", |
205 | + quoted_db1, ".", quoted_table1, " to ", |
206 | + quoted_db2, ".", quoted_table2, NullS) - tmp_buf2); |
207 | type_str= "rename table"; |
208 | break; |
209 | case SOT_CREATE_TABLE: |
210 | |
211 | === modified file 'sql/item.cc' |
212 | --- sql/item.cc 2014-06-11 13:33:46 +0000 |
213 | +++ sql/item.cc 2014-07-31 14:56:03 +0000 |
214 | @@ -1013,22 +1013,6 @@ |
215 | } |
216 | } |
217 | |
218 | -void Item_name_string::copy_no_truncate(const char *str, size_t length, |
219 | - const CHARSET_INFO *cs) |
220 | -{ |
221 | - if (!my_charset_same(cs, system_charset_info)) |
222 | - { |
223 | - size_t res_length; |
224 | - char *tmp= sql_strmake_with_convert(str, length, cs, UINT_MAX, |
225 | - system_charset_info, &res_length); |
226 | - set(tmp, tmp ? res_length : 0); |
227 | - } |
228 | - else |
229 | - { |
230 | - char *tmp= sql_strmake(str, length); |
231 | - set(tmp, tmp ? length : 0); |
232 | - } |
233 | -} |
234 | |
235 | void Item_name_string::copy(const char *str_arg, size_t length_arg, |
236 | const CHARSET_INFO *cs_arg, |
237 | |
238 | === modified file 'sql/item.h' |
239 | --- sql/item.h 2014-06-04 14:48:06 +0000 |
240 | +++ sql/item.h 2014-07-31 14:56:03 +0000 |
241 | @@ -190,7 +190,6 @@ |
242 | Allocate space using sql_strmake() or sql_strmake_with_convert(). |
243 | */ |
244 | void copy(const char *str, size_t length, const CHARSET_INFO *cs); |
245 | - |
246 | /** |
247 | Variants for copy(), for various argument combinations. |
248 | */ |
249 | @@ -279,9 +278,6 @@ |
250 | */ |
251 | void copy(const char *str_arg, size_t length_arg, const CHARSET_INFO *cs_arg, |
252 | bool is_autogenerated_arg); |
253 | - |
254 | - void copy_no_truncate(const char *str, size_t length, |
255 | - const CHARSET_INFO *cs); |
256 | }; |
257 | |
258 | |
259 | |
260 | === modified file 'sql/item_func.cc' |
261 | --- sql/item_func.cc 2014-06-11 13:33:46 +0000 |
262 | +++ sql/item_func.cc 2014-07-31 14:56:03 +0000 |
263 | @@ -5747,10 +5747,10 @@ |
264 | } |
265 | |
266 | |
267 | -void Item_user_var_as_out_param::print_for_load(THD *thd, String *str) |
268 | +void Item_user_var_as_out_param::print(String *str, enum_query_type query_type) |
269 | { |
270 | str->append('@'); |
271 | - append_identifier(thd, str, name.ptr(), name.length()); |
272 | + append_identifier(current_thd, str, name); |
273 | } |
274 | |
275 | |
276 | |
277 | === modified file 'sql/item_func.h' |
278 | --- sql/item_func.h 2014-06-11 13:33:46 +0000 |
279 | +++ sql/item_func.h 2014-07-31 14:56:03 +0000 |
280 | @@ -1796,7 +1796,7 @@ |
281 | |
282 | /* fix_fields() binds variable name with its entry structure */ |
283 | bool fix_fields(THD *thd, Item **ref); |
284 | - virtual void print_for_load(THD *thd, String *str); |
285 | + virtual void print(String *str, enum_query_type query_type); |
286 | void set_null_value(const CHARSET_INFO* cs); |
287 | void set_value(const char *str, uint length, const CHARSET_INFO* cs); |
288 | }; |
289 | |
290 | === modified file 'sql/log_event.cc' |
291 | --- sql/log_event.cc 2014-06-04 14:48:06 +0000 |
292 | +++ sql/log_event.cc 2014-07-31 14:56:03 +0000 |
293 | @@ -18,7 +18,6 @@ |
294 | #ifdef MYSQL_CLIENT |
295 | |
296 | #include "sql_priv.h" |
297 | -#include "../client/sql_string.h" |
298 | #include "mysqld_error.h" |
299 | |
300 | #else |
301 | @@ -27,7 +26,6 @@ |
302 | #include "sql_priv.h" |
303 | #include "unireg.h" |
304 | #include "my_global.h" // REQUIRED by log_event.h > m_string.h > my_bitmap.h |
305 | -#include "sql_string.h" |
306 | #include "log_event.h" |
307 | #include "sql_base.h" // close_thread_tables |
308 | #include "sql_cache.h" // QUERY_CACHE_FLAGS_SIZE |
309 | @@ -427,28 +425,29 @@ |
310 | pretty_print_str() |
311 | */ |
312 | |
313 | -static void |
314 | -pretty_print_str(String *packet, const char *str, int len) |
315 | +static char *pretty_print_str(char *packet, const char *str, int len) |
316 | { |
317 | const char *end= str + len; |
318 | - packet->append(STRING_WITH_LEN("'")); |
319 | + char *pos= packet; |
320 | + *pos++= '\''; |
321 | while (str < end) |
322 | { |
323 | char c; |
324 | switch ((c=*str++)) { |
325 | - case '\n': packet->append(STRING_WITH_LEN("\\n")); break; |
326 | - case '\r': packet->append(STRING_WITH_LEN("\\r")); break; |
327 | - case '\\': packet->append(STRING_WITH_LEN("\\\\")); break; |
328 | - case '\b': packet->append(STRING_WITH_LEN("\\b")); break; |
329 | - case '\t': packet->append(STRING_WITH_LEN("\\t")); break; |
330 | - case '\'': packet->append(STRING_WITH_LEN("\\'")); break; |
331 | - case 0 : packet->append(STRING_WITH_LEN("\\0")); break; |
332 | + case '\n': *pos++= '\\'; *pos++= 'n'; break; |
333 | + case '\r': *pos++= '\\'; *pos++= 'r'; break; |
334 | + case '\\': *pos++= '\\'; *pos++= '\\'; break; |
335 | + case '\b': *pos++= '\\'; *pos++= 'b'; break; |
336 | + case '\t': *pos++= '\\'; *pos++= 't'; break; |
337 | + case '\'': *pos++= '\\'; *pos++= '\''; break; |
338 | + case 0 : *pos++= '\\'; *pos++= '0'; break; |
339 | default: |
340 | - packet->append(&c, 1); |
341 | + *pos++= c; |
342 | break; |
343 | } |
344 | } |
345 | - packet->append(STRING_WITH_LEN("'")); |
346 | + *pos++= '\''; |
347 | + return pos; |
348 | } |
349 | #endif /* !MYSQL_CLIENT */ |
350 | |
351 | @@ -897,7 +896,7 @@ |
352 | Log_event::pack_info() |
353 | */ |
354 | |
355 | -int Log_event::pack_info(THD* thd, Protocol *protocol) |
356 | +int Log_event::pack_info(Protocol *protocol) |
357 | { |
358 | protocol->store("", &my_charset_bin); |
359 | return 0; |
360 | @@ -907,8 +906,7 @@ |
361 | /** |
362 | Only called by SHOW BINLOG EVENTS |
363 | */ |
364 | -int Log_event::net_send(THD *thd, Protocol *protocol, const char* log_name, |
365 | - my_off_t pos) |
366 | +int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos) |
367 | { |
368 | const char *p= strrchr(log_name, FN_LIBCHAR); |
369 | const char *event_type; |
370 | @@ -922,7 +920,7 @@ |
371 | protocol->store(event_type, strlen(event_type), &my_charset_bin); |
372 | protocol->store((uint32) server_id); |
373 | protocol->store((ulonglong) log_pos); |
374 | - if (pack_info(thd, protocol)) |
375 | + if (pack_info(protocol)) |
376 | return 1; |
377 | return protocol->write(); |
378 | } |
379 | @@ -3178,25 +3176,23 @@ |
380 | show the catalog ?? |
381 | */ |
382 | |
383 | -int Query_log_event::pack_info(THD* thd, Protocol *protocol) |
384 | +int Query_log_event::pack_info(Protocol *protocol) |
385 | { |
386 | // TODO: show the catalog ?? |
387 | - char temp_buf_mem[1024]; |
388 | - String temp_buf(temp_buf_mem, sizeof(temp_buf_mem), system_charset_info); |
389 | - temp_buf.real_alloc(9 + db_len + q_len); |
390 | + String temp_buf; |
391 | // Add use `DB` to the string if required |
392 | if (!(flags & LOG_EVENT_SUPPRESS_USE_F) |
393 | && db && db_len) |
394 | { |
395 | - temp_buf.append(STRING_WITH_LEN("use ")); |
396 | - append_identifier(thd, &temp_buf, db, db_len); |
397 | + temp_buf.append("use "); |
398 | + append_identifier(this->thd, &temp_buf, db, db_len); |
399 | temp_buf.append("; "); |
400 | } |
401 | // Add the query to the string |
402 | if (query && q_len) |
403 | - temp_buf.append(query, q_len); |
404 | - // persist the buffer in protocol |
405 | - protocol->store(&temp_buf); |
406 | + temp_buf.append(query); |
407 | + // persist the buffer in protocol |
408 | + protocol->store(temp_buf.ptr(), temp_buf.length(), &my_charset_bin); |
409 | return 0; |
410 | } |
411 | #endif |
412 | @@ -4269,19 +4265,7 @@ |
413 | if (different_db) |
414 | memcpy(print_event_info->db, db, db_len + 1); |
415 | if (db[0] && different_db) |
416 | - { |
417 | - QUOTED_IDENTIFIER(q_db, |
418 | - /* Room for expand ` to `` + initial/final ` + \0 */ |
419 | - FN_REFLEN*2+3, |
420 | - '`', |
421 | - &my_charset_bin, |
422 | - db, |
423 | - db_len); |
424 | - my_b_printf(file, |
425 | - "use %s%s\n", |
426 | - q_db.c_ptr(), |
427 | - print_event_info->delimiter); |
428 | - } |
429 | + my_b_printf(file, "use %s%s\n", quoted_id, print_event_info->delimiter); |
430 | } |
431 | |
432 | end=int10_to_str((long) when.tv_sec, strmov(buff,"SET TIMESTAMP="),10); |
433 | @@ -5156,7 +5140,7 @@ |
434 | */ |
435 | |
436 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
437 | -int Start_log_event_v3::pack_info(THD* thd, Protocol *protocol) |
438 | +int Start_log_event_v3::pack_info(Protocol *protocol) |
439 | { |
440 | char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos; |
441 | pos= strmov(buf, "Server ver: "); |
442 | @@ -5906,110 +5890,142 @@ |
443 | **************************************************************************/ |
444 | |
445 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
446 | -void Load_log_event::print_query(THD* thd, bool need_db, const char *cs, |
447 | - String *buf, my_off_t *fn_start, |
448 | - my_off_t *fn_end, const char *qualify_db) |
449 | -{ |
450 | +uint Load_log_event::get_query_buffer_length() |
451 | +{ |
452 | + return |
453 | + //the DB name may double if we escape the quote character |
454 | + 5 + 2*db_len + 3 + |
455 | + // Likewise for the fname |
456 | + 18 + 2 * fname_len + 2 + // "LOAD DATA INFILE 'file''" |
457 | + 11 + // "CONCURRENT " |
458 | + 7 + // LOCAL |
459 | + 9 + // " REPLACE or IGNORE " |
460 | + 13 + table_name_len*2 + // "INTO TABLE `table`" |
461 | + 21 + sql_ex.field_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'" |
462 | + 23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'" |
463 | + 12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'" |
464 | + 21 + sql_ex.line_term_len*4 + 2 + // " LINES TERMINATED BY 'str'" |
465 | + 19 + sql_ex.line_start_len*4 + 2 + // " LINES STARTING BY 'str'" |
466 | + 15 + 22 + // " IGNORE xxx LINES" |
467 | + 3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)" |
468 | +} |
469 | + |
470 | + |
471 | +void Load_log_event::print_query(bool need_db, const char *cs, char *buf, |
472 | + char **end, char **fn_start, char **fn_end) |
473 | +{ |
474 | + char quoted_id[1 + NAME_LEN * 2 + 2];//quoted length |
475 | + int quoted_id_len= 0; |
476 | + char *pos= buf; |
477 | + |
478 | if (need_db && db && db_len) |
479 | { |
480 | - buf->append(STRING_WITH_LEN("use ")); |
481 | - append_identifier(thd, buf, db, db_len); |
482 | - buf->append(STRING_WITH_LEN("; ")); |
483 | + pos= strmov(pos, "use "); |
484 | +#ifdef MYSQL_SERVER |
485 | + quoted_id_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_id, |
486 | + db, 0); |
487 | +#else |
488 | + quoted_id_len= my_strmov_quoted_identifier((char *) quoted_id, db); |
489 | +#endif |
490 | + quoted_id[quoted_id_len]= '\0'; |
491 | + pos= strmov(pos, quoted_id); |
492 | + pos= strmov(pos, "; "); |
493 | } |
494 | |
495 | - buf->append(STRING_WITH_LEN("LOAD DATA ")); |
496 | + pos= strmov(pos, "LOAD DATA "); |
497 | |
498 | if (is_concurrent) |
499 | - buf->append(STRING_WITH_LEN("CONCURRENT ")); |
500 | + pos= strmov(pos, "CONCURRENT "); |
501 | |
502 | if (fn_start) |
503 | - *fn_start= buf->length(); |
504 | + *fn_start= pos; |
505 | |
506 | if (check_fname_outside_temp_buf()) |
507 | - buf->append(STRING_WITH_LEN("LOCAL ")); |
508 | - buf->append(STRING_WITH_LEN("INFILE '")); |
509 | - buf->append_for_single_quote(fname, fname_len); |
510 | - buf->append(STRING_WITH_LEN("' ")); |
511 | + pos= strmov(pos, "LOCAL "); |
512 | + pos= strmov(pos, "INFILE '"); |
513 | + String quoted_fname; |
514 | + String(fname, fname_len, NULL).print("ed_fname); |
515 | + memcpy(pos, quoted_fname.ptr(), quoted_fname.length()); |
516 | + pos= strmov(pos + quoted_fname.length(), "' "); |
517 | |
518 | if (sql_ex.opt_flags & REPLACE_FLAG) |
519 | - buf->append(STRING_WITH_LEN("REPLACE ")); |
520 | + pos= strmov(pos, "REPLACE "); |
521 | else if (sql_ex.opt_flags & IGNORE_FLAG) |
522 | - buf->append(STRING_WITH_LEN("IGNORE ")); |
523 | + pos= strmov(pos, "IGNORE "); |
524 | |
525 | - buf->append(STRING_WITH_LEN("INTO")); |
526 | + pos= strmov(pos ,"INTO"); |
527 | |
528 | if (fn_end) |
529 | - *fn_end= buf->length(); |
530 | + *fn_end= pos; |
531 | |
532 | - buf->append(STRING_WITH_LEN(" TABLE ")); |
533 | - buf->append(table_name, table_name_len); |
534 | + pos= strmov(pos ," TABLE "); |
535 | + memcpy(pos, table_name, table_name_len); |
536 | + pos+= table_name_len; |
537 | |
538 | if (cs != NULL) |
539 | { |
540 | - buf->append(STRING_WITH_LEN(" CHARACTER SET ")); |
541 | - buf->append(cs, strlen(cs)); |
542 | + pos= strmov(pos ," CHARACTER SET "); |
543 | + pos= strmov(pos , cs); |
544 | } |
545 | |
546 | /* We have to create all optional fields as the default is not empty */ |
547 | - buf->append(STRING_WITH_LEN(" FIELDS TERMINATED BY ")); |
548 | - pretty_print_str(buf, sql_ex.field_term, sql_ex.field_term_len); |
549 | + pos= strmov(pos, " FIELDS TERMINATED BY "); |
550 | + pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len); |
551 | if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG) |
552 | - buf->append(STRING_WITH_LEN(" OPTIONALLY ")); |
553 | - buf->append(STRING_WITH_LEN(" ENCLOSED BY ")); |
554 | - pretty_print_str(buf, sql_ex.enclosed, sql_ex.enclosed_len); |
555 | - |
556 | - buf->append(STRING_WITH_LEN(" ESCAPED BY ")); |
557 | - pretty_print_str(buf, sql_ex.escaped, sql_ex.escaped_len); |
558 | - |
559 | - buf->append(STRING_WITH_LEN(" LINES TERMINATED BY ")); |
560 | - pretty_print_str(buf, sql_ex.line_term, sql_ex.line_term_len); |
561 | + pos= strmov(pos, " OPTIONALLY "); |
562 | + pos= strmov(pos, " ENCLOSED BY "); |
563 | + pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len); |
564 | + |
565 | + pos= strmov(pos, " ESCAPED BY "); |
566 | + pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len); |
567 | + |
568 | + pos= strmov(pos, " LINES TERMINATED BY "); |
569 | + pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len); |
570 | if (sql_ex.line_start_len) |
571 | { |
572 | - buf->append(STRING_WITH_LEN(" STARTING BY ")); |
573 | - pretty_print_str(buf, sql_ex.line_start, sql_ex.line_start_len); |
574 | + pos= strmov(pos, " STARTING BY "); |
575 | + pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len); |
576 | } |
577 | |
578 | if ((long) skip_lines > 0) |
579 | { |
580 | - char skipbuf[22]; |
581 | - buf->append(STRING_WITH_LEN(" IGNORE ")); |
582 | - longlong10_to_str((longlong) skip_lines, skipbuf, 10); |
583 | - buf->append(skipbuf); |
584 | - buf->append(STRING_WITH_LEN(" LINES ")); |
585 | + pos= strmov(pos, " IGNORE "); |
586 | + pos= longlong10_to_str((longlong) skip_lines, pos, 10); |
587 | + pos= strmov(pos," LINES "); |
588 | } |
589 | |
590 | if (num_fields) |
591 | { |
592 | uint i; |
593 | const char *field= fields; |
594 | - buf->append(STRING_WITH_LEN(" (")); |
595 | + pos= strmov(pos, " ("); |
596 | for (i = 0; i < num_fields; i++) |
597 | { |
598 | if (i) |
599 | { |
600 | - /* |
601 | - Yes, the space and comma is reversed here. But this is mostly dead |
602 | - code, at most used when reading really old binlogs from old servers, |
603 | - so better just leave it as is... |
604 | - */ |
605 | - buf->append(STRING_WITH_LEN(" ,")); |
606 | + *pos++= ' '; |
607 | + *pos++= ','; |
608 | } |
609 | - append_identifier(thd, buf, field, field_lens[i]); |
610 | - field+= field_lens[i] + 1; |
611 | + quoted_id_len= my_strmov_quoted_identifier(this->thd, quoted_id, field, |
612 | + 0); |
613 | + memcpy(pos, quoted_id, quoted_id_len-1); |
614 | } |
615 | - buf->append(STRING_WITH_LEN(")")); |
616 | + *pos++= ')'; |
617 | } |
618 | + |
619 | + *end= pos; |
620 | } |
621 | |
622 | |
623 | -int Load_log_event::pack_info(THD *thd, Protocol *protocol) |
624 | +int Load_log_event::pack_info(Protocol *protocol) |
625 | { |
626 | - char query_buffer[1024]; |
627 | - String query_str(query_buffer, sizeof(query_buffer), system_charset_info); |
628 | + char *buf, *end; |
629 | |
630 | - query_str.length(0); |
631 | - print_query(thd, TRUE, NULL, &query_str, 0, 0, NULL); |
632 | - protocol->store(query_str.ptr(), query_str.length(), &my_charset_bin); |
633 | + if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME)))) |
634 | + return 1; |
635 | + print_query(TRUE, NULL, buf, &end, 0, 0); |
636 | + protocol->store(buf, end-buf, &my_charset_bin); |
637 | + my_free(buf); |
638 | return 0; |
639 | } |
640 | #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */ |
641 | @@ -6314,14 +6330,15 @@ |
642 | my_b_printf(head,"REPLACE "); |
643 | else if (sql_ex.opt_flags & IGNORE_FLAG) |
644 | my_b_printf(head,"IGNORE "); |
645 | - |
646 | - QUOTED_IDENTIFIER(quoted_table_name, |
647 | - 512, |
648 | - '`', |
649 | - &my_charset_bin, |
650 | - table_name, |
651 | - strlen(table_name)); |
652 | - my_b_printf(head, "INTO TABLE %s", quoted_table_name.c_ptr()); |
653 | + |
654 | +#ifdef MYSQL_SERVER |
655 | + id_len= my_strmov_quoted_identifier(this->thd, temp_buf, table_name, 0); |
656 | +#else |
657 | + id_len= my_strmov_quoted_identifier(temp_buf, table_name); |
658 | +#endif |
659 | + temp_buf[id_len]= '\0'; |
660 | + my_b_printf(head, "INTO TABLE %s", temp_buf); |
661 | + |
662 | my_b_printf(head, " FIELDS TERMINATED BY "); |
663 | pretty_print_str(head, sql_ex.field_term, sql_ex.field_term_len); |
664 | |
665 | @@ -6505,21 +6522,16 @@ |
666 | else |
667 | { |
668 | char llbuff[22]; |
669 | + char *end; |
670 | enum enum_duplicates handle_dup; |
671 | bool ignore= 0; |
672 | char *load_data_query; |
673 | - char query_buffer[1024]; |
674 | - String query_str(query_buffer, sizeof(query_buffer), system_charset_info); |
675 | - query_str.length(0); |
676 | |
677 | - print_query(thd, FALSE, NULL, &query_str, NULL, NULL, NULL); |
678 | /* |
679 | Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST |
680 | and written to slave's binlog if binlogging is on. |
681 | */ |
682 | - if (!(load_data_query= (char *) thd->strmake(query_str.ptr(), |
683 | - query_str.length() + |
684 | - sizeof(size_t)))) |
685 | + if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1))) |
686 | { |
687 | /* |
688 | This will set thd->fatal_error in case of OOM. So we surely will notice |
689 | @@ -6528,11 +6540,9 @@ |
690 | goto error; |
691 | } |
692 | |
693 | - memcpy(load_data_query + query_str.length() + 1, |
694 | - (char *) &thd->db_length, |
695 | - sizeof(size_t)); |
696 | - |
697 | - thd->set_query(load_data_query, query_str.length()); |
698 | + print_query(FALSE, NULL, load_data_query, &end, NULL, NULL); |
699 | + *end= 0; |
700 | + thd->set_query(load_data_query, (uint) (end - load_data_query)); |
701 | |
702 | if (sql_ex.opt_flags & REPLACE_FLAG) |
703 | handle_dup= DUP_REPLACE; |
704 | @@ -6720,7 +6730,7 @@ |
705 | */ |
706 | |
707 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
708 | -int Rotate_log_event::pack_info(THD *thd, Protocol *protocol) |
709 | +int Rotate_log_event::pack_info(Protocol *protocol) |
710 | { |
711 | char buf1[256], buf[22]; |
712 | String tmp(buf1, sizeof(buf1), log_cs); |
713 | @@ -6991,7 +7001,7 @@ |
714 | */ |
715 | |
716 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
717 | -int Intvar_log_event::pack_info(THD *thd, Protocol *protocol) |
718 | +int Intvar_log_event::pack_info(Protocol *protocol) |
719 | { |
720 | char buf[256], *pos; |
721 | pos= strmake(buf, get_var_type_name(), sizeof(buf)-23); |
722 | @@ -7144,7 +7154,7 @@ |
723 | **************************************************************************/ |
724 | |
725 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
726 | -int Rand_log_event::pack_info(THD *thd, Protocol *protocol) |
727 | +int Rand_log_event::pack_info(Protocol *protocol) |
728 | { |
729 | char buf1[256], *pos; |
730 | pos= strmov(buf1,"rand_seed1="); |
731 | @@ -7269,7 +7279,7 @@ |
732 | **************************************************************************/ |
733 | |
734 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
735 | -int Xid_log_event::pack_info(THD *thd, Protocol *protocol) |
736 | +int Xid_log_event::pack_info(Protocol *protocol) |
737 | { |
738 | char buf[128], *pos; |
739 | pos= strmov(buf, "COMMIT /* xid="); |
740 | @@ -7510,122 +7520,85 @@ |
741 | **************************************************************************/ |
742 | |
743 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
744 | -static bool |
745 | -user_var_append_name_part(THD *thd, String *buf, |
746 | - const char *name, size_t name_len) |
747 | +int User_var_log_event::pack_info(Protocol* protocol) |
748 | { |
749 | - return buf->append("@") || |
750 | - append_identifier(thd, buf, name, name_len) || |
751 | - buf->append("="); |
752 | -} |
753 | + char *buf= 0; |
754 | + char quoted_id[1 + FN_REFLEN * 2 + 2];// quoted identifier |
755 | + int id_len= my_strmov_quoted_identifier(this->thd, quoted_id, name, name_len); |
756 | + quoted_id[id_len]= '\0'; |
757 | + uint val_offset= 2 + id_len; |
758 | + uint event_len= val_offset; |
759 | |
760 | -int User_var_log_event::pack_info(THD *thd, Protocol* protocol) |
761 | -{ |
762 | if (is_null) |
763 | { |
764 | - char buf_mem[FN_REFLEN+7]; |
765 | - String buf(buf_mem, sizeof(buf_mem), system_charset_info); |
766 | - buf.length(0); |
767 | - if (user_var_append_name_part(thd, &buf, name, name_len) || |
768 | - buf.append("NULL")) |
769 | + if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME)))) |
770 | return 1; |
771 | - protocol->store(buf.ptr(), buf.length(), &my_charset_bin); |
772 | + strmov(buf + val_offset, "NULL"); |
773 | + event_len= val_offset + 4; |
774 | } |
775 | else |
776 | { |
777 | switch (type) { |
778 | case REAL_RESULT: |
779 | - { |
780 | double real_val; |
781 | - char buf2[MY_GCVT_MAX_FIELD_WIDTH + 1]; |
782 | - char buf_mem[FN_REFLEN + MY_GCVT_MAX_FIELD_WIDTH + 1]; |
783 | - String buf(buf_mem, sizeof(buf_mem), system_charset_info); |
784 | float8get(real_val, val); |
785 | - my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH, |
786 | - buf2, NULL); |
787 | - buf.length(0); |
788 | - if (user_var_append_name_part(thd, &buf, name, name_len) || |
789 | - buf.append(buf2)) |
790 | - return 1; |
791 | - protocol->store(buf.ptr(), buf.length(), &my_charset_bin); |
792 | + if (!(buf= (char*) my_malloc(val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1, |
793 | + MYF(MY_WME)))) |
794 | + return 1; |
795 | + event_len+= my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH, |
796 | + buf + val_offset, NULL); |
797 | break; |
798 | - } |
799 | case INT_RESULT: |
800 | - { |
801 | - char buf2[22]; |
802 | - char buf_mem[FN_REFLEN + 22]; |
803 | - String buf(buf_mem, sizeof(buf_mem), system_charset_info); |
804 | - buf.length(0); |
805 | - if (user_var_append_name_part(thd, &buf, name, name_len) || |
806 | - buf.append(buf2, |
807 | - longlong10_to_str(uint8korr(val), |
808 | - buf2, |
809 | - (flags & |
810 | - User_var_log_event::UNSIGNED_F) ? |
811 | - 10 : -10) |
812 | - -buf2)) |
813 | + if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME)))) |
814 | return 1; |
815 | - protocol->store(buf.ptr(), buf.length(), &my_charset_bin); |
816 | + event_len= longlong10_to_str(uint8korr(val), buf + val_offset, |
817 | + ((flags & User_var_log_event::UNSIGNED_F) ? |
818 | + 10 : -10))-buf; |
819 | break; |
820 | - } |
821 | case DECIMAL_RESULT: |
822 | { |
823 | - char buf_mem[FN_REFLEN + DECIMAL_MAX_STR_LENGTH]; |
824 | - String buf(buf_mem, sizeof(buf_mem), system_charset_info); |
825 | - char buf2[DECIMAL_MAX_STR_LENGTH+1]; |
826 | - String str(buf2, sizeof(buf2), &my_charset_bin); |
827 | + if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH + 1, |
828 | + MYF(MY_WME)))) |
829 | + return 1; |
830 | + String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH + 1, &my_charset_bin); |
831 | my_decimal dec; |
832 | - buf.length(0); |
833 | binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0], |
834 | val[1]); |
835 | my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str); |
836 | - if (user_var_append_name_part(thd, &buf, name, name_len) || |
837 | - buf.append(buf2)) |
838 | - return 1; |
839 | - protocol->store(buf.ptr(), buf.length(), &my_charset_bin); |
840 | + event_len= str.length() + val_offset; |
841 | break; |
842 | - } |
843 | + } |
844 | case STRING_RESULT: |
845 | - { |
846 | /* 15 is for 'COLLATE' and other chars */ |
847 | - char buf_mem[FN_REFLEN + 512 + 1 + 2*MY_CS_NAME_SIZE+15]; |
848 | - String buf(buf_mem, sizeof(buf_mem), system_charset_info); |
849 | + buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15, |
850 | + MYF(MY_WME)); |
851 | CHARSET_INFO *cs; |
852 | - buf.length(0); |
853 | + if (!buf) |
854 | + return 1; |
855 | if (!(cs= get_charset(charset_number, MYF(0)))) |
856 | { |
857 | - if (buf.append("???")) |
858 | - return 1; |
859 | + strmov(buf+val_offset, "???"); |
860 | + event_len+= 3; |
861 | } |
862 | else |
863 | { |
864 | - size_t old_len; |
865 | - char *beg, *end; |
866 | - if (user_var_append_name_part(thd, &buf, name, name_len) || |
867 | - buf.append("_") || |
868 | - buf.append(cs->csname) || |
869 | - buf.append(" ")) |
870 | - return 1; |
871 | - old_len= buf.length(); |
872 | - if (buf.reserve(old_len + val_len*2 + 2 + sizeof(" COLLATE ") + |
873 | - MY_CS_NAME_SIZE)) |
874 | - return 1; |
875 | - beg= const_cast<char *>(buf.ptr()) + old_len; |
876 | - end= str_to_hex(beg, val, val_len); |
877 | - buf.length(old_len + (end - beg)); |
878 | - if (buf.append(" COLLATE ") || |
879 | - buf.append(cs->name)) |
880 | - return 1; |
881 | + char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS); |
882 | + p= str_to_hex(p, val, val_len); |
883 | + p= strxmov(p, " COLLATE ", cs->name, NullS); |
884 | + event_len= p-buf; |
885 | } |
886 | - protocol->store(buf.ptr(), buf.length(), &my_charset_bin); |
887 | break; |
888 | - } |
889 | case ROW_RESULT: |
890 | default: |
891 | DBUG_ASSERT(1); |
892 | return 1; |
893 | } |
894 | } |
895 | + buf[0]= '@'; |
896 | + memcpy(buf + 1, quoted_id, id_len); |
897 | + buf[1 + id_len]= '='; |
898 | + protocol->store(buf, event_len, &my_charset_bin); |
899 | + my_free(buf); |
900 | return 0; |
901 | } |
902 | #endif /* !MYSQL_CLIENT */ |
903 | @@ -7808,20 +7781,22 @@ |
904 | void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info) |
905 | { |
906 | IO_CACHE *const head= &print_event_info->head_cache; |
907 | + char quoted_id[1 + NAME_LEN * 2 + 2];// quoted length of the identifier |
908 | + char name_id[NAME_LEN]; |
909 | + int quoted_len= 0; |
910 | |
911 | if (!print_event_info->short_form) |
912 | { |
913 | print_header(head, print_event_info, FALSE); |
914 | my_b_printf(head, "\tUser_var\n"); |
915 | } |
916 | - |
917 | - QUOTED_IDENTIFIER(quoted_name, |
918 | - 512, |
919 | - '`', |
920 | - &my_charset_bin, |
921 | - name, |
922 | - name_len); |
923 | - my_b_printf(head, "SET @%s", quoted_name.c_ptr()); |
924 | + strmov(name_id, name); |
925 | + name_id[name_len]= '\0'; |
926 | + my_b_printf(head, "SET @"); |
927 | + quoted_len= my_strmov_quoted_identifier((char *) quoted_id, |
928 | + (const char *) name_id); |
929 | + quoted_id[quoted_len]= '\0'; |
930 | + my_b_write(head, (uchar*) quoted_id, quoted_len); |
931 | |
932 | if (is_null) |
933 | { |
934 | @@ -7896,20 +7871,12 @@ |
935 | */ |
936 | my_b_printf(head, ":=???%s\n", print_event_info->delimiter); |
937 | else |
938 | - { |
939 | - QUOTED_IDENTIFIER(quoted_charset_name, |
940 | - 512, |
941 | - '`', |
942 | - &my_charset_bin, |
943 | - cs->name, |
944 | - strlen(cs->name)); |
945 | - my_b_printf(head, ":=_%s %s COLLATE %s%s\n", |
946 | - cs->csname, hex_str, quoted_charset_name.c_ptr(), |
947 | + my_b_printf(head, ":=_%s %s COLLATE `%s`%s\n", |
948 | + cs->csname, hex_str, cs->name, |
949 | print_event_info->delimiter); |
950 | - } |
951 | - my_afree(hex_str); |
952 | + my_free(hex_str); |
953 | + } |
954 | break; |
955 | - } |
956 | case ROW_RESULT: |
957 | default: |
958 | DBUG_ASSERT(1); |
959 | @@ -8294,7 +8261,7 @@ |
960 | */ |
961 | |
962 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
963 | -int Create_file_log_event::pack_info(THD *thd, Protocol *protocol) |
964 | +int Create_file_log_event::pack_info(Protocol *protocol) |
965 | { |
966 | char buf[NAME_LEN*2 + 30 + 21*2], *pos; |
967 | pos= strmov(buf, "db="); |
968 | @@ -8500,7 +8467,7 @@ |
969 | */ |
970 | |
971 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
972 | -int Append_block_log_event::pack_info(THD *thd, Protocol *protocol) |
973 | +int Append_block_log_event::pack_info(Protocol *protocol) |
974 | { |
975 | char buf[256]; |
976 | size_t length; |
977 | @@ -8660,7 +8627,7 @@ |
978 | */ |
979 | |
980 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
981 | -int Delete_file_log_event::pack_info(THD *thd, Protocol *protocol) |
982 | +int Delete_file_log_event::pack_info(Protocol *protocol) |
983 | { |
984 | char buf[64]; |
985 | size_t length; |
986 | @@ -8764,7 +8731,7 @@ |
987 | */ |
988 | |
989 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
990 | -int Execute_load_log_event::pack_info(THD *thd, Protocol *protocol) |
991 | +int Execute_load_log_event::pack_info(Protocol *protocol) |
992 | { |
993 | char buf[64]; |
994 | size_t length; |
995 | @@ -9037,26 +9004,36 @@ |
996 | |
997 | |
998 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
999 | -int Execute_load_query_log_event::pack_info(THD *thd, Protocol *protocol) |
1000 | +int Execute_load_query_log_event::pack_info(Protocol *protocol) |
1001 | { |
1002 | - char buf_mem[1024]; |
1003 | - char file_id_buf[22]; |
1004 | - String buf(buf_mem, sizeof(buf_mem), system_charset_info); |
1005 | - buf.real_alloc(9 + db_len + q_len + 10 + 21); |
1006 | + char *buf, *pos; |
1007 | + if (!(buf= (char*) my_malloc(9 + (db_len * 2) + 2 + q_len + 10 + 21, |
1008 | + MYF(MY_WME)))) |
1009 | + return 1; |
1010 | + pos= buf; |
1011 | if (db && db_len) |
1012 | { |
1013 | - if (buf.append("use ") || |
1014 | - append_identifier(thd, &buf, db, db_len) || |
1015 | - buf.append("; ")) |
1016 | - return 1; |
1017 | - } |
1018 | - if (query && q_len && buf.append(query, q_len)) |
1019 | - return 1; |
1020 | - int10_to_str((long) file_id, file_id_buf, 10); |
1021 | - if (buf.append(" ;file_id=") || |
1022 | - buf.append(file_id_buf)) |
1023 | - return 1; |
1024 | - protocol->store(buf.ptr(), buf.length(), &my_charset_bin); |
1025 | + /* |
1026 | + Statically allocates room to store '\0' and an identifier |
1027 | + that may have NAME_LEN * 2 due to quoting and there are |
1028 | + two quoting characters that wrap them. |
1029 | + */ |
1030 | + char quoted_db[1 + NAME_LEN * 2 + 2];// quoted length of the identifier |
1031 | + size_t size= 0; |
1032 | + size= my_strmov_quoted_identifier(this->thd, quoted_db, db, 0); |
1033 | + pos= strmov(buf, "use "); |
1034 | + memcpy(pos, quoted_db, size); |
1035 | + pos= strmov(pos + size, "; "); |
1036 | + } |
1037 | + if (query && q_len) |
1038 | + { |
1039 | + memcpy(pos, query, q_len); |
1040 | + pos+= q_len; |
1041 | + } |
1042 | + pos= strmov(pos, " ;file_id="); |
1043 | + pos= int10_to_str((long) file_id, pos, 10); |
1044 | + protocol->store(buf, pos-buf, &my_charset_bin); |
1045 | + my_free(buf); |
1046 | return 0; |
1047 | } |
1048 | |
1049 | @@ -11661,7 +11638,7 @@ |
1050 | #endif |
1051 | |
1052 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
1053 | -int Rows_log_event::pack_info(THD *thd, Protocol *protocol) |
1054 | +int Rows_log_event::pack_info(Protocol *protocol) |
1055 | { |
1056 | char buf[256]; |
1057 | char const *const flagstr= |
1058 | @@ -12390,7 +12367,7 @@ |
1059 | */ |
1060 | |
1061 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
1062 | -int Table_map_log_event::pack_info(THD *thd, Protocol *protocol) |
1063 | +int Table_map_log_event::pack_info(Protocol *protocol) |
1064 | { |
1065 | char buf[256]; |
1066 | size_t bytes= my_snprintf(buf, sizeof(buf), |
1067 | @@ -12411,21 +12388,9 @@ |
1068 | if (!print_event_info->short_form) |
1069 | { |
1070 | print_header(&print_event_info->head_cache, print_event_info, TRUE); |
1071 | - QUOTED_IDENTIFIER(db_nam, |
1072 | - 512, |
1073 | - '`', |
1074 | - &my_charset_bin, |
1075 | - m_dbnam, |
1076 | - strlen(m_dbnam)); |
1077 | - QUOTED_IDENTIFIER(tbl_nam, |
1078 | - 512, |
1079 | - '`', |
1080 | - &my_charset_bin, |
1081 | - m_tblnam, |
1082 | - strlen(m_tblnam)); |
1083 | my_b_printf(&print_event_info->head_cache, |
1084 | - "\tTable_map: %s.%s mapped to number %llu\n", |
1085 | - db_nam.c_ptr(), tbl_nam.c_ptr(), m_table_id.id()); |
1086 | + "\tTable_map: `%s`.`%s` mapped to number %llu\n", |
1087 | + m_dbnam, m_tblnam, m_table_id.id()); |
1088 | print_base64(&print_event_info->body_cache, print_event_info, TRUE); |
1089 | } |
1090 | } |
1091 | @@ -13231,7 +13196,7 @@ |
1092 | |
1093 | |
1094 | #ifndef MYSQL_CLIENT |
1095 | -int Incident_log_event::pack_info(THD *thd, Protocol *protocol) |
1096 | +int Incident_log_event::pack_info(Protocol *protocol) |
1097 | { |
1098 | char buf[256]; |
1099 | size_t bytes; |
1100 | @@ -13326,7 +13291,7 @@ |
1101 | |
1102 | #ifndef MYSQL_CLIENT |
1103 | /* Pack info for its unrecognized ignorable event */ |
1104 | -int Ignorable_log_event::pack_info(THD *, Protocol *protocol) |
1105 | +int Ignorable_log_event::pack_info(Protocol *protocol) |
1106 | { |
1107 | char buf[256]; |
1108 | size_t bytes; |
1109 | @@ -13385,7 +13350,7 @@ |
1110 | } |
1111 | |
1112 | #ifndef MYSQL_CLIENT |
1113 | -int Rows_query_log_event::pack_info(THD *, Protocol *protocol) |
1114 | +int Rows_query_log_event::pack_info(Protocol *protocol) |
1115 | { |
1116 | char *buf; |
1117 | size_t bytes; |
1118 | @@ -13527,7 +13492,7 @@ |
1119 | #endif |
1120 | |
1121 | #ifndef MYSQL_CLIENT |
1122 | -int Gtid_log_event::pack_info(THD *, Protocol *protocol) |
1123 | +int Gtid_log_event::pack_info(Protocol *protocol) |
1124 | { |
1125 | char buffer[MAX_SET_STRING_LENGTH + 1]; |
1126 | size_t len= to_string(buffer); |
1127 | @@ -13674,7 +13639,7 @@ |
1128 | #endif |
1129 | |
1130 | #ifndef MYSQL_CLIENT |
1131 | -int Previous_gtids_log_event::pack_info(THD *, Protocol *protocol) |
1132 | +int Previous_gtids_log_event::pack_info(Protocol *protocol) |
1133 | { |
1134 | size_t length= 0; |
1135 | global_sid_lock->rdlock(); |
1136 | |
1137 | === modified file 'sql/log_event.h' |
1138 | --- sql/log_event.h 2014-06-04 14:48:06 +0000 |
1139 | +++ sql/log_event.h 2014-07-31 14:56:03 +0000 |
1140 | @@ -1222,8 +1222,7 @@ |
1141 | */ |
1142 | static void init_show_field_list(List<Item>* field_list); |
1143 | #ifdef HAVE_REPLICATION |
1144 | - int net_send(THD *thd, Protocol *protocol, const char* log_name, |
1145 | - my_off_t pos); |
1146 | + int net_send(Protocol *protocol, const char* log_name, my_off_t pos); |
1147 | |
1148 | /** |
1149 | Stores a string representation of this event in the Protocol. |
1150 | @@ -1232,7 +1231,7 @@ |
1151 | @retval 0 success |
1152 | @retval nonzero error |
1153 | */ |
1154 | - virtual int pack_info(THD *thd, Protocol *protocol); |
1155 | + virtual int pack_info(Protocol *protocol); |
1156 | |
1157 | #endif /* HAVE_REPLICATION */ |
1158 | virtual const char* get_db() |
1159 | @@ -2174,7 +2173,7 @@ |
1160 | virtual uchar mts_number_dbs() { return mts_accessed_dbs; } |
1161 | |
1162 | #ifdef HAVE_REPLICATION |
1163 | - int pack_info(THD *thd, Protocol* protocol); |
1164 | + int pack_info(Protocol* protocol); |
1165 | #endif /* HAVE_REPLICATION */ |
1166 | #else |
1167 | void print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info); |
1168 | @@ -2460,11 +2459,9 @@ |
1169 | const Format_description_log_event* description_event); |
1170 | |
1171 | public: |
1172 | -#ifndef MYSQL_CLIENT |
1173 | - void print_query(THD *thd, bool need_db, const char *cs, String *buf, |
1174 | - my_off_t *fn_start, my_off_t *fn_end, |
1175 | - const char *qualify_db); |
1176 | -#endif |
1177 | + uint get_query_buffer_length(); |
1178 | + void print_query(bool need_db, const char *cs, char *buf, char **end, |
1179 | + char **fn_start, char **fn_end); |
1180 | ulong thread_id; |
1181 | ulong slave_proxy_id; |
1182 | uint32 table_name_len; |
1183 | @@ -2525,7 +2522,7 @@ |
1184 | Name_resolution_context *context); |
1185 | const char* get_db() { return db; } |
1186 | #ifdef HAVE_REPLICATION |
1187 | - int pack_info(THD *thd, Protocol* protocol); |
1188 | + int pack_info(Protocol* protocol); |
1189 | #endif /* HAVE_REPLICATION */ |
1190 | #else |
1191 | void print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
1192 | @@ -2624,7 +2621,7 @@ |
1193 | #ifdef MYSQL_SERVER |
1194 | Start_log_event_v3(); |
1195 | #ifdef HAVE_REPLICATION |
1196 | - int pack_info(THD *thd, Protocol* protocol); |
1197 | + int pack_info(Protocol* protocol); |
1198 | #endif /* HAVE_REPLICATION */ |
1199 | #else |
1200 | Start_log_event_v3() {} |
1201 | @@ -2796,7 +2793,7 @@ |
1202 | :Log_event(thd_arg, 0, cache_type_arg, logging_type_arg), |
1203 | val(val_arg), type(type_arg) { } |
1204 | #ifdef HAVE_REPLICATION |
1205 | - int pack_info(THD *thd, Protocol* protocol); |
1206 | + int pack_info(Protocol* protocol); |
1207 | #endif /* HAVE_REPLICATION */ |
1208 | #else |
1209 | void print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
1210 | @@ -2874,7 +2871,7 @@ |
1211 | :Log_event(thd_arg, 0, cache_type_arg, logging_type_arg), |
1212 | seed1(seed1_arg), seed2(seed2_arg) { } |
1213 | #ifdef HAVE_REPLICATION |
1214 | - int pack_info(THD *thd, Protocol* protocol); |
1215 | + int pack_info(Protocol* protocol); |
1216 | #endif /* HAVE_REPLICATION */ |
1217 | #else |
1218 | void print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
1219 | @@ -2923,7 +2920,7 @@ |
1220 | xid(x) |
1221 | { } |
1222 | #ifdef HAVE_REPLICATION |
1223 | - int pack_info(THD *thd, Protocol* protocol); |
1224 | + int pack_info(Protocol* protocol); |
1225 | #endif /* HAVE_REPLICATION */ |
1226 | #else |
1227 | void print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
1228 | @@ -2986,7 +2983,7 @@ |
1229 | { |
1230 | is_null= !val; |
1231 | } |
1232 | - int pack_info(THD *thd, Protocol* protocol); |
1233 | + int pack_info(Protocol* protocol); |
1234 | #else |
1235 | void print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
1236 | #endif |
1237 | @@ -3128,7 +3125,7 @@ |
1238 | uint ident_len_arg, |
1239 | ulonglong pos_arg, uint flags); |
1240 | #ifdef HAVE_REPLICATION |
1241 | - int pack_info(THD *thd, Protocol* protocol); |
1242 | + int pack_info(Protocol* protocol); |
1243 | #endif /* HAVE_REPLICATION */ |
1244 | #else |
1245 | void print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
1246 | @@ -3189,7 +3186,7 @@ |
1247 | uchar* block_arg, uint block_len_arg, |
1248 | bool using_trans); |
1249 | #ifdef HAVE_REPLICATION |
1250 | - int pack_info(THD *thd, Protocol* protocol); |
1251 | + int pack_info(Protocol* protocol); |
1252 | #endif /* HAVE_REPLICATION */ |
1253 | #else |
1254 | void print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
1255 | @@ -3261,7 +3258,7 @@ |
1256 | Append_block_log_event(THD* thd, const char* db_arg, uchar* block_arg, |
1257 | uint block_len_arg, bool using_trans); |
1258 | #ifdef HAVE_REPLICATION |
1259 | - int pack_info(THD* thd, Protocol* protocol); |
1260 | + int pack_info(Protocol* protocol); |
1261 | virtual int get_create_or_append() const; |
1262 | #endif /* HAVE_REPLICATION */ |
1263 | #else |
1264 | @@ -3302,7 +3299,7 @@ |
1265 | #ifdef MYSQL_SERVER |
1266 | Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans); |
1267 | #ifdef HAVE_REPLICATION |
1268 | - int pack_info(THD* thd, Protocol* protocol); |
1269 | + int pack_info(Protocol* protocol); |
1270 | #endif /* HAVE_REPLICATION */ |
1271 | #else |
1272 | void print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
1273 | @@ -3343,7 +3340,7 @@ |
1274 | #ifdef MYSQL_SERVER |
1275 | Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans); |
1276 | #ifdef HAVE_REPLICATION |
1277 | - int pack_info(THD* thd, Protocol* protocol); |
1278 | + int pack_info(Protocol* protocol); |
1279 | #endif /* HAVE_REPLICATION */ |
1280 | #else |
1281 | void print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
1282 | @@ -3453,7 +3450,7 @@ |
1283 | bool using_trans, bool immediate, |
1284 | bool suppress_use, int errcode); |
1285 | #ifdef HAVE_REPLICATION |
1286 | - int pack_info(THD* thd, Protocol* protocol); |
1287 | + int pack_info(Protocol* protocol); |
1288 | #endif /* HAVE_REPLICATION */ |
1289 | #else |
1290 | void print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
1291 | @@ -3934,7 +3931,7 @@ |
1292 | #endif |
1293 | |
1294 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
1295 | - virtual int pack_info(THD* thd, Protocol *protocol); |
1296 | + virtual int pack_info(Protocol *protocol); |
1297 | #endif |
1298 | |
1299 | #ifdef MYSQL_CLIENT |
1300 | @@ -4057,7 +4054,7 @@ |
1301 | virtual Log_event_type get_general_type_code() = 0; /* General rows op type, no version */ |
1302 | |
1303 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
1304 | - virtual int pack_info(THD* thd, Protocol *protocol); |
1305 | + virtual int pack_info(Protocol *protocol); |
1306 | #endif |
1307 | |
1308 | #ifdef MYSQL_CLIENT |
1309 | @@ -4718,7 +4715,7 @@ |
1310 | #endif |
1311 | |
1312 | #ifdef MYSQL_SERVER |
1313 | - int pack_info(THD*, Protocol*); |
1314 | + int pack_info(Protocol*); |
1315 | #endif |
1316 | |
1317 | Incident_log_event(const char *buf, uint event_len, |
1318 | @@ -4790,7 +4787,7 @@ |
1319 | virtual ~Ignorable_log_event(); |
1320 | |
1321 | #ifndef MYSQL_CLIENT |
1322 | - virtual int pack_info(THD*, Protocol*); |
1323 | + int pack_info(Protocol*); |
1324 | #endif |
1325 | |
1326 | #ifdef MYSQL_CLIENT |
1327 | @@ -4821,7 +4818,7 @@ |
1328 | #endif |
1329 | |
1330 | #ifndef MYSQL_CLIENT |
1331 | - virtual int pack_info(THD*, Protocol*); |
1332 | + int pack_info(Protocol*); |
1333 | #endif |
1334 | |
1335 | Rows_query_log_event(const char *buf, uint event_len, |
1336 | @@ -4924,7 +4921,7 @@ |
1337 | #endif |
1338 | |
1339 | #ifndef MYSQL_CLIENT |
1340 | - virtual int pack_info(THD*, Protocol*); |
1341 | + int pack_info(Protocol*); |
1342 | #endif |
1343 | |
1344 | Gtid_log_event(const char *buffer, uint event_len, |
1345 | @@ -5062,7 +5059,7 @@ |
1346 | #endif |
1347 | |
1348 | #ifndef MYSQL_CLIENT |
1349 | - virtual int pack_info(THD*, Protocol*); |
1350 | + int pack_info(Protocol*); |
1351 | #endif |
1352 | |
1353 | Previous_gtids_log_event(const char *buffer, uint event_len, |
1354 | |
1355 | === modified file 'sql/log_event_old.cc' |
1356 | --- sql/log_event_old.cc 2014-03-17 10:59:40 +0000 |
1357 | +++ sql/log_event_old.cc 2014-07-31 14:56:03 +0000 |
1358 | @@ -1922,7 +1922,7 @@ |
1359 | |
1360 | |
1361 | #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) |
1362 | -int Old_rows_log_event::pack_info(THD *thd, Protocol *protocol) |
1363 | +int Old_rows_log_event::pack_info(Protocol *protocol) |
1364 | { |
1365 | char buf[256]; |
1366 | char const *const flagstr= |
1367 | |
1368 | === modified file 'sql/log_event_old.h' |
1369 | --- sql/log_event_old.h 2014-04-25 10:55:01 +0000 |
1370 | +++ sql/log_event_old.h 2014-07-31 14:56:03 +0000 |
1371 | @@ -110,7 +110,7 @@ |
1372 | flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; } |
1373 | |
1374 | #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) |
1375 | - virtual int pack_info(THD *thd, Protocol *protocol); |
1376 | + virtual int pack_info(Protocol *protocol); |
1377 | #endif |
1378 | |
1379 | #ifdef MYSQL_CLIENT |
1380 | |
1381 | === modified file 'sql/sql_base.cc' |
1382 | --- sql/sql_base.cc 2014-06-04 14:48:06 +0000 |
1383 | +++ sql/sql_base.cc 2014-07-31 14:56:03 +0000 |
1384 | @@ -3933,44 +3933,28 @@ |
1385 | entry->file->implicit_emptied= 0; |
1386 | if (mysql_bin_log.is_open()) |
1387 | { |
1388 | - char query_buf[2*FN_REFLEN + 21]; |
1389 | - String query(query_buf, sizeof(query_buf), system_charset_info); |
1390 | - query.length(0); |
1391 | - if (query.ptr()) |
1392 | - { |
1393 | - /* this DELETE FROM is needed even with row-based binlogging */ |
1394 | - query.append("DELETE FROM "); |
1395 | - append_identifier(thd, &query, share->db.str, share->db.length); |
1396 | - query.append("."); |
1397 | - append_identifier(thd, &query, share->table_name.str, |
1398 | - share->table_name.length); |
1399 | - int errcode= query_error_code(thd, TRUE); |
1400 | - if (thd->binlog_query(THD::STMT_QUERY_TYPE, |
1401 | - query.ptr(), query.length(), |
1402 | - FALSE, FALSE, FALSE, errcode)) |
1403 | - return FALSE; |
1404 | - } |
1405 | - else |
1406 | + bool error= false; |
1407 | + String temp_buf; |
1408 | + error= temp_buf.append("DELETE FROM "); |
1409 | + append_identifier(thd, &temp_buf, share->db.str, strlen(share->db.str)); |
1410 | + error= temp_buf.append("."); |
1411 | + append_identifier(thd, &temp_buf, share->table_name.str, |
1412 | + strlen(share->table_name.str)); |
1413 | + int errcode= query_error_code(thd, TRUE); |
1414 | + if (thd->binlog_query(THD::STMT_QUERY_TYPE, |
1415 | + temp_buf.c_ptr_safe(), temp_buf.length(), |
1416 | + FALSE, TRUE, FALSE, errcode)) |
1417 | + return TRUE; |
1418 | + if (error) |
1419 | { |
1420 | /* |
1421 | As replication is maybe going to be corrupted, we need to warn the |
1422 | DBA on top of warning the client (which will automatically be done |
1423 | because of MYF(MY_WME) in my_malloc() above). |
1424 | */ |
1425 | - char q_db_c[512]; |
1426 | - char q_table_name_c[512]; |
1427 | - String q_db(q_db_c, sizeof(q_db_c), system_charset_info); |
1428 | - String q_table_name(q_table_name_c, sizeof(q_table_name), system_charset_info); |
1429 | - q_db.length(0); |
1430 | - q_table_name.length(0); |
1431 | - append_identifier(thd, &q_db, share->db.str, share->db.length); |
1432 | - append_identifier(thd, |
1433 | - &q_table_name, |
1434 | - share->table_name.str, |
1435 | - share->table_name.length); |
1436 | sql_print_error("When opening HEAP table, could not allocate memory " |
1437 | - "to write 'DELETE FROM %s.%s' to the binary log", |
1438 | - q_db.c_ptr(), q_table_name.c_ptr()); |
1439 | + "to write 'DELETE FROM `%s`.`%s`' to the binary log", |
1440 | + share->db.str, share->table_name.str); |
1441 | delete entry->triggers; |
1442 | return TRUE; |
1443 | } |
1444 | |
1445 | === modified file 'sql/sql_db.cc' |
1446 | --- sql/sql_db.cc 2014-03-03 17:51:33 +0000 |
1447 | +++ sql/sql_db.cc 2014-07-31 14:56:03 +0000 |
1448 | @@ -541,6 +541,7 @@ |
1449 | bool silent) |
1450 | { |
1451 | char path[FN_REFLEN+16]; |
1452 | + char tmp_query[FN_REFLEN+16]; |
1453 | long result= 1; |
1454 | int error= 0; |
1455 | MY_STAT stat_info; |
1456 | @@ -626,10 +627,23 @@ |
1457 | { |
1458 | char *query; |
1459 | uint query_length; |
1460 | + char db_name_quoted[2 * FN_REFLEN + sizeof("create database ") + 2]; |
1461 | + int id_len= 0; |
1462 | |
1463 | - query= thd->query(); |
1464 | - query_length= thd->query_length(); |
1465 | - DBUG_ASSERT(query); |
1466 | + if (!thd->query()) // Only in replication |
1467 | + { |
1468 | + id_len= my_strmov_quoted_identifier(thd, (char *) db_name_quoted, db, |
1469 | + 0); |
1470 | + db_name_quoted[id_len]= '\0'; |
1471 | + query= tmp_query; |
1472 | + query_length= (uint) (strxmov(tmp_query,"create database ", |
1473 | + db_name_quoted, NullS) - tmp_query); |
1474 | + } |
1475 | + else |
1476 | + { |
1477 | + query= thd->query(); |
1478 | + query_length= thd->query_length(); |
1479 | + } |
1480 | |
1481 | ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB, |
1482 | query, query_length, |
1483 | @@ -881,11 +895,23 @@ |
1484 | { |
1485 | const char *query; |
1486 | ulong query_length; |
1487 | - |
1488 | - query= thd->query(); |
1489 | - query_length= thd->query_length(); |
1490 | - DBUG_ASSERT(query); |
1491 | - |
1492 | + // quoted db name + wraping quote |
1493 | + char buffer_temp [2 * FN_REFLEN + 2]; |
1494 | + int id_len= 0; |
1495 | + if (!thd->query()) |
1496 | + { |
1497 | + /* The client used the old obsolete mysql_drop_db() call */ |
1498 | + query= path; |
1499 | + id_len= my_strmov_quoted_identifier(thd, buffer_temp, db, strlen(db)); |
1500 | + buffer_temp[id_len] ='\0'; |
1501 | + query_length= (uint) (strxmov(path, "DROP DATABASE ", buffer_temp, "", |
1502 | + NullS) - path); |
1503 | + } |
1504 | + else |
1505 | + { |
1506 | + query= thd->query(); |
1507 | + query_length= thd->query_length(); |
1508 | + } |
1509 | if (mysql_bin_log.is_open()) |
1510 | { |
1511 | int errcode= query_error_code(thd, TRUE); |
1512 | @@ -916,8 +942,9 @@ |
1513 | else if (mysql_bin_log.is_open() && !silent) |
1514 | { |
1515 | char *query, *query_pos, *query_end, *query_data_start; |
1516 | + char temp_identifier[ 2 * FN_REFLEN + 2]; |
1517 | TABLE_LIST *tbl; |
1518 | - uint db_len; |
1519 | + uint db_len, id_length=0; |
1520 | |
1521 | if (!(query= (char*) thd->alloc(MAX_DROP_TABLE_Q_LEN))) |
1522 | goto exit; /* not much else we can do */ |
1523 | @@ -939,16 +966,8 @@ |
1524 | if (exists) |
1525 | continue; |
1526 | |
1527 | - char quoted_name_c[FN_REFLEN+3]; |
1528 | - String quoted_name(quoted_name_c, |
1529 | - sizeof(quoted_name_c), |
1530 | - system_charset_info); |
1531 | - quoted_name.length(0); |
1532 | - quoted_name.append_identifier(tbl->table_name, |
1533 | - strlen(tbl->table_name), |
1534 | - system_charset_info, |
1535 | - '`'); |
1536 | - tbl_name_len= quoted_name.length() + 1; /* +1 for the comma */ |
1537 | + /* 3 for the quotes and the comma*/ |
1538 | + tbl_name_len= strlen(tbl->table_name) + 3; |
1539 | if (query_pos + tbl_name_len + 1 >= query_end) |
1540 | { |
1541 | /* |
1542 | @@ -962,8 +981,10 @@ |
1543 | } |
1544 | query_pos= query_data_start; |
1545 | } |
1546 | - |
1547 | - query_pos= strmov(query_pos, quoted_name.c_ptr()); |
1548 | + id_length= my_strmov_quoted_identifier(thd, (char *)temp_identifier, |
1549 | + tbl->table_name, 0); |
1550 | + temp_identifier[id_length]= '\0'; |
1551 | + query_pos= strmov(query_pos,(char *)&temp_identifier); |
1552 | *query_pos++ = ','; |
1553 | } |
1554 | |
1555 | |
1556 | === modified file 'sql/sql_load.cc' |
1557 | --- sql/sql_load.cc 2014-06-04 14:48:06 +0000 |
1558 | +++ sql/sql_load.cc 2014-07-31 14:56:03 +0000 |
1559 | @@ -686,21 +686,20 @@ |
1560 | bool transactional_table, |
1561 | int errcode) |
1562 | { |
1563 | - char *load_data_query; |
1564 | - my_off_t fname_start, |
1565 | - fname_end; |
1566 | + char *load_data_query, |
1567 | + *end, |
1568 | + *fname_start, |
1569 | + *fname_end, |
1570 | + *p= NULL; |
1571 | + size_t pl= 0; |
1572 | List<Item> fv; |
1573 | - Item *item, *val; |
1574 | + Item *item; |
1575 | + String *str; |
1576 | + String pfield, pfields; |
1577 | int n; |
1578 | - const char *tbl; |
1579 | + const char *tbl= table_name_arg; |
1580 | const char *tdb= (thd->db != NULL ? thd->db : db_arg); |
1581 | String string_buf; |
1582 | - const char *qualify_db= NULL; |
1583 | - char command_buffer[1024]; |
1584 | - String query_str(command_buffer, sizeof(command_buffer), |
1585 | - system_charset_info); |
1586 | - |
1587 | - query_str.length(0); |
1588 | if (!thd->db || strcmp(db_arg, thd->db)) |
1589 | { |
1590 | /* |
1591 | @@ -711,7 +710,6 @@ |
1592 | string_buf.set_charset(system_charset_info); |
1593 | append_identifier(thd, &string_buf, db_arg, strlen(db_arg)); |
1594 | string_buf.append("."); |
1595 | - qualify_db= db_arg; |
1596 | } |
1597 | append_identifier(thd, &string_buf, table_name_arg, |
1598 | strlen(table_name_arg)); |
1599 | @@ -724,8 +722,6 @@ |
1600 | */ |
1601 | if (thd->lex->local_file) |
1602 | lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name)); |
1603 | - lle.print_query(thd, FALSE, (const char *) ex->cs?ex->cs->csname:NULL, |
1604 | - &query_str, &fname_start, &fname_end, qualify_db); |
1605 | |
1606 | /* |
1607 | prepare fields-list and SET if needed; print_query won't do that for us. |
1608 | @@ -734,51 +730,66 @@ |
1609 | { |
1610 | List_iterator<Item> li(thd->lex->field_list); |
1611 | |
1612 | - query_str.append(" ("); |
1613 | + pfields.append(" ("); |
1614 | n= 0; |
1615 | |
1616 | while ((item= li++)) |
1617 | { |
1618 | if (n++) |
1619 | - query_str.append(", "); |
1620 | + pfields.append(", "); |
1621 | if (item->type() == Item::FIELD_ITEM) |
1622 | - append_identifier(thd, &query_str, item->item_name.ptr(), |
1623 | + append_identifier(thd, &pfields, item->item_name.ptr(), |
1624 | strlen(item->item_name.ptr())); |
1625 | else |
1626 | - { |
1627 | - /* Actually Item_user_var_as_out_param despite claiming STRING_ITEM. */ |
1628 | - DBUG_ASSERT(item->type() == Item::STRING_ITEM); |
1629 | - ((Item_user_var_as_out_param *)item)->print_for_load(thd, &query_str); |
1630 | - } |
1631 | + item->print(&pfields, QT_ORDINARY); |
1632 | } |
1633 | - query_str.append(")"); |
1634 | + pfields.append(")"); |
1635 | } |
1636 | |
1637 | if (!thd->lex->update_list.is_empty()) |
1638 | { |
1639 | List_iterator<Item> lu(thd->lex->update_list); |
1640 | - List_iterator<Item> lv(thd->lex->value_list); |
1641 | + List_iterator<String> ls(thd->lex->load_set_str_list); |
1642 | |
1643 | - query_str.append(" SET "); |
1644 | + pfields.append(" SET "); |
1645 | n= 0; |
1646 | |
1647 | while ((item= lu++)) |
1648 | { |
1649 | - val= lv++; |
1650 | + str= ls++; |
1651 | if (n++) |
1652 | - query_str.append(", "); |
1653 | - append_identifier(thd, &query_str, item->item_name.ptr(), |
1654 | + pfields.append(", "); |
1655 | + append_identifier(thd, &pfields, item->item_name.ptr(), |
1656 | strlen(item->item_name.ptr())); |
1657 | - query_str.append(val->item_name.ptr()); |
1658 | + // Extract exact Item value |
1659 | + str->copy(); |
1660 | + pfields.append(str->ptr()); |
1661 | + str->free(); |
1662 | } |
1663 | + /* |
1664 | + Clear the SET string list once the SET command is reconstructed |
1665 | + as we donot require the list anymore. |
1666 | + */ |
1667 | + thd->lex->load_set_str_list.empty(); |
1668 | } |
1669 | |
1670 | - if (!(load_data_query= (char *)thd->strmake(query_str.ptr(), query_str.length()))) |
1671 | + p= pfields.c_ptr_safe(); |
1672 | + pl= strlen(p); |
1673 | + |
1674 | + if (!(load_data_query= (char *)thd->alloc(lle.get_query_buffer_length() + 1 + pl))) |
1675 | return TRUE; |
1676 | |
1677 | + lle.print_query(FALSE, ex->cs ? ex->cs->csname : NULL, |
1678 | + load_data_query, &end, |
1679 | + &fname_start, &fname_end); |
1680 | + |
1681 | + strcpy(end, p); |
1682 | + end += pl; |
1683 | + |
1684 | Execute_load_query_log_event |
1685 | - e(thd, load_data_query, query_str.length(), |
1686 | - static_cast<uint>(fname_start - 1), static_cast<uint>(fname_end), |
1687 | + e(thd, load_data_query, end-load_data_query, |
1688 | + static_cast<uint>(fname_start - load_data_query - 1), |
1689 | + static_cast<uint>(fname_end - load_data_query), |
1690 | (duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE : |
1691 | (ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR), |
1692 | transactional_table, FALSE, FALSE, errcode); |
1693 | |
1694 | === modified file 'sql/sql_select.cc' |
1695 | --- sql/sql_select.cc 2014-06-04 14:48:06 +0000 |
1696 | +++ sql/sql_select.cc 2014-07-31 14:56:03 +0000 |
1697 | @@ -78,7 +78,6 @@ |
1698 | LEX *lex= thd->lex; |
1699 | register SELECT_LEX *select_lex = &lex->select_lex; |
1700 | DBUG_ENTER("handle_select"); |
1701 | - |
1702 | MYSQL_SELECT_START(thd->query()); |
1703 | |
1704 | if (lex->proc_analyse && lex->sql_command != SQLCOM_SELECT) |
1705 | |
1706 | === modified file 'sql/sql_show.cc' |
1707 | --- sql/sql_show.cc 2014-07-23 05:17:52 +0000 |
1708 | +++ sql/sql_show.cc 2014-07-31 14:56:03 +0000 |
1709 | @@ -1118,17 +1118,49 @@ |
1710 | packet target string |
1711 | name the identifier to be appended |
1712 | name_length length of the appending identifier |
1713 | - |
1714 | - RETURN VALUES |
1715 | - true Error |
1716 | - false Ok |
1717 | */ |
1718 | |
1719 | -bool |
1720 | +void |
1721 | append_identifier(THD *thd, String *packet, const char *name, uint length) |
1722 | { |
1723 | - int q= get_quote_char_for_identifier(thd, name, length); |
1724 | - return packet->append_identifier(name, length, system_charset_info, q); |
1725 | + const char *name_end; |
1726 | + char quote_char; |
1727 | + int q; |
1728 | + q= thd ? get_quote_char_for_identifier(thd, name, length) : '`'; |
1729 | + |
1730 | + if (q == EOF) |
1731 | + { |
1732 | + packet->append(name, length, packet->charset()); |
1733 | + return; |
1734 | + } |
1735 | + |
1736 | + /* |
1737 | + The identifier must be quoted as it includes a quote character or |
1738 | + it's a keyword |
1739 | + */ |
1740 | + |
1741 | + (void) packet->reserve(length*2 + 2); |
1742 | + quote_char= (char) q; |
1743 | + packet->append("e_char, 1, system_charset_info); |
1744 | + |
1745 | + for (name_end= name+length ; name < name_end ; name+= length) |
1746 | + { |
1747 | + uchar chr= (uchar) *name; |
1748 | + length= my_mbcharlen(system_charset_info, chr); |
1749 | + /* |
1750 | + my_mbcharlen can return 0 on a wrong multibyte |
1751 | + sequence. It is possible when upgrading from 4.0, |
1752 | + and identifier contains some accented characters. |
1753 | + The manual says it does not work. So we'll just |
1754 | + change length to 1 not to hang in the endless loop. |
1755 | + */ |
1756 | + if (!length) |
1757 | + length= 1; |
1758 | + if (length == 1 && chr == (uchar) quote_char) |
1759 | + packet->append("e_char, 1, system_charset_info); |
1760 | + packet->append(name, length, system_charset_info); |
1761 | + } |
1762 | + packet->append("e_char, 1, system_charset_info); |
1763 | } |
1764 | |
1765 | |
1766 | |
1767 | === modified file 'sql/sql_show.h' |
1768 | --- sql/sql_show.h 2013-08-14 03:57:21 +0000 |
1769 | +++ sql/sql_show.h 2014-07-31 14:56:03 +0000 |
1770 | @@ -165,7 +165,7 @@ |
1771 | int copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table); |
1772 | int get_quote_char_for_identifier(THD *thd, const char *name, uint length); |
1773 | |
1774 | -bool append_identifier(THD *thd, String *packet, const char *name, |
1775 | +void append_identifier(THD *thd, String *packet, const char *name, |
1776 | uint length); |
1777 | inline void append_identifier(THD *thd, String *packet, Simple_cstring str) |
1778 | { |
1779 | |
1780 | === modified file 'sql/sql_string.cc' |
1781 | --- sql/sql_string.cc 2014-06-04 14:48:06 +0000 |
1782 | +++ sql/sql_string.cc 2014-07-31 14:56:03 +0000 |
1783 | @@ -575,49 +575,6 @@ |
1784 | return FALSE; |
1785 | } |
1786 | |
1787 | -bool String::append_identifier(const char *name, |
1788 | - uint length, |
1789 | - const CHARSET_INFO *ci, |
1790 | - int quote_char) |
1791 | -{ |
1792 | - const char *name_end; |
1793 | - char q= (char)quote_char; |
1794 | - const CHARSET_INFO *lci = ci ? ci : charset(); |
1795 | - |
1796 | - if (quote_char == EOF) |
1797 | - return append(name, length, charset()); |
1798 | - |
1799 | - /* |
1800 | - The identifier must be quoted as it includes a quote character or |
1801 | - it's a keyword |
1802 | - */ |
1803 | - |
1804 | - (void)reserve(length*2 + 2); |
1805 | - if (append(&q, 1, lci)) |
1806 | - return true; |
1807 | - |
1808 | - for (name_end= name+length ; name < name_end ; name+= length) |
1809 | - { |
1810 | - uchar chr= (uchar) *name; |
1811 | - length= my_mbcharlen(lci, chr); |
1812 | - /* |
1813 | - my_mbcharlen can return 0 on a wrong multibyte |
1814 | - sequence. It is possible when upgrading from 4.0, |
1815 | - and identifier contains some accented characters. |
1816 | - The manual says it does not work. So we'll just |
1817 | - change length to 1 not to hang in the endless loop. |
1818 | - */ |
1819 | - if (!length) |
1820 | - length= 1; |
1821 | - if (length == 1 && chr == (uchar) q && |
1822 | - append(&q, 1, lci)) |
1823 | - return true; |
1824 | - if (append(name, length, lci)) |
1825 | - return true; |
1826 | - } |
1827 | - return append(&q, 1, lci); |
1828 | -} |
1829 | - |
1830 | uint32 String::numchars() const |
1831 | { |
1832 | return str_charset->cset->numchars(str_charset, Ptr, Ptr+str_length); |
1833 | @@ -1085,47 +1042,39 @@ |
1834 | |
1835 | |
1836 | |
1837 | -/* |
1838 | - Append characters to a single-quoted string '...', escaping special |
1839 | - characters as necessary. |
1840 | - Does not add the enclosing quotes, this is left up to caller. |
1841 | -*/ |
1842 | -void String::append_for_single_quote(const char *st, uint len) |
1843 | + |
1844 | +void String::print(String *str) |
1845 | { |
1846 | - const char *end= st+len; |
1847 | + char *st= (char*)Ptr, *end= st+str_length; |
1848 | for (; st < end; st++) |
1849 | { |
1850 | uchar c= *st; |
1851 | switch (c) |
1852 | { |
1853 | case '\\': |
1854 | - append(STRING_WITH_LEN("\\\\")); |
1855 | + str->append(STRING_WITH_LEN("\\\\")); |
1856 | break; |
1857 | case '\0': |
1858 | - append(STRING_WITH_LEN("\\0")); |
1859 | + str->append(STRING_WITH_LEN("\\0")); |
1860 | break; |
1861 | case '\'': |
1862 | - append(STRING_WITH_LEN("\\'")); |
1863 | + str->append(STRING_WITH_LEN("\\'")); |
1864 | break; |
1865 | case '\n': |
1866 | - append(STRING_WITH_LEN("\\n")); |
1867 | + str->append(STRING_WITH_LEN("\\n")); |
1868 | break; |
1869 | case '\r': |
1870 | - append(STRING_WITH_LEN("\\r")); |
1871 | + str->append(STRING_WITH_LEN("\\r")); |
1872 | break; |
1873 | case '\032': // Ctrl-Z |
1874 | - append(STRING_WITH_LEN("\\Z")); |
1875 | + str->append(STRING_WITH_LEN("\\Z")); |
1876 | break; |
1877 | default: |
1878 | - append(c); |
1879 | + str->append(c); |
1880 | } |
1881 | } |
1882 | } |
1883 | |
1884 | -void String::print(String *str) |
1885 | -{ |
1886 | - str->append_for_single_quote(Ptr, str_length); |
1887 | -} |
1888 | |
1889 | /* |
1890 | Exchange state of this object and argument. |
1891 | |
1892 | === modified file 'sql/sql_string.h' |
1893 | --- sql/sql_string.h 2014-06-04 14:48:06 +0000 |
1894 | +++ sql/sql_string.h 2014-07-31 14:56:03 +0000 |
1895 | @@ -106,11 +106,6 @@ |
1896 | } |
1897 | }; |
1898 | |
1899 | -#define QUOTED_IDENTIFIER(str_name, buf_size, q, cs, id_name, id_size) \ |
1900 | - char buf_##str_name[(buf_size)]; \ |
1901 | - String str_name((buf_##str_name), (buf_size), (cs)); \ |
1902 | - str_name.length(0); \ |
1903 | - str_name.append_identifier((id_name), (id_size), (cs), (q)); |
1904 | |
1905 | class String; |
1906 | typedef struct charset_info_st CHARSET_INFO; |
1907 | @@ -423,10 +418,6 @@ |
1908 | bool append_with_prefill(const char *s, uint32 arg_length, |
1909 | uint32 full_length, char fill_char); |
1910 | bool append_parenthesized(long nr, int radix= 10); |
1911 | - bool append_identifier(const char *name, |
1912 | - uint length, |
1913 | - const CHARSET_INFO *ci, |
1914 | - int quote_char); |
1915 | int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 |
1916 | int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1 |
1917 | bool replace(uint32 offset,uint32 arg_length,const char *to,uint32 length); |
1918 | @@ -529,7 +520,6 @@ |
1919 | return FALSE; |
1920 | } |
1921 | void print(String *print); |
1922 | - void append_for_single_quote(const char *st, uint len); |
1923 | |
1924 | /* Swap two string objects. Efficient way to exchange data without memcpy. */ |
1925 | void swap(String &s); |
1926 | |
1927 | === modified file 'sql/sql_truncate.cc' |
1928 | --- sql/sql_truncate.cc 2014-06-04 14:48:06 +0000 |
1929 | +++ sql/sql_truncate.cc 2014-07-31 14:56:03 +0000 |
1930 | @@ -35,8 +35,7 @@ |
1931 | @return TRUE on failure, FALSE otherwise. |
1932 | */ |
1933 | |
1934 | -static bool fk_info_append_fields(THD *thd, String *str, |
1935 | - List<LEX_STRING> *fields) |
1936 | +static bool fk_info_append_fields(String *str, List<LEX_STRING> *fields) |
1937 | { |
1938 | bool res= FALSE; |
1939 | LEX_STRING *field; |
1940 | @@ -44,7 +43,7 @@ |
1941 | |
1942 | while ((field= it++)) |
1943 | { |
1944 | - res|= append_identifier(thd, str, field->str, field->length); |
1945 | + append_identifier(NULL, str, field->str, field->length); |
1946 | res|= str->append(", "); |
1947 | } |
1948 | |
1949 | @@ -76,24 +75,24 @@ |
1950 | `db`.`tbl`, CONSTRAINT `id` FOREIGN KEY (`fk`) REFERENCES `db`.`tbl` (`fk`) |
1951 | */ |
1952 | |
1953 | - res|= append_identifier(thd, &str, fk_info->foreign_db->str, |
1954 | - fk_info->foreign_db->length); |
1955 | + append_identifier(NULL, &str, fk_info->foreign_db->str, |
1956 | + fk_info->foreign_db->length); |
1957 | res|= str.append("."); |
1958 | - res|= append_identifier(thd, &str, fk_info->foreign_table->str, |
1959 | - fk_info->foreign_table->length); |
1960 | + append_identifier(NULL, &str, fk_info->foreign_table->str, |
1961 | + fk_info->foreign_table->length); |
1962 | res|= str.append(", CONSTRAINT "); |
1963 | - res|= append_identifier(thd, &str, fk_info->foreign_id->str, |
1964 | - fk_info->foreign_id->length); |
1965 | + append_identifier(NULL, &str, fk_info->foreign_id->str, |
1966 | + fk_info->foreign_id->length); |
1967 | res|= str.append(" FOREIGN KEY ("); |
1968 | - res|= fk_info_append_fields(thd, &str, &fk_info->foreign_fields); |
1969 | + res|= fk_info_append_fields(&str, &fk_info->foreign_fields); |
1970 | res|= str.append(") REFERENCES "); |
1971 | - res|= append_identifier(thd, &str, fk_info->referenced_db->str, |
1972 | - fk_info->referenced_db->length); |
1973 | + append_identifier(NULL, &str, fk_info->referenced_db->str, |
1974 | + fk_info->referenced_db->length); |
1975 | res|= str.append("."); |
1976 | - res|= append_identifier(thd, &str, fk_info->referenced_table->str, |
1977 | - fk_info->referenced_table->length); |
1978 | + append_identifier(NULL, &str, fk_info->referenced_table->str, |
1979 | + fk_info->referenced_table->length); |
1980 | res|= str.append(" ("); |
1981 | - res|= fk_info_append_fields(thd, &str, &fk_info->referenced_fields); |
1982 | + res|= fk_info_append_fields(&str, &fk_info->referenced_fields); |
1983 | res|= str.append(')'); |
1984 | |
1985 | return res ? NULL : thd->strmake(str.ptr(), str.length()); |
1986 | |
1987 | === modified file 'sql/sql_yacc.yy' |
1988 | --- sql/sql_yacc.yy 2014-07-28 11:30:03 +0000 |
1989 | +++ sql/sql_yacc.yy 2014-07-31 14:56:03 +0000 |
1990 | @@ -13421,7 +13421,7 @@ |
1991 | lex->value_list.push_back($4) || |
1992 | lex->load_set_str_list.push_back(val)) |
1993 | MYSQL_YYABORT; |
1994 | - $4->item_name.copy_no_truncate($3, length, YYTHD->charset()); |
1995 | + $4->item_name.copy($3, length, YYTHD->charset()); |
1996 | } |
1997 | ; |
1998 |