26
26
#include < iostream>
27
27
#include < map>
28
28
#include < regex>
29
+ #include < sstream>
29
30
#include < string>
30
31
31
32
#include " client/mysqltest/error_names.h"
@@ -112,10 +113,18 @@ static bool run_secondary_load_statement(MYSQL *mysql, std::string table_name) {
112
113
ignore_errors.push_back (get_errcode_from_name (" ER_CHECK_NOT_IMPLEMENTED" ));
113
114
ignore_errors.push_back (get_errcode_from_name (" ER_RAPID_PLUGIN" ));
114
115
115
- // ALTER TABLE statement
116
- std::string alter_stmt = " ALTER TABLE " + table_name + " SECONDARY_LOAD; " ;
116
+ std::stringstream table_names (table_name);
117
+ std::string table ;
117
118
118
- return run_alter_statement (alter_stmt, mysql, ignore_errors);
119
+ // DML Statements like DELETE or UPDATE may contain multiple table
120
+ // names separated by comma.
121
+ while (std::getline (table_names, table, ' ,' )) {
122
+ // ALTER TABLE statement to load the data to secondary engine.
123
+ std::string alter_stmt = " ALTER TABLE " + table + " SECONDARY_LOAD;" ;
124
+ if (run_alter_statement (alter_stmt, mysql, ignore_errors)) return true ;
125
+ }
126
+
127
+ return false ;
119
128
}
120
129
121
130
// / Run ALTER TABLE table_name SECONDARY_UNLOAD statement to unload
@@ -139,10 +148,18 @@ static bool run_secondary_unload_statement(
139
148
ignore_errors.push_back (get_errcode_from_name (" ER_DBACCESS_DENIED_ERROR" ));
140
149
ignore_errors.push_back (get_errcode_from_name (" ER_SECONDARY_ENGINE" ));
141
150
142
- // ALTER TABLE statement
143
- std::string alter_stmt = " ALTER TABLE " + table_name + " SECONDARY_UNLOAD; " ;
151
+ std::stringstream table_names (table_name);
152
+ std::string table ;
144
153
145
- return run_alter_statement (alter_stmt, mysql, ignore_errors);
154
+ // DML Statements like DELETE or UPDATE may contain multiple table
155
+ // names separated by comma.
156
+ while (std::getline (table_names, table, ' ,' )) {
157
+ // ALTER TABLE statement to unload the data from secondary engine.
158
+ std::string alter_stmt = " ALTER TABLE " + table + " SECONDARY_UNLOAD;" ;
159
+ if (run_alter_statement (alter_stmt, mysql, ignore_errors)) return true ;
160
+ }
161
+
162
+ return false ;
146
163
}
147
164
148
165
// / Match a statement string against the pattern. If match found,
@@ -226,20 +243,72 @@ static bool match_ddl_statement(std::string statement,
226
243
return false ;
227
244
}
228
245
246
+ // / Check if a statement is a DML statement. If yes, parse the statement
247
+ // / to extract the table name and store it in a string object.
248
+ // /
249
+ // / @param statement Original statement
250
+ // / @param table_name String object to store the table name
251
+ // /
252
+ // / @retval True if match or table name found, false otherwise.
253
+ static bool match_dml_statement (std::string statement,
254
+ std::string *table_name) {
255
+ std::map<std::string, std::uint16_t > dml_pattern_strings = {
256
+ {" ^\\ s*delete\\ s+((\\ /\\ *\\ +.*\\ *\\ /"
257
+ " \\ s+)?)((LOW_PRIORITY\\ s+)?)((QUICK\\ s+)?)((IGNORE\\ s+)?)"
258
+ " FROM\\ s+(.*?)((\\ s+.*)?)" ,
259
+ 9 },
260
+ {" ^\\ s*insert\\ s+((\\ /\\ *\\ +.*\\ *\\ /"
261
+ " \\ s+)?)((LOW_PRIORITY\\ s+|DELAYED\\ s+|HIGH_PRIORITY\\ s+)?)"
262
+ " ((IGNORE\\ s+)?)((INTO\\ s+)?)(.*?)(\\ s*\\ (|\\ s+).*" ,
263
+ 9 },
264
+ {" ^\\ s*replace\\ s+((\\ /\\ *\\ +.*\\ *\\ /"
265
+ " \\ s+)?)((LOW_PRIORITY\\ s+|DELAYED\\ s+)?)((INTO\\ s+)?)(.*?)"
266
+ " (\\ s*\\ (|\\ s+).*" ,
267
+ 7 },
268
+ {" ^\\ s*update\\ s+((\\ /\\ *\\ +.*\\ *\\ /"
269
+ " \\ s+)?)((LOW_PRIORITY\\ s+)?)((IGNORE\\ s+)?)(.*?)\\ s+set.*" ,
270
+ 7 }};
271
+
272
+ for (std::pair<std::string, std::uint16_t > pattern : dml_pattern_strings) {
273
+ *table_name =
274
+ regex_match_statement (statement, pattern.first , pattern.second );
275
+ if (table_name->length ()) return true ;
276
+ }
277
+
278
+ return false ;
279
+ }
280
+
281
+ // / Check if a statement is a TRUNCATE statement. If yes, parse the
282
+ // / statement to extract the table name and store it in a string object.
283
+ // /
284
+ // / @param statement Original statement
285
+ // / @param table_name String object to store the table name
286
+ // /
287
+ // / @retval True if the match or table name found, false otherwise.
288
+ static bool match_truncate_statement (std::string statement,
289
+ std::string *table_name) {
290
+ std::string pattern_str = " ^\\ s*truncate\\ s+(table\\ s+)?(.*?)(\\ s+.*|\\ s*)" ;
291
+ *table_name = regex_match_statement (statement, pattern_str, 2 );
292
+ if (table_name->length ()) return true ;
293
+ return false ;
294
+ }
295
+
229
296
// / Check if the statement is a CREATE TABLE statement or a DDL
230
297
// / statement. If yes, run the ALTER TABLE statements needed to change
231
298
// / the secondary engine and to load the data from primary engine to
232
299
// / secondary engine.
233
300
// /
234
- // / @param secondary_engine Secondary engine name
235
- // / @param statement Original statement
236
- // / @param mysql mysql handle
237
- // / @param expected_errors List of expected errors
301
+ // / @param secondary_engine Secondary engine name
302
+ // / @param statement Original statement
303
+ // / @param mysql mysql handle
304
+ // / @param expected_errors List of expected errors
305
+ // / @param opt_change_propagation Boolean flag indicating whether change
306
+ // / propagation is enabled or not.
238
307
// /
239
308
// / @retval True if load operation fails, false otherwise.
240
309
bool run_secondary_engine_load_statements (
241
310
const char *secondary_engine, char *statement, MYSQL *mysql,
242
- std::vector<unsigned int > expected_errors) {
311
+ std::vector<unsigned int > expected_errors, bool opt_change_propagation ) {
243
312
std::string table_name (" " );
244
313
245
314
// Check if the statement is a CREATE TABLE statement or a DDL statement
@@ -262,6 +331,23 @@ bool run_secondary_engine_load_statements(
262
331
// Load the data from primary engine to secondary engine.
263
332
if (run_secondary_load_statement (mysql, table_name)) return true ;
264
333
}
334
+ } else if (expected_errors.size () == 0 ) {
335
+ if (match_truncate_statement (statement, &table_name) ||
336
+ (!opt_change_propagation &&
337
+ match_dml_statement (statement, &table_name))) {
338
+ DBUG_ASSERT (table_name.length ());
339
+
340
+ // Unload the data from secondary engine.
341
+ if (run_secondary_unload_statement (mysql, table_name, expected_errors))
342
+ return true ;
343
+
344
+ // Skip running ALTER TABLE statement to load the data from primary
345
+ // engine to secondary engine if the previous ALTER TABLE statement
346
+ // failed with an error.
347
+ if (mysql_errno (mysql) == 0 )
348
+ // Load the data from primary engine to secondary engine.
349
+ if (run_secondary_load_statement (mysql, table_name)) return true ;
350
+ }
265
351
}
266
352
267
353
return false ;
0 commit comments