1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-08-07 03:22:57 +03:00

Merge pull request #705 from drrtuy/MCOL-2160

MCOL-2160 MCOL-1883 RENAME now supports both '/' symbols in table names and crash described in MCOL-1883 has been fixed.
This commit is contained in:
Roman Nozdrin
2019-03-07 15:08:18 +05:30
committed by GitHub

View File

@@ -39,7 +39,6 @@
#include <tr1/unordered_set> #include <tr1/unordered_set>
#endif #endif
#include <utility> #include <utility>
//#define NDEBUG
#include <cassert> #include <cassert>
using namespace std; using namespace std;
@@ -654,7 +653,7 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
{ {
SqlParser parser; SqlParser parser;
THD* thd = current_thd; THD* thd = current_thd;
#ifdef INFINIDB_DEBUG #ifdef MCS_DEBUG
cout << "ProcessDDLStatement: " << schema << "." << table << ":" << ddlStatement << endl; cout << "ProcessDDLStatement: " << schema << "." << table << ":" << ddlStatement << endl;
#endif #endif
@@ -1599,7 +1598,6 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
} }
else if (ddlpackage::AtaRenameColumn* renameColumnsPtr = dynamic_cast<AtaRenameColumn*>(actionList[i])) else if (ddlpackage::AtaRenameColumn* renameColumnsPtr = dynamic_cast<AtaRenameColumn*>(actionList[i]))
{ {
//cout << "Rename a column" << endl;
uint64_t startValue = 1; uint64_t startValue = 1;
bool autoIncre = false; bool autoIncre = false;
//@Bug 3746 Handle compression type //@Bug 3746 Handle compression type
@@ -1798,7 +1796,6 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
stmt.fSql = ddlStatement; stmt.fSql = ddlStatement;
stmt.fOwner = schema; stmt.fOwner = schema;
stmt.fTableWithAutoi = isAnyAutoincreCol; stmt.fTableWithAutoi = isAnyAutoincreCol;
//cout << "Sending to DDLProc" << endl;
ByteStream bytestream; ByteStream bytestream;
bytestream << stmt.fSessionID; bytestream << stmt.fSessionID;
stmt.serialize(bytestream); stmt.serialize(bytestream);
@@ -1887,30 +1884,6 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
return rc; return rc;
} }
// Fails with `/` sign in table name
pair<string, string> parseTableName(const string& tn)
{
string db;
string tb;
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
#ifdef _MSC_VER
boost::char_separator<char> sep("\\");
#else
boost::char_separator<char> sep("/");
#endif
tokenizer tokens(tn, sep);
tokenizer::iterator tok_iter = tokens.begin();
++tok_iter;
idbassert(tok_iter != tokens.end());
db = *tok_iter;
++tok_iter;
idbassert(tok_iter != tokens.end());
tb = *tok_iter;
++tok_iter;
idbassert(tok_iter == tokens.end());
return make_pair(db, tb);
}
} }
// //
@@ -1988,7 +1961,7 @@ static bool get_field_default_value(THD *thd, Field *field, String *def_value,
int ha_calpont_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO* create_info, cal_connection_info& ci) int ha_calpont_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO* create_info, cal_connection_info& ci)
{ {
#ifdef INFINIDB_DEBUG #ifdef MCS_DEBUG
cout << "ha_calpont_impl_create_: " << name << endl; cout << "ha_calpont_impl_create_: " << name << endl;
#endif #endif
THD* thd = current_thd; THD* thd = current_thd;
@@ -2060,7 +2033,7 @@ int ha_calpont_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO*
if (isCreate) if (isCreate)
{ {
#ifdef INFINIDB_DEBUG #ifdef MCS_DEBUG
cout << "ha_calpont_impl_create_: SCHEMA SYNC ONLY found, returning" << endl; cout << "ha_calpont_impl_create_: SCHEMA SYNC ONLY found, returning" << endl;
#endif #endif
return 0; return 0;
@@ -2091,7 +2064,7 @@ int ha_calpont_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO*
{ {
ci.isAlter = true; ci.isAlter = true;
ci.alterTableState = cal_connection_info::ALTER_FIRST_RENAME; ci.alterTableState = cal_connection_info::ALTER_FIRST_RENAME;
#ifdef INFINIDB_DEBUG #ifdef MCS_DEBUG
cout << "ha_calpont_impl_create_: now in state ALTER_FIRST_RENAME" << endl; cout << "ha_calpont_impl_create_: now in state ALTER_FIRST_RENAME" << endl;
#endif #endif
} }
@@ -2269,7 +2242,7 @@ int ha_calpont_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO*
//Bug 1705 reset the flag if error occurs //Bug 1705 reset the flag if error occurs
ci.alterTableState = cal_connection_info::NOT_ALTER; ci.alterTableState = cal_connection_info::NOT_ALTER;
ci.isAlter = false; ci.isAlter = false;
#ifdef INFINIDB_DEBUG #ifdef MCS_DEBUG
cout << "ha_calpont_impl_create_: ProcessDDL error, now in state NOT_ALTER" << endl; cout << "ha_calpont_impl_create_: ProcessDDL error, now in state NOT_ALTER" << endl;
#endif #endif
} }
@@ -2279,7 +2252,7 @@ int ha_calpont_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO*
int ha_calpont_impl_delete_table_(const char* db, const char* name, cal_connection_info& ci) int ha_calpont_impl_delete_table_(const char* db, const char* name, cal_connection_info& ci)
{ {
#ifdef INFINIDB_DEBUG #ifdef MCS_DEBUG
cout << "ha_calpont_impl_delete_table: " << db << name << endl; cout << "ha_calpont_impl_delete_table: " << db << name << endl;
#endif #endif
THD* thd = current_thd; THD* thd = current_thd;
@@ -2295,7 +2268,6 @@ int ha_calpont_impl_delete_table_(const char* db, const char* name, cal_connecti
std::string stmt(query); std::string stmt(query);
algorithm::to_upper(stmt); algorithm::to_upper(stmt);
// cout << "ha_calpont_impl_delete_table: " << schema.c_str() << "." << tbl.c_str() << " " << stmt.c_str() << endl;
// @bug 4158 allow table name with 'restrict' in it (but not by itself) // @bug 4158 allow table name with 'restrict' in it (but not by itself)
std::string::size_type fpos; std::string::size_type fpos;
fpos = stmt.rfind(" RESTRICT"); fpos = stmt.rfind(" RESTRICT");
@@ -2334,7 +2306,6 @@ int ha_calpont_impl_delete_table_(const char* db, const char* name, cal_connecti
stmt += ";"; stmt += ";";
int rc = ProcessDDLStatement(stmt, schema, tbl, tid2sid(thd->thread_id), emsg); int rc = ProcessDDLStatement(stmt, schema, tbl, tid2sid(thd->thread_id), emsg);
// cout << "ProcessDDLStatement rc=" << rc << endl;
if (rc != 0) if (rc != 0)
{ {
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, emsg.c_str()); push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, emsg.c_str());
@@ -2343,6 +2314,7 @@ int ha_calpont_impl_delete_table_(const char* db, const char* name, cal_connecti
return rc; return rc;
} }
/** /**
@brief @brief
Find and return a pointer to the last slash in the name. Find and return a pointer to the last slash in the name.
@@ -2395,16 +2367,54 @@ void decode_table_name(char *buf, const char *path, size_t pathLen)
} }
} }
/**
@brief
Parses the path to extract both database and table names.
@details
Parses the path to extract both database
and table names, e.g path ./test/d$ produces
a pair of strings 'test' and 'd$'. This f() looks for a '/'
token only twice to allow '/' symbol in table names.
Called from ha_calpont_ddl.cpp by ha_calpont_impl_rename_table_().
*/
pair<string, string> parseTableName(const string& tn)
{
string db;
string tb;
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
#ifdef _MSC_VER
boost::char_separator<char> sep("\\");
#else
boost::char_separator<char> sep("/");
#endif
tokenizer tokens(tn, sep);
tokenizer::iterator tok_iter = tokens.begin();
++tok_iter;
idbassert(tok_iter != tokens.end());
db = *tok_iter;
++tok_iter;
idbassert(tok_iter != tokens.end());
tb = *tok_iter;
return make_pair(db, tb);
}
int ha_calpont_impl_rename_table_(const char* from, const char* to, cal_connection_info& ci) int ha_calpont_impl_rename_table_(const char* from, const char* to, cal_connection_info& ci)
{ {
THD* thd = current_thd; THD* thd = current_thd;
string emsg; string emsg;
// to and from are rewritten after decode_table_name()
// so use a copy of pntrs
const char* from_cpy = from;
const char* to_cpy = to;
pair<string, string> fromPair; pair<string, string> fromPair;
pair<string, string> toPair; pair<string, string> toPair;
string stmt; string stmt;
//this is replcated DDL, treat it just like SSO //this is replicated DDL, treat it just like SSO
if (thd->slave_thread) if (thd->slave_thread)
return 0; return 0;
@@ -2418,16 +2428,18 @@ int ha_calpont_impl_rename_table_(const char* from, const char* to, cal_connecti
} }
// MCOL-1855 Decode the table name if it contains encoded symbols. // MCOL-1855 Decode the table name if it contains encoded symbols.
// This approach fails when `/` is used in the paths. size_t pathLen = strlen(from_cpy);
size_t pathLen = strlen(from); char pathCopy[FN_REFLEN];
char pathCopy[pathLen]; decode_table_name(pathCopy, from_cpy, pathLen);
decode_table_name(pathCopy, from, pathLen);
fromPair = parseTableName(const_cast<const char*>(pathCopy)); fromPair = parseTableName(const_cast<const char*>(pathCopy));
pathLen = strlen(to); pathLen = strlen(to_cpy);
decode_table_name(pathCopy, to, pathLen); decode_table_name(pathCopy, to_cpy, pathLen);
toPair = parseTableName(const_cast<const char*>(pathCopy)); toPair = parseTableName(const_cast<const char*>(pathCopy));
// TBD The next two blocks must be removed to allow different dbnames
// in RENAME statement.
if (fromPair.first != toPair.first) if (fromPair.first != toPair.first)
{ {
thd->get_stmt_da()->set_overwrite_status(true); thd->get_stmt_da()->set_overwrite_status(true);