1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-30 19:23:07 +03:00

MCOL-5 We've had problems with CREATE and DELETE crashing. Add some better error handling

This commit is contained in:
David Hall
2016-08-12 16:57:51 -05:00
parent 6fa865d8de
commit 10e5ed83ce
4 changed files with 79 additions and 57 deletions

View File

@ -1880,7 +1880,13 @@ int ha_calpont_impl_create_(const char *name, TABLE *table_arg, HA_CREATE_INFO *
#endif #endif
THD *thd = current_thd; THD *thd = current_thd;
string stmt = idb_mysql_query_str(thd); char* query = thd->query();
if (!query)
{
setError(thd, ER_INTERNAL_ERROR, "Attempt to create table, but query is NULL");
return 1;
}
string stmt(query);
stmt += ";"; stmt += ";";
algorithm::to_upper(stmt); algorithm::to_upper(stmt);
@ -1894,23 +1900,11 @@ int ha_calpont_impl_create_(const char *name, TABLE *table_arg, HA_CREATE_INFO *
{ {
tablecomment = table_arg->s->comment.str; tablecomment = table_arg->s->comment.str;
try { try {
#ifndef SKIP_AUTOI
isAnyAutoincreCol = parseAutoincrementTableComment(tablecomment, startValue, columnName); isAnyAutoincreCol = parseAutoincrementTableComment(tablecomment, startValue, columnName);
#else
algorithm::to_upper(tablecomment);
if ( tablecomment.find("AUTOINCREMENT") != string::npos )
{
int rc = 1;
thd->get_stmt_da()->set_overwrite_status(true);
thd->raise_error_printf(ER_INTERNAL_ERROR, (IDBErrorInfo::instance()->errorMsg(ERR_CREATE_AUTOINCREMENT_NOT_SUPPORT)).c_str());
return rc;
}
#endif
} }
catch (runtime_error& ex) catch (runtime_error& ex)
{ {
thd->get_stmt_da()->set_overwrite_status(true); setError(thd, ER_INTERNAL_ERROR, ex.what());
thd->raise_error_printf(ER_INTERNAL_ERROR, ex.what());
return 1; return 1;
} }
algorithm::to_upper(tablecomment); algorithm::to_upper(tablecomment);
@ -1928,8 +1922,7 @@ int ha_calpont_impl_create_(const char *name, TABLE *table_arg, HA_CREATE_INFO *
&& tbl != "sysconstraint" && tbl != "sysindexcol" && tbl != "sysconstraint" && tbl != "sysindexcol"
&& tbl != "sysconstraintcol" ) && tbl != "sysconstraintcol" )
{ {
thd->get_stmt_da()->set_overwrite_status(true); setError(thd, ER_INTERNAL_ERROR, "Cannot create non-system Calpont tables in calpontsys database");
thd->raise_error_printf(ER_INTERNAL_ERROR, "Can not create non-system Calpont tables in calpontsys database");
return 1; return 1;
} }
@ -1938,18 +1931,18 @@ int ha_calpont_impl_create_(const char *name, TABLE *table_arg, HA_CREATE_INFO *
{ {
schemaSyncOnly = true; schemaSyncOnly = true;
pat = createpatstr; pat = createpatstr;
if (!regex_search(stmt, pat)) { if (!regex_search(stmt, pat))
{
isCreate = false; isCreate = false;
}
if (isCreate)
{
#ifdef INFINIDB_DEBUG
cout << "ha_calpont_impl_create_: SCHEMA SYNC ONLY found, returning" << endl;
#endif
return 0;
} }
else if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ALTER_VTABLE) //check if it is select if (isCreate)
{
#ifdef INFINIDB_DEBUG
cout << "ha_calpont_impl_create_: SCHEMA SYNC ONLY found, returning" << endl;
#endif
return 0;
}
if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ALTER_VTABLE) //check if it is select
{ {
return 0; return 0;
} }
@ -1958,14 +1951,12 @@ int ha_calpont_impl_create_(const char *name, TABLE *table_arg, HA_CREATE_INFO *
{ {
if (db == "calpontsys") if (db == "calpontsys")
{ {
thd->get_stmt_da()->set_overwrite_status(true); setError(thd, ER_INTERNAL_ERROR, "Calpont system tables can only be created with 'SCHEMA SYNC ONLY'");
thd->raise_error_printf(ER_INTERNAL_ERROR, "Calpont system tables can only be created with 'SCHEMA SYNC ONLY'"); return 1;
return 1;
} }
else if ( db == "infinidb_vtable") //@bug 3540. table created in infinidb_vtable schema could be dropped when select statement happen to have same tablename. else if ( db == "infinidb_vtable") //@bug 3540. table created in infinidb_vtable schema could be dropped when select statement happen to have same tablename.
{ {
thd->get_stmt_da()->set_overwrite_status(true); setError(thd, ER_INTERNAL_ERROR, "Table creation is not allowed in infinidb_vtable schema.");
thd->raise_error_printf(ER_INTERNAL_ERROR, "Table creation is not allowed in infinidb_vtable schema.");
return 1; return 1;
} }
} }
@ -1980,7 +1971,7 @@ int ha_calpont_impl_create_(const char *name, TABLE *table_arg, HA_CREATE_INFO *
} }
string emsg; string emsg;
stmt = idb_mysql_query_str(thd); stmt = thd->query();
stmt += ";"; stmt += ";";
int rc = 0; int rc = 0;
@ -1997,20 +1988,18 @@ int ha_calpont_impl_create_(const char *name, TABLE *table_arg, HA_CREATE_INFO *
if (ci.isSlaveNode) if (ci.isSlaveNode)
{ {
string emsg = logging::IDBErrorInfo::instance()->errorMsg(ERR_DML_DDL_SLAVE); string emsg = logging::IDBErrorInfo::instance()->errorMsg(ERR_DML_DDL_SLAVE);
setError(current_thd, ER_CHECK_NOT_IMPLEMENTED, emsg); setError(thd, ER_CHECK_NOT_IMPLEMENTED, emsg);
return 1; return 1;
} }
// @bug 3908. error out primary key for now. // @bug 3908. error out primary key for now.
if (table_arg->key_info && table_arg->key_info->name && string(table_arg->key_info->name) == "PRIMARY") if (table_arg->key_info && table_arg->key_info->name && string(table_arg->key_info->name) == "PRIMARY")
{ {
rc = 1; string emsg = logging::IDBErrorInfo::instance()->errorMsg(ERR_CONSTRAINTS);
Message::Args args; setError(thd, ER_CHECK_NOT_IMPLEMENTED, emsg);
thd->get_stmt_da()->set_overwrite_status(true);
thd->raise_error_printf(ER_CHECK_NOT_IMPLEMENTED, (IDBErrorInfo::instance()->errorMsg(ERR_CONSTRAINTS, args)).c_str());
ci.alterTableState = cal_connection_info::NOT_ALTER; ci.alterTableState = cal_connection_info::NOT_ALTER;
ci.isAlter = false; ci.isAlter = false;
return rc; return 1;
} }
int compressiontype = thd->variables.infinidb_compression_type; int compressiontype = thd->variables.infinidb_compression_type;
@ -2026,19 +2015,18 @@ int ha_calpont_impl_create_(const char *name, TABLE *table_arg, HA_CREATE_INFO *
compressiontype = thd->variables.infinidb_compression_type; compressiontype = thd->variables.infinidb_compression_type;
else if ( compressiontype < 0 ) else if ( compressiontype < 0 )
{ {
rc = 1; string emsg = IDBErrorInfo::instance()->errorMsg(ERR_INVALID_COMPRESSION_TYPE);
thd->raise_error_printf(ER_INTERNAL_ERROR, (IDBErrorInfo::instance()->errorMsg(ERR_INVALID_COMPRESSION_TYPE)).c_str()); setError(thd, ER_INTERNAL_ERROR, emsg);
ci.alterTableState = cal_connection_info::NOT_ALTER; ci.alterTableState = cal_connection_info::NOT_ALTER;
ci.isAlter = false; ci.isAlter = false;
return rc; return 1;
} }
//hdfs //hdfs
if ((compressiontype ==0) && (useHdfs)) if ((compressiontype ==0) && (useHdfs))
{ {
compressiontype = 2; compressiontype = 2;
string errmsg ("The table is created with Columnstore compression type 2 under HDFS." ); push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, "The table is created with Columnstore compression type 2 under HDFS.");
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, errmsg.c_str());
} }
if (compressiontype == 1) compressiontype = 2; if (compressiontype == 1) compressiontype = 2;
@ -2046,20 +2034,20 @@ int ha_calpont_impl_create_(const char *name, TABLE *table_arg, HA_CREATE_INFO *
IDBCompressInterface idbCompress; IDBCompressInterface idbCompress;
if ( ( compressiontype > 0 ) && !(idbCompress.isCompressionAvail( compressiontype )) ) if ( ( compressiontype > 0 ) && !(idbCompress.isCompressionAvail( compressiontype )) )
{ {
rc = 1; string emsg = IDBErrorInfo::instance()->errorMsg(ERR_INVALID_COMPRESSION_TYPE);
thd->raise_error_printf(ER_INTERNAL_ERROR, (IDBErrorInfo::instance()->errorMsg(ERR_INVALID_COMPRESSION_TYPE)).c_str()); setError(thd, ER_INTERNAL_ERROR, emsg);
ci.alterTableState = cal_connection_info::NOT_ALTER; ci.alterTableState = cal_connection_info::NOT_ALTER;
ci.isAlter = false; ci.isAlter = false;
return rc; return 1;
} }
rc = ProcessDDLStatement(stmt, db, tbl, tid2sid(thd->thread_id), emsg, compressiontype, isAnyAutoincreCol, startValue, columnName); rc = ProcessDDLStatement(stmt, db, tbl, tid2sid(thd->thread_id), emsg, compressiontype, isAnyAutoincreCol, startValue, columnName);
if (rc != 0) { if (rc != 0) {
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, 9999, emsg.c_str()); push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, emsg.c_str());
//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 INFINIDB_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
@ -2075,7 +2063,13 @@ int ha_calpont_impl_delete_table_(const char *db, const char *name, cal_connecti
THD *thd = current_thd; THD *thd = current_thd;
std::string tbl(name); std::string tbl(name);
std::string schema(db); std::string schema(db);
std::string stmt(idb_mysql_query_str(thd)); char* query = thd->query();
if (!query)
{
setError(thd, ER_INTERNAL_ERROR, "Attempt to drop table, but query is NULL");
return 1;
}
std::string stmt(query);
algorithm::to_upper(stmt); algorithm::to_upper(stmt);
// @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;
@ -2094,16 +2088,16 @@ int ha_calpont_impl_delete_table_(const char *db, const char *name, cal_connecti
if (ci.isSlaveNode) if (ci.isSlaveNode)
{ {
string emsg = logging::IDBErrorInfo::instance()->errorMsg(ERR_DML_DDL_SLAVE); string emsg = logging::IDBErrorInfo::instance()->errorMsg(ERR_DML_DDL_SLAVE);
setError(current_thd, ER_CHECK_NOT_IMPLEMENTED, emsg); setError(thd, ER_CHECK_NOT_IMPLEMENTED, emsg);
return 1; return 1;
} }
string emsg; string emsg;
stmt = idb_mysql_query_str(thd); stmt = thd->query();
stmt += ";"; stmt += ";";
int rc = ProcessDDLStatement(stmt, schema, tbl, tid2sid(thd->thread_id), emsg); int rc = ProcessDDLStatement(stmt, schema, tbl, tid2sid(thd->thread_id), emsg);
if (rc != 0) if (rc != 0)
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, 9999, emsg.c_str()); push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, emsg.c_str());
return rc; return rc;
} }

View File

@ -1841,7 +1841,6 @@ void setError(THD* thd, uint32_t errcode, string errmsg)
thd->infinidb_vtable.cal_conn_info = (void*)(new cal_connection_info()); thd->infinidb_vtable.cal_conn_info = (void*)(new cal_connection_info());
cal_connection_info* ci = reinterpret_cast<cal_connection_info*>(thd->infinidb_vtable.cal_conn_info); cal_connection_info* ci = reinterpret_cast<cal_connection_info*>(thd->infinidb_vtable.cal_conn_info);
ci->expressionId = 0; ci->expressionId = 0;
} }
void setError(THD* thd, uint32_t errcode, string errmsg, gp_walk_info& gwi) void setError(THD* thd, uint32_t errcode, string errmsg, gp_walk_info& gwi)

View File

@ -3123,6 +3123,18 @@ int ha_calpont_impl_create(const char *name, TABLE *table_arg, HA_CREATE_INFO *c
//@Bug 1948. Mysql calls create table to create a new table with new signature. //@Bug 1948. Mysql calls create table to create a new table with new signature.
if (ci->alterTableState > 0) return 0; if (ci->alterTableState > 0) return 0;
// Just to be sure
if (!table_arg)
{
setError(thd, ER_INTERNAL_ERROR, "ha_calpont_impl_create_: table_arg is NULL");
return 1;
}
if (!table_arg->s)
{
setError(thd, ER_INTERNAL_ERROR, "ha_calpont_impl_create_: table_arg->s is NULL");
return 1;
}
int rc = ha_calpont_impl_create_(name, table_arg, create_info, *ci); int rc = ha_calpont_impl_create_(name, table_arg, create_info, *ci);
return rc; return rc;
@ -3130,11 +3142,17 @@ int ha_calpont_impl_create(const char *name, TABLE *table_arg, HA_CREATE_INFO *c
int ha_calpont_impl_delete_table(const char *name) int ha_calpont_impl_delete_table(const char *name)
{ {
THD *thd = current_thd;
if (!name)
{
setError(thd, ER_INTERNAL_ERROR, "Drop Table with NULL name not permitted");
return 1;
}
//if this is an InfiniDB tmp table ('#sql*.frm') just leave... //if this is an InfiniDB tmp table ('#sql*.frm') just leave...
if (!memcmp((uchar*)name, tmp_file_prefix, tmp_file_prefix_length)) return 0; if (!memcmp((uchar*)name, tmp_file_prefix, tmp_file_prefix_length)) return 0;
THD *thd = current_thd;
// @bug1940 Do nothing for select query. Support of set default engine to IDB. // @bug1940 Do nothing for select query. Support of set default engine to IDB.
if (string(name).find("@0024vtable") != string::npos) if (string(name).find("@0024vtable") != string::npos)
return 0; return 0;
@ -3156,6 +3174,11 @@ int ha_calpont_impl_delete_table(const char *name)
} }
TABLE_LIST *first_table= (TABLE_LIST*) thd->lex->select_lex.table_list.first; TABLE_LIST *first_table= (TABLE_LIST*) thd->lex->select_lex.table_list.first;
if (!first_table->db)
{
setError(thd, ER_INTERNAL_ERROR, "Drop Table with NULL schema not permitted");
return 1;
}
if (!ci) return 0; if (!ci) return 0;

View File

@ -35,10 +35,16 @@ template <class T> bool isnan(T);
#ifdef _DEBUG #ifdef _DEBUG
#ifndef _MSC_VER #ifndef _MSC_VER
#ifndef SAFE_MUTEX
#define SAFE_MUTEX #define SAFE_MUTEX
#endif
#ifndef SAFEMALLOC
#define SAFEMALLOC #define SAFEMALLOC
#endif #endif
#endif
#ifndef ENABLED_DEBUG_SYNC
#define ENABLED_DEBUG_SYNC #define ENABLED_DEBUG_SYNC
#endif
#define INFINIDB_DEBUG #define INFINIDB_DEBUG
#define DBUG_ON 1 #define DBUG_ON 1
#undef DBUG_OFF #undef DBUG_OFF