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

MCOL-4713 Analyze table implementation.

This commit is contained in:
Denis Khalikov
2021-06-11 02:07:04 +03:00
parent ceb73cddcd
commit c20015a7b2
18 changed files with 1837 additions and 208 deletions

View File

@ -200,6 +200,24 @@ const char** ha_mcs::bas_ext() const
return ha_mcs_exts;
}
int ha_mcs::analyze(THD* thd, HA_CHECK_OPT* check_opt)
{
DBUG_ENTER("ha_mcs::analyze");
int rc;
try
{
rc = ha_mcs_impl_analyze(thd, table);
}
catch (std::runtime_error& e)
{
thd->raise_error_printf(ER_INTERNAL_ERROR, e.what());
rc = ER_INTERNAL_ERROR;
}
DBUG_RETURN(rc);
}
/**
@brief
Used for opening tables. The name will be the name of the file.

View File

@ -126,6 +126,11 @@ public:
return (double) (stats.records + stats.deleted) / 20.0 + 10;
}
/** @brief
Analyze table command.
*/
int analyze(THD* thd, HA_CHECK_OPT* check_opt);
/*
Everything below are methods that we implement in ha_example.cc.

View File

@ -105,6 +105,7 @@ using namespace BRM;
using namespace querystats;
#include "calpontselectexecutionplan.h"
#include "mcsanalyzetableexecutionplan.h"
#include "calpontsystemcatalog.h"
#include "simplecolumn_int.h"
#include "simplecolumn_decimal.h"
@ -142,6 +143,7 @@ using namespace funcexp;
#include "ha_mcs_sysvars.h"
#include "ha_mcs_datatype.h"
#include "statistics.h"
namespace cal_impl_if
{
@ -1899,8 +1901,248 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector<COND*>& c
return rc;
}
inline bool isSupportedToAnalyze(const execplan::CalpontSystemCatalog::ColType& colType)
{
return colType.isUnsignedInteger() || colType.isSignedInteger();
}
// Initializes `cal_connection_info` using given `thd` and `sessionID`.
bool initializeCalConnectionInfo(cal_connection_info* ci, THD* thd,
boost::shared_ptr<execplan::CalpontSystemCatalog> csc,
uint32_t sessionID, bool localQuery)
{
ci->stats.reset();
ci->stats.setStartTime();
if (thd->main_security_ctx.user)
{
ci->stats.fUser = thd->main_security_ctx.user;
}
else
{
ci->stats.fUser = "";
}
if (thd->main_security_ctx.host)
ci->stats.fHost = thd->main_security_ctx.host;
else if (thd->main_security_ctx.host_or_ip)
ci->stats.fHost = thd->main_security_ctx.host_or_ip;
else
ci->stats.fHost = "unknown";
try
{
ci->stats.userPriority(ci->stats.fHost, ci->stats.fUser);
}
catch (std::exception& e)
{
string msg = string("Columnstore User Priority - ") + e.what();
ci->warningMsg = msg;
}
if (ci->queryState != 0)
{
sm::sm_cleanup(ci->cal_conn_hndl);
ci->cal_conn_hndl = 0;
}
sm::sm_init(sessionID, &ci->cal_conn_hndl, localQuery);
idbassert(ci->cal_conn_hndl != 0);
ci->cal_conn_hndl->csc = csc;
idbassert(ci->cal_conn_hndl->exeMgr != 0);
try
{
ci->cal_conn_hndl->connect();
}
catch (...)
{
setError(thd, ER_INTERNAL_ERROR, IDBErrorInfo::instance()->errorMsg(ERR_LOST_CONN_EXEMGR));
CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID);
return false;
}
return true;
}
bool sendExecutionPlanToExeMgr(sm::cpsm_conhdl_t* hndl, ByteStream::quadbyte qb,
std::shared_ptr<execplan::MCSAnalyzeTableExecutionPlan> caep,
cal_connection_info* ci, THD* thd)
{
ByteStream msg;
try
{
msg << qb;
hndl->exeMgr->write(msg);
msg.restart();
caep->rmParms(ci->rmParms);
// Send the execution plan.
caep->serialize(msg);
hndl->exeMgr->write(msg);
// Get the status from ExeMgr.
msg.restart();
msg = hndl->exeMgr->read();
// Any return code is ok for now.
if (msg.length() == 0)
{
auto emsg = "Lost connection to ExeMgr. Please contact your administrator";
setError(thd, ER_INTERNAL_ERROR, emsg);
return false;
}
}
catch (...)
{
return false;
}
return true;
}
} //anon namespace
int ha_mcs_impl_analyze(THD* thd, TABLE* table)
{
uint32_t sessionID = execplan::CalpontSystemCatalog::idb_tid2sid(thd->thread_id);
boost::shared_ptr<execplan::CalpontSystemCatalog> csc =
execplan::CalpontSystemCatalog::makeCalpontSystemCatalog(sessionID);
csc->identity(execplan::CalpontSystemCatalog::FE);
auto table_name =
execplan::make_table(table->s->db.str, table->s->table_name.str, lower_case_table_names);
// Skip for now.
if (table->s->db.length && strcmp(table->s->db.str, "information_schema") == 0)
return 0;
bool columnStore = (table ? isMCSTable(table) : true);
// Skip non columnstore tables.
if (!columnStore)
return 0;
execplan::CalpontSystemCatalog::RIDList oidlist = csc->columnRIDs(table_name, true);
execplan::MCSAnalyzeTableExecutionPlan::ReturnedColumnList returnedColumnList;
execplan::MCSAnalyzeTableExecutionPlan::ColumnMap columnMap;
// Iterate over table oid list and create a `SimpleColumn` for every column with supported type.
for (uint32_t i = 0, e = oidlist.size(); i < e; ++i)
{
execplan::SRCP returnedColumn;
const auto objNum = oidlist[i].objnum;
auto tableColName = csc->colName(objNum);
auto colType = csc->colType(objNum);
if (!isSupportedToAnalyze(colType))
continue;
execplan::SimpleColumn* simpleColumn = new execplan::SimpleColumn();
simpleColumn->columnName(tableColName.column);
simpleColumn->tableName(tableColName.table, lower_case_table_names);
simpleColumn->schemaName(tableColName.schema, lower_case_table_names);
simpleColumn->oid(objNum);
simpleColumn->alias(tableColName.column);
simpleColumn->resultType(colType);
simpleColumn->timeZone(thd->variables.time_zone->get_name()->ptr());
returnedColumn.reset(simpleColumn);
returnedColumnList.push_back(returnedColumn);
columnMap.insert(execplan::MCSAnalyzeTableExecutionPlan::ColumnMap::value_type(
simpleColumn->columnName(), returnedColumn));
}
// Create execution plan and initialize it with `returned columns` and `column map`.
std::shared_ptr<execplan::MCSAnalyzeTableExecutionPlan> caep(
new execplan::MCSAnalyzeTableExecutionPlan(returnedColumnList, columnMap));
caep->schemaName(table->s->db.str, lower_case_table_names);
caep->tableName(table->s->table_name.str, lower_case_table_names);
caep->timeZone(thd->variables.time_zone->get_name()->ptr());
SessionManager sm;
BRM::TxnID txnID;
txnID = sm.getTxnID(sessionID);
if (!txnID.valid)
{
txnID.id = 0;
txnID.valid = true;
}
QueryContext verID;
verID = sm.verID();
caep->txnID(txnID.id);
caep->verID(verID);
caep->sessionID(sessionID);
string query;
query.assign(idb_mysql_query_str(thd));
caep->data(query);
if (!get_fe_conn_info_ptr())
set_fe_conn_info_ptr(reinterpret_cast<void*>(new cal_connection_info(), thd));
cal_connection_info* ci = reinterpret_cast<cal_connection_info*>(get_fe_conn_info_ptr());
idbassert(ci != 0);
try
{
caep->priority(ci->stats.userPriority(ci->stats.fHost, ci->stats.fUser));
}
catch (std::exception& e)
{
string msg = string("Columnstore User Priority - ") + e.what();
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, msg.c_str());
}
if (thd->killed == KILL_QUERY || thd->killed == KILL_QUERY_HARD)
{
force_close_fep_conn(thd, ci);
return 0;
}
caep->traceFlags(ci->traceFlags);
cal_table_info ti;
sm::cpsm_conhdl_t* hndl;
bool localQuery = (get_local_query(thd) > 0 ? true : false);
caep->localQuery(localQuery);
// Try to initialize connection.
if (!initializeCalConnectionInfo(ci, thd, csc, sessionID, localQuery))
goto error;
hndl = ci->cal_conn_hndl;
if (caep->traceOn())
std::cout << caep->toString() << std::endl;
{
ByteStream::quadbyte qb = ANALYZE_TABLE_EXECUTE;
// Serialize and the send the `anlyze table` execution plan.
if (!sendExecutionPlanToExeMgr(hndl, qb, caep, ci, thd))
goto error;
}
ci->rmParms.clear();
ci->tableMap[table] = ti;
return 0;
error:
if (ci->cal_conn_hndl)
{
sm::sm_cleanup(ci->cal_conn_hndl);
ci->cal_conn_hndl = 0;
}
return ER_INTERNAL_ERROR;
}
int ha_mcs_impl_open(const char* name, int mode, uint32_t test_if_locked)
{
IDEBUG ( cout << "ha_mcs_impl_open: " << name << ", " << mode << ", " << test_if_locked << endl );

View File

@ -27,6 +27,7 @@ struct mcs_handler_info;
extern int ha_mcs_impl_discover_existence(const char* schema, const char* name);
extern int ha_mcs_impl_create(const char* name, TABLE* table_arg, HA_CREATE_INFO* create_info);
extern int ha_mcs_impl_delete_table(const char* name);
extern int ha_mcs_impl_analyze(THD* thd, TABLE* table);
extern int ha_mcs_impl_open(const char* name, int mode, uint32_t test_if_locked);
extern int ha_mcs_impl_close(void);
extern int ha_mcs_impl_rnd_next(uchar* buf, TABLE* table);