!466 MOT fixes and code cleanup

Merge pull request !466 from Vinoth Veeraraghavan/master
This commit is contained in:
opengauss-bot 2020-12-11 15:14:35 +08:00 committed by Gitee
commit db55fa203c
75 changed files with 1880 additions and 1931 deletions

View File

@ -13802,6 +13802,22 @@ static void dumpForeignDataWrapper(Archive* fout, FdwInfo* fdwinfo)
destroyPQExpBuffer(labelq);
}
static inline bool IsDefaultForeignServer(const char* serverName)
{
/*
* gsmpp_server, gsmpp_errorinfo_server, mot_server are created by default at the time of initdb.
*/
if ((0 == strncmp(serverName, "gsmpp_server", strlen("gsmpp_server") + 1)) ||
(0 == strncmp(serverName, "\"gsmpp_server\"", strlen("\"gsmpp_server\"") + 1)) ||
(0 == strncmp(serverName, "gsmpp_errorinfo_server", strlen("gsmpp_errorinfo_server") + 1)) ||
(0 == strncmp(serverName, "\"gsmpp_errorinfo_server\"", strlen("\"gsmpp_errorinfo_server\"") + 1)) ||
(0 == strncmp(serverName, "mot_server", strlen("mot_server") + 1)) ||
(0 == strncmp(serverName, "\"mot_server\"", strlen("\"mot_server\"") + 1))) {
return true;
}
return false;
}
/*
* dumpForeignServer
* write out a foreign server definition
@ -13823,17 +13839,13 @@ static void dumpForeignServer(Archive* fout, ForeignServerInfo* srvinfo)
if (isExecUserNotObjectOwner(fout, srvinfo->rolname))
return;
/*
* gsmpp_server, gsmpp_errorinfo_server, mot_server are created by default at the time of initdb,
* so. skip it.
* so skip it.
*/
qsrvname = gs_strdup(fmtId(srvinfo->dobj.name));
if ((0 == strncmp(qsrvname, "gsmpp_server", strlen("gsmpp_server") + 1)) ||
(0 == strncmp(qsrvname, "\"gsmpp_server\"", strlen("\"gsmpp_server\"") + 1)) ||
(0 == strncmp(qsrvname, "gsmpp_errorinfo_server", strlen("gsmpp_errorinfo_server") + 1)) ||
(0 == strncmp(qsrvname, "\"gsmpp_errorinfo_server\"", strlen("\"gsmpp_errorinfo_server\"") + 1)) ||
(0 == strncmp(qsrvname, "mot_server", strlen("mot_server") + 1)) ||
(0 == strncmp(qsrvname, "\"mot_server\"", strlen("\"mot_server\"") + 1))) {
if (IsDefaultForeignServer(qsrvname)) {
free(qsrvname);
qsrvname = NULL;
return;

View File

@ -1474,7 +1474,7 @@ static void MotFdwDropForeignIndex(Relation userHeapRelation, Relation userIndex
{
/* Forward drop stmt to MOT FDW. */
if (RelationIsForeignTable(userHeapRelation) && isMOTFromTblOid(RelationGetRelid(userHeapRelation))) {
FdwRoutine* fdwroutine = GetFdwRoutineByRelId(userHeapRelation->rd_id);
FdwRoutine* fdwroutine = GetFdwRoutineByRelId(RelationGetRelid(userHeapRelation));
if (fdwroutine->ValidateTableDef != NULL) {
DropForeignStmt stmt;
stmt.type = T_DropForeignStmt;
@ -3885,13 +3885,13 @@ static void MotFdwReindex(Relation heapRelation, Relation iRel)
{
/* Forward reindex stmt to MOT FDW. */
if (RelationIsForeignTable(heapRelation) && isMOTFromTblOid(RelationGetRelid(heapRelation))) {
FdwRoutine* fdwroutine = GetFdwRoutineByRelId(heapRelation->rd_id);
FdwRoutine* fdwroutine = GetFdwRoutineByRelId(RelationGetRelid(heapRelation));
if (fdwroutine->ValidateTableDef != NULL) {
ReindexForeignStmt stmt;
stmt.type = T_ReindexStmt;
stmt.relkind = RELKIND_INDEX;
stmt.reloid = heapRelation->rd_id;
stmt.indexoid = iRel->rd_id;
stmt.reloid = RelationGetRelid(heapRelation);
stmt.indexoid = RelationGetRelid(iRel);
stmt.name = iRel->rd_rel->relname.data;
fdwroutine->ValidateTableDef((Node*)&stmt);

View File

@ -340,6 +340,11 @@ static void knl_g_bgworker_init(knl_g_bgworker_context* bgworker_cxt)
bgworker_cxt->have_crashed_worker = false;
}
static void knl_g_mot_init(knl_g_mot_context* mot_cxt)
{
mot_cxt->jitExecMode = JitExec::JIT_EXEC_MODE_INVALID;
}
void knl_instance_init()
{
g_instance.binaryupgrade = false;
@ -388,6 +393,7 @@ void knl_instance_init()
knl_g_dw_init(&g_instance.dw_cxt);
knl_g_xlog_init(&g_instance.xlog_cxt);
knl_g_numa_init(&g_instance.numa_cxt);
knl_g_mot_init(&g_instance.mot_cxt);
knl_g_bgworker_init(&g_instance.bgworker_cxt);
MemoryContextSwitchTo(old_cxt);

View File

@ -1405,7 +1405,6 @@ static void knl_t_mot_init(knl_t_mot_context* mot_cxt)
mot_cxt->log_line_overflow = false;
mot_cxt->log_line_buf = NULL;
mot_cxt->log_level = 3; // the equivalent of MOT::LogLevel::LL_INFO
mot_cxt->init_codegen_once = false;
mot_cxt->currentThreadId = (uint16_t)-1;
mot_cxt->currentNumaNodeId = (-2);

View File

@ -91,6 +91,25 @@ OpFusion::OpFusion(MemoryContext context, CachedPlanSource* psrc, List* plantree
m_tmpisnull = NULL;
}
FusionType OpFusion::GetMotFusionType(PlannedStmt* plannedStmt)
{
FusionType result;
switch (plannedStmt->commandType) {
case CMD_SELECT:
result = MOT_JIT_SELECT_FUSION;
break;
case CMD_INSERT:
case CMD_UPDATE:
case CMD_DELETE:
result = MOT_JIT_MODIFY_FUSION;
break;
default:
result = NOBYPASS_NO_QUERY_TYPE;
break;
}
return result;
}
FusionType OpFusion::getFusionType(CachedPlan* plan, ParamListInfo params, List* plantree_list)
{
if (IsInitdb == true) {
@ -130,17 +149,7 @@ FusionType OpFusion::getFusionType(CachedPlan* plan, ParamListInfo params, List*
FusionType result = NONE_FUSION;
if (plan && plan->mot_jit_context && JitExec::IsMotCodegenEnabled()) {
if (((PlannedStmt*)st)->commandType == CMD_SELECT) {
result = MOT_JIT_SELECT_FUSION;
} else if (((PlannedStmt*)st)->commandType == CMD_INSERT) {
result = MOT_JIT_MODIFY_FUSION;
} else if (((PlannedStmt*)st)->commandType == CMD_UPDATE) {
result = MOT_JIT_MODIFY_FUSION;
} else if (((PlannedStmt*)st)->commandType == CMD_DELETE) {
result = MOT_JIT_MODIFY_FUSION;
} else {
result = NOBYPASS_NO_QUERY_TYPE;
}
result = GetMotFusionType(planned_stmt);
} else {
if (planned_stmt->subplans != NULL || planned_stmt->initPlan != NULL) {
return NOBYPASS_NO_SIMPLE_PLAN;

View File

@ -103,9 +103,8 @@ else
endif
endif
ifeq ($(CC_VERSION), 8.2.0)
CFLAGS += -faligned-new
endif
CFLAGS += -faligned-new
# turn on some warnings
CFLAGS += -Wwrite-strings -Wcast-align -Wreturn-type
CFLAGS += -Wpointer-arith -Wlogical-op -Waddress -Wsizeof-pointer-memaccess -Winit-self
@ -143,9 +142,7 @@ endif
LDFLAGS += $(CFLAGS)
ifeq ($(CC_VERSION), 8.2.0)
LDFLAGS += -latomic
endif
LDFLAGS += -latomic
INCLUDE += -I$(JEMALLOC_INCLUDE_PATH)
PYREPLICA :=

View File

@ -62,7 +62,7 @@ bool OccTransactionManager::Init()
bool OccTransactionManager::QuickVersionCheck(const Access* access)
{
// We always validate on commited rows!
// We always validate on committed rows!
const Row* row = access->GetRowFromHeader();
return (row->m_rowHeader.GetCSN() == access->m_tid);
}
@ -77,13 +77,25 @@ bool OccTransactionManager::QuickHeaderValidation(const Access* access)
// For upgrade we verify the row
// csn has not changed!
Sentinel* sent = access->m_origSentinel;
if (access->m_params.IsUpgradeInsert() and access->m_params.IsDummyDeletedRow() == false) {
if (sent->GetData()->GetCommitSequenceNumber() != access->m_tid) {
return false;
if (access->m_params.IsUpgradeInsert()) {
if (access->m_params.IsDummyDeletedRow()) {
// Check is sentinel is deleted and CSN is VALID - ABA problem
if (sent->IsCommited() == false) {
if (sent->GetData()->GetCommitSequenceNumber() != access->m_tid) {
return false;
}
} else {
return false;
}
} else {
// We deleted internally!, we only need to check version
if (sent->GetData()->GetCommitSequenceNumber() != access->m_tid) {
return false;
}
}
} else {
// if the sent is commited we abort!
if (sent->IsCommited()) {
// If the sent is committed or inserted-deleted we abort!
if (sent->IsCommited() or sent->GetData() != nullptr) {
return false;
}
}
@ -113,11 +125,11 @@ bool OccTransactionManager::ValidateWriteSet(TxnManager* txMan)
TxnOrderedSet_t& orderedSet = txMan->m_accessMgr->GetOrderedRowSet();
for (const auto& raPair : orderedSet) {
const Access* ac = raPair.second;
if (ac->m_type == RD or !ac->m_params.IsPrimarySentinel()) {
if (ac->m_type == RD) {
continue;
}
if (!ac->GetRowFromHeader()->m_rowHeader.ValidateWrite(ac->m_tid)) {
if (!QuickHeaderValidation(ac)) {
return false;
}
}
@ -167,8 +179,8 @@ RC OccTransactionManager::LockHeaders(TxnManager* txMan, uint32_t& numSentinelsL
if (ac->m_params.IsPrimaryUpgrade()) {
ac->m_auxRow->m_rowHeader.Lock();
}
// New insert row is already commited!
// Check if row has chainged in sentinel
// New insert row is already committed!
// Check if row has changed in sentinel
if (!QuickHeaderValidation(ac)) {
rc = RC_ABORT;
goto final;

View File

@ -84,7 +84,8 @@ ConfigTree* CmdLineConfigLoader::ParseCmdLine(char** argv, int argc)
mot_string key;
mot_string value;
bool parseError = false;
int arrayIndex = 0;
uint64_t arrayIndex = 0;
bool hasArrayIndex = false;
for (int i = 0; i < argc && !parseError; ++i) {
if (!line.assign(argv[i])) {
@ -114,12 +115,13 @@ ConfigTree* CmdLineConfigLoader::ParseCmdLine(char** argv, int argc)
currentSection = itr->second;
// parse the key-value part
if (!ConfigFileParser::ParseKeyValue(keyValuePart, sectionFullName, key, value, arrayIndex)) {
if (!ConfigFileParser::ParseKeyValue(
keyValuePart, sectionFullName, key, value, arrayIndex, hasArrayIndex)) {
// key-value line malformed
parseError = true;
} else {
// check for array item
if (arrayIndex == -1) {
if (!hasArrayIndex) {
ConfigItem* configItem = ConfigFileParser::MakeConfigValue(sectionFullName, key, value);
if (configItem == nullptr) {
REPORT_PARSE_ERROR(MOT_ERROR_INTERNAL,
@ -142,14 +144,14 @@ ConfigTree* CmdLineConfigLoader::ParseCmdLine(char** argv, int argc)
}
}
// create item and add it to array
if ((uint32_t)arrayIndex != configArray->GetConfigItemCount()) {
if (arrayIndex != configArray->GetConfigItemCount()) {
// array items must be ordered
REPORT_PARSE_ERROR(MOT_ERROR_INVALID_CFG,
"Failed to parse command line arguments: array %s items not well-ordered, "
"expecting %u, got %u (command line argument: %s)",
"expecting %u, got %" PRIu64 " (command line argument: %s)",
configArray->GetName(),
configArray->GetConfigItemCount(),
(uint32_t)arrayIndex,
arrayIndex,
argv[i]);
} else {
ConfigItem* configItem =
@ -160,7 +162,7 @@ ConfigTree* CmdLineConfigLoader::ParseCmdLine(char** argv, int argc)
value.c_str());
} else if (!configArray->AddConfigItem(configItem)) {
REPORT_PARSE_ERROR(MOT_ERROR_OOM,
"Failed to add %dth item to configuration array %s",
"Failed to add %" PRIu64 "th item to configuration array %s",
arrayIndex,
configArray->GetName());
}

View File

@ -35,10 +35,10 @@ static void FormatTime(uint64_t timeVal, char* buf, uint32_t len)
struct tm t;
if (localtime_r(&(ts.tv_sec), &t) != NULL) {
int ret = strftime(buf, len, "%F %T", &t);
size_t ret = strftime(buf, len, "%F %T", &t);
if (ret != 0) {
len -= ret - 1;
errno_t erc = snprintf_s(&buf[strlen(buf)], len, len - 1, ".%09ld", ts.tv_nsec);
len -= ret;
errno_t erc = snprintf_s(buf + ret, len, len - 1, ".%09ld", ts.tv_nsec);
securec_check_ss(erc, "\0", "\0");
}
}

View File

@ -58,10 +58,11 @@ bool ConfigFileParser::BreakSectionName(const mot_string& sectionFullName, mot_s
return result;
}
bool ConfigFileParser::ParseKeyValue(
const mot_string& keyValuePart, const mot_string& section, mot_string& key, mot_string& value, int& arrayIndex)
bool ConfigFileParser::ParseKeyValue(const mot_string& keyValuePart, const mot_string& section, mot_string& key,
mot_string& value, uint64_t& arrayIndex, bool& hasArrayIndex)
{
bool result = false;
hasArrayIndex = false;
uint32_t equalPos = keyValuePart.find('=');
if (equalPos == mot_string::npos) {
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL,
@ -73,7 +74,6 @@ bool ConfigFileParser::ParseKeyValue(
} else {
key.trim();
value.trim();
arrayIndex = -1;
result = true;
// check for array item
@ -85,9 +85,8 @@ bool ConfigFileParser::ParseKeyValue(
MOT_REPORT_ERROR(
MOT_ERROR_INTERNAL, "Load Configuration", "Failed to parse integer part from array item specifier");
} else {
uint64_t intValue = 0;
if (ParseUIntValue(section, key, intPart, intValue, true)) {
arrayIndex = (int)intValue;
if (ParseUIntValue(section, key, intPart, arrayIndex, true)) {
hasArrayIndex = true;
key.substr_inplace(0, poundPos);
result = true;
} else {

View File

@ -53,11 +53,12 @@ public:
* @param section The containing section (for error message in case of failure).
* @param[out] key The resulting key.
* @param[out] value The resulting value.
* @param[out] arrayIndex The array index in case of array item, or -1 if not.
* @param[out] arrayIndex The array index in case of array item.
* @param[out] hasArrayIndex Returns true if the key specifies an array item.
* @return True if parsing was successful.
*/
static bool ParseKeyValue(
const mot_string& keyValuePart, const mot_string& section, mot_string& key, mot_string& value, int& arrayIndex);
static bool ParseKeyValue(const mot_string& keyValuePart, const mot_string& section, mot_string& key,
mot_string& value, uint64_t& arrayIndex, bool& hasArrayIndex);
/**
* @brief Creates a typed configuration value.

View File

@ -87,7 +87,8 @@ ConfigTree* PropsConfigFileLoader::LoadConfigFile(const char* configFilePath)
mot_string key;
mot_string value;
bool parseError = false;
int arrayIndex = 0;
uint64_t arrayIndex = 0;
bool hasArrayIndex = false;
// unsupported yet
FileLineReader reader(configFilePath);
@ -131,7 +132,8 @@ ConfigTree* PropsConfigFileLoader::LoadConfigFile(const char* configFilePath)
currentSection = itr->second;
// parse the key-value part
if (!ConfigFileParser::ParseKeyValue(keyValuePart, sectionFullName, key, value, arrayIndex)) {
if (!ConfigFileParser::ParseKeyValue(
keyValuePart, sectionFullName, key, value, arrayIndex, hasArrayIndex)) {
// key-value line malformed
REPORT_PARSE_ERROR(MOT_ERROR_INVALID_CFG,
"Failed to parse configuration file %s at line %d: %s (key/value malformed)",
@ -140,7 +142,7 @@ ConfigTree* PropsConfigFileLoader::LoadConfigFile(const char* configFilePath)
line.c_str());
} else {
// check for array item
if (arrayIndex == -1) {
if (!hasArrayIndex) {
ConfigItem* configItem = ConfigFileParser::MakeConfigValue(sectionFullName, key, value);
if (configItem == nullptr) {
REPORT_PARSE_ERROR(MOT_ERROR_INTERNAL,
@ -162,17 +164,17 @@ ConfigTree* PropsConfigFileLoader::LoadConfigFile(const char* configFilePath)
MOT_ERROR_OOM, "Failed to add configuration array to parent section");
}
}
if ((uint32_t)arrayIndex != configArray->GetConfigItemCount()) {
if (arrayIndex != configArray->GetConfigItemCount()) {
// array items must be ordered
REPORT_PARSE_ERROR(MOT_ERROR_INVALID_CFG,
"Failed to parse configuration file %s at line %d: %s (array %s items not "
"well-ordered, expecting %u, got %u)",
"well-ordered, expecting %u, got %" PRIu64 ")",
configFilePath,
reader.GetLineNumber(),
line.c_str(),
configArray->GetName(),
configArray->GetConfigItemCount(),
(uint32_t)arrayIndex);
arrayIndex);
} else {
ConfigItem* configItem =
ConfigFileParser::MakeArrayConfigValue(sectionFullName, arrayIndex, value);
@ -180,7 +182,7 @@ ConfigTree* PropsConfigFileLoader::LoadConfigFile(const char* configFilePath)
REPORT_PARSE_ERROR(MOT_ERROR_INTERNAL, "Failed to create configuration array value");
} else if (!configArray->AddConfigItem(configItem)) {
REPORT_PARSE_ERROR(MOT_ERROR_OOM,
"Failed to add %dth item to configuration array %s",
"Failed to add %" PRIu64 "th item to configuration array %s",
arrayIndex,
configArray->GetName());
}

View File

@ -102,14 +102,11 @@ mot_string GlobalStatistics::MakeName(const char* baseName, NamingScheme namingS
return result;
}
bool GlobalStatistics::RegisterStatistics(StatisticVariable* statVar)
void GlobalStatistics::RegisterStatistics(StatisticVariable* statVar)
{
bool result = true;
if (!m_statVars.push_back(statVar)) {
MOT_REPORT_ERROR(
MOT_ERROR_OOM, "Register Statistics", "Failed to register statistics variable %s", statVar->GetName());
result = false;
}
return result;
}
} // namespace MOT

View File

@ -125,9 +125,10 @@ protected:
/**
* Allows derived classes to register their statistic variables.
* @param stat_var The statistic variable to register.
* @return True if registration succeeded, otherwise false.
* @note In case of failure the system continues to operate, but the
* statistics variable will not be periodically reported to the log.
*/
bool RegisterStatistics(StatisticVariable* statVar);
void RegisterStatistics(StatisticVariable* statVar);
private:
/** @var The set of managed statistic variables. */

View File

@ -128,9 +128,8 @@ mot_string ThreadStatistics::MakeName(const char* baseName, uint64_t threadId)
return result;
}
bool ThreadStatistics::RegisterStatistics(StatisticVariable* statVar)
void ThreadStatistics::RegisterStatistics(StatisticVariable* statVar)
{
bool result = false;
if (!m_statVars.push_back(statVar)) {
MOT_REPORT_ERROR(
MOT_ERROR_OOM, "Register Statistics", "Failed to add statistic variable %s", statVar->GetName());
@ -139,9 +138,6 @@ bool ThreadStatistics::RegisterStatistics(StatisticVariable* statVar)
"Register Statistics",
"Failed to add valid thread slot for statistic variable %s",
statVar->GetName());
} else {
result = true;
}
return result;
}
} // namespace MOT

View File

@ -170,9 +170,10 @@ protected:
/**
* @brief Allows derived classes to register their statistic variables.
* @param statVar The statistic variable to register.
* @return True if registration succeede, otherwise false.
* @note In case of failure the system continues to operate, but the
* statistics variable will not be periodically reported to the log.
*/
bool RegisterStatistics(StatisticVariable* statVar);
void RegisterStatistics(StatisticVariable* statVar);
private:
/** @var The logical identifier of the thread to which this set of statistic variables belong. */

View File

@ -940,6 +940,7 @@ static inline uint32_t PushSuperChunk(MemRawChunkPool* chunkPool, MemRawChunkHea
chunkPool->m_poolName,
chunksPushed,
count);
FreeChunk(chunkPool, chunk);
break;
}
}

View File

@ -14,7 +14,7 @@
* -------------------------------------------------------------------------
*
* object_pool.cpp
* Object pool implementation.
* Object pool interfaces.
*
* IDENTIFICATION
* src/gausskernel/storage/mot/core/src/memory/object_pool.cpp
@ -25,143 +25,7 @@
#include "object_pool.h"
namespace MOT {
IMPLEMENT_CLASS_LOGGER(ObjAllocInterface, Memory)
IMPLEMENT_CLASS_LOGGER(SlabAllocator, Memory)
IMPLEMENT_CLASS_LOGGER(ObjPool, Memory)
ObjPoolPtr::ObjPoolPtr(ObjPool* target)
{
m_data.m_ptr = target;
if (target != NULL)
m_data.m_slice[LIST_PTR_SLICE_IX] = target->m_listCounter;
}
ObjPoolPtr& ObjPoolPtr::operator=(ObjPool* right)
{
m_data.m_ptr = right;
if (right != NULL)
m_data.m_slice[LIST_PTR_SLICE_IX] = right->m_listCounter;
return *this;
}
ObjAllocInterface* ObjAllocInterface::GetObjPool(uint16_t size, bool local, uint8_t align)
{
ObjAllocInterface* result = NULL;
if (local) {
result = new (std::nothrow) LocalObjPool(size, align);
} else {
result = new (std::nothrow) GlobalObjPool(size, align);
}
if (result == NULL) {
MOT_REPORT_ERROR(MOT_ERROR_OOM,
"Allocate Object Pool",
"Failed to allocate memory for %s object pool",
local ? "local" : "global");
} else if (!result->Initialize()) {
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL,
"Allocate Object Pool",
"Failed to pre-allocate memory for %s object pool",
local ? "local" : "global");
delete result;
result = NULL;
}
return result;
}
void ObjAllocInterface::FreeObjPool(ObjAllocInterface** pool)
{
if (pool != NULL && *pool != NULL) {
delete *pool;
*pool = NULL;
}
}
ObjAllocInterface::~ObjAllocInterface()
{
ObjPool* p = m_objList;
while (p != NULL) {
ObjPool* tmp = p;
p = p->m_next;
ObjPool::DelObjPool(tmp, m_type, m_global);
}
}
inline MemBufferClass ObjAllocInterface::CalcBufferClass(uint16_t size)
{
int pool_size = sizeof(ObjPool) + NUM_OBJS * size;
// 1KB has 11 bit set (starting from less significant)
// we use 32 bit int for size, so first 1 bit will 32 - __builtin_clz(pool_size)
// the buffer classes start from 1KB
return MemBufferClassLowerBound(pool_size);
}
void ObjAllocInterface::GetStats(PoolStatsSt& stats)
{
ObjPoolPtr p;
if (stats.m_type == PoolStatsT::POOL_STATS_ALL)
p = m_objList;
else
p = m_nextFree;
stats.m_objSize = m_size;
stats.m_poolGrossSize = (1024 * MemBufferClassToSizeKb(m_type));
if (p.Get()) {
stats.m_perPoolTotalCount = p->m_totalCount;
stats.m_perPoolOverhead = p->m_overheadBytes;
stats.m_perPoolWaist = p->m_notUsedBytes;
}
while (p.Get() != NULL) {
stats.m_poolCount++;
if (p->m_totalCount == p->m_freeCount)
stats.m_poolFreeCount++;
stats.m_totalObjCount += p->m_totalCount;
stats.m_freeObjCount += p->m_freeCount;
if (stats.m_type == PoolStatsT::POOL_STATS_ALL)
p = p->m_next;
else
p = p->m_objNext;
}
if (stats.m_poolCount > 0)
stats.m_fragmentationPercent = (int16_t)(stats.m_poolFreeCount * 100 / stats.m_poolCount);
else
stats.m_fragmentationPercent = 0;
}
void ObjAllocInterface::PrintStats(PoolStatsSt& stats, const char* prefix, LogLevel level)
{
const char* hist_str = "";
MOT_LOG(level,
"%s: type: %d, size: %d, pools: %u(%u), total objects: %lu, free objects: %lu"
", overhead: %lu, waist: %lu"
"\n%s",
prefix,
m_type,
m_size,
stats.m_poolCount,
stats.m_poolFreeCount,
stats.m_totalObjCount,
stats.m_freeObjCount,
stats.m_poolCount * stats.m_perPoolOverhead,
stats.m_poolCount * stats.m_perPoolWaist,
hist_str);
}
void ObjAllocInterface::Print(const char* prefix, LogLevel level)
{
PoolStatsSt stats;
errno_t erc = memset_s(&stats, sizeof(PoolStatsSt), 0, sizeof(PoolStatsSt));
securec_check(erc, "\0", "\0");
stats.m_type = PoolStatsT::POOL_STATS_ALL;
GetStats(stats);
PrintStats(stats, prefix, level);
}
PoolStatsSt* SlabAllocator::GetStats()
{
@ -184,16 +48,18 @@ PoolStatsSt* SlabAllocator::GetStats()
void SlabAllocator::FreeStats(PoolStatsSt* stats)
{
if (stats != NULL)
if (stats != NULL) {
free(stats);
}
}
void SlabAllocator::GetSize(uint64_t& size, uint64_t& netto)
{
PoolStatsSt* stats = GetStats();
if (stats == NULL)
if (stats == NULL) {
return;
}
for (int i = 0; i <= SLUB_MAX_BIN; i++) {
if (m_bins[i] != NULL) {
@ -207,8 +73,9 @@ void SlabAllocator::GetSize(uint64_t& size, uint64_t& netto)
void SlabAllocator::PrintStats(PoolStatsSt* stats, const char* prefix, LogLevel level)
{
if (stats == NULL)
if (stats == NULL) {
return;
}
for (int i = 0; i <= SLUB_MAX_BIN; i++) {
if (m_bins[i] != NULL) {

View File

@ -14,7 +14,7 @@
* -------------------------------------------------------------------------
*
* object_pool.h
* Object pool implementation.
* Object pool interfaces.
*
* IDENTIFICATION
* src/gausskernel/storage/mot/core/src/memory/object_pool.h
@ -25,511 +25,9 @@
#ifndef OBJECT_POOL_H
#define OBJECT_POOL_H
#include <new>
#include <atomic>
#include <signal.h>
#include <pthread.h>
#include <string.h>
#include <unordered_map>
#include "global.h"
#include "mot_atomic_ops.h"
#include "utilities.h"
#include "cycles.h"
#include "thread_id.h"
#include "mm_def.h"
#include "mm_buffer_api.h"
#include "mm_session_api.h"
#include "memory_statistics.h"
#include "mm_api.h"
#include "spin_lock.h"
#include "object_pool_impl.h"
namespace MOT {
#define MAX_THR_NUM 4096
#define INITIAL_NUM_OBJPOOL 1
#define NUM_OBJS (uint8_t)(255)
#define NOT_VALID (uint8_t)(-1)
#define G_THREAD_ID ((int16_t)MOTCurrThreadId)
#define OBJ_INDEX_SIZE 1
#define MEMORY_BARRIER asm volatile("" ::: "memory");
#define OBJ_RELEASE_START_NOMARK(ptr, size) \
uint8_t* p = (uint8_t*)ptr; \
uint8_t* oix_ptr = (p + size - 1); \
uint8_t oix = *oix_ptr; \
if (oix == NOT_VALID) { \
printf("Detected double free of pointer or corruption: 0x%lx\n", (uint64_t)ptr); \
MOTAbort((void*)ptr); \
} \
ObjPoolPtr op = (ObjPool*)(p - sizeof(ObjPool) - oix * size);
#define OBJ_RELEASE_MARK(ptr) (*(uint8_t*)ptr = NOT_VALID)
#define OBJ_RELEASE_START(ptr, size) \
uint8_t* p = (uint8_t*)ptr; \
uint8_t* oix_ptr = (p + size - 1); \
uint8_t oix = *oix_ptr; \
if (oix == NOT_VALID) { \
printf("Detected double free of pointer or corruption: 0x%lx\n", (uint64_t)ptr); \
MOTAbort(ptr); \
} else { \
if (!__sync_bool_compare_and_swap(oix_ptr, oix, NOT_VALID)) { \
printf("Detected double free of pointer or corruption: 0x%lx\n", (uint64_t)ptr); \
MOTAbort(ptr); \
} \
} \
ObjPoolPtr op = (ObjPool*)(p - sizeof(ObjPool) - oix * size);
#define CAS(ptr, oldval, newval) \
__sync_bool_compare_and_swap((uint64_t*)&ptr, *(uint64_t*)&(oldval), *(uint64_t*)&newval)
#define PUSH_NOLOCK(list, obj) \
{ \
obj->m_objNext = list; \
list = obj; \
}
#define POP_NOLOCK(list) \
{ \
if (list.Get() != nullptr) { \
list = (list)->m_objNext; \
} \
}
#define PUSH(list, obj) \
{ \
++obj; \
do { \
obj->m_objNext = list; \
} while (!CAS(list, obj->m_objNext, obj)); \
}
#define POP(list, obj) \
{ \
do { \
obj = list; \
if (obj.Get() == nullptr) \
break; \
} while (!CAS(list, obj, obj->m_objNext)); \
}
#define ADD_TO_LIST_NOLOCK(list, obj) \
{ \
obj->m_next = list; \
if (list != nullptr) \
list->m_prev = obj; \
list = obj; \
}
#define DEL_FROM_LIST_NOLOCK(list, obj) \
{ \
if (obj->m_prev != nullptr) { \
obj->m_prev->m_next = obj->m_next; \
} \
if (obj->m_next != nullptr) { \
obj->m_next->m_prev = obj->m_prev; \
} \
}
#define ADD_TO_LIST(list, obj) \
{ \
do { \
obj->m_next = list; \
} while (!CAS(list, obj->m_next, obj)); \
if (likely(obj->m_next != nullptr)) \
obj->m_next->m_prev = obj; \
}
#define DEL_FROM_LIST(locker, list, obj) \
{ \
do { \
if (list == obj) { \
if (CAS(list, obj, obj->m_next)) { \
obj->m_next = nullptr; \
obj->m_prev = nullptr; \
break; \
} \
} \
locker.lock(); \
DEL_FROM_LIST_NOLOCK(list, obj) \
locker.unlock(); \
} while (0); \
}
typedef enum PoolAllocState { PAS_FIRST, PAS_EMPTY, PAS_NONE } PoolAllocStateT;
class ObjPool;
// DO NOT CHANGE ORDER OF THE MEMBERS
typedef struct PACKED ObjPool_st {
public:
friend ObjPool;
uint8_t m_nextFreeObj;
private:
uint8_t m_fill1[7];
public:
uint8_t m_objIndexArr[NUM_OBJS + 1];
uint8_t m_nextOccupiedObj;
private:
uint8_t m_fill2[7];
public:
uint8_t m_data[0];
} ObjPoolSt;
typedef enum PoolStatsType : uint8_t { POOL_STATS_ALL = 0, POOL_STATS_FREE } PoolStatsT;
typedef struct PoolStats_st {
PoolStatsT m_type;
uint16_t m_objSize;
uint16_t m_perPoolTotalCount;
uint32_t m_poolCount;
uint32_t m_poolFreeCount;
uint64_t m_totalObjCount;
uint64_t m_freeObjCount;
uint64_t m_poolGrossSize;
int16_t m_fragmentationPercent;
uint32_t m_perPoolOverhead;
uint32_t m_perPoolWaist;
} PoolStatsSt;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define LIST_PTR_SLICE_IX 3
#else
#define LIST_PTR_SLICE_IX 0
#endif
#define LIST_PTR_MASK 0xffffffffffff // usable address space is 48 bits
class PACKED ObjPoolPtr {
public:
/**
* @brief Default constructor for a NULL pointer.
*/
ObjPoolPtr()
{
m_data.m_ptr = nullptr;
}
/**
* @brief Constructs an objects on pre-allocated memory buffer.
* @param target Address of an object.
*/
ObjPoolPtr(ObjPool* target);
/**
* @brief Copy constructor.
* @param other The object.
*/
ObjPoolPtr(ObjPoolPtr& other)
{
m_data.m_ptr = other.m_data.m_ptr;
}
ObjPoolPtr(const ObjPoolPtr& other)
{
m_data.m_ptr = other.m_data.m_ptr;
}
/**
* @brief Retrieves a pointer to the managed object.
* @return A pointer to the object.
*/
inline ObjPool* Get()
{
return (ObjPool*)(((uint64_t)m_data.m_ptr) & LIST_PTR_MASK);
}
/**
* @brief Member access operator implementation.
* @return Retrieves a pointer to the managed object.
*/
inline ObjPool* operator->()
{
return Get();
}
/**
* @brief Retrieves a pointer to the managed object.
* @return A pointer to the object.
*/
inline ObjPool* Get() const
{
return Get();
}
/**
* @brief Member access operator implementation.
* @return Retrieves a pointer to the managed object.
*/
inline ObjPool* operator->() const
{
return Get();
}
inline void operator++();
ObjPoolPtr& operator=(const ObjPoolPtr& right)
{
m_data.m_ptr = right.m_data.m_ptr;
return *this;
}
ObjPoolPtr& operator=(ObjPool* right);
bool operator==(const ObjPoolPtr& right) const
{
return (m_data.m_ptr == right.m_data.m_ptr);
}
bool operator==(ObjPoolPtr& right) const
{
return (m_data.m_ptr == right.m_data.m_ptr);
}
/**
* @brief Destructor. Deallocates the object.
*/
~ObjPoolPtr()
{}
private:
union {
ObjPool* m_ptr;
uint16_t m_slice[4];
} m_data;
};
class ObjAllocInterface {
public:
friend class ObjPool;
spin_lock m_listLock;
ObjPool* m_objList;
ObjPoolPtr m_nextFree;
uint16_t m_size;
uint16_t m_oixOffset;
MemBufferClass m_type;
bool m_global;
static ObjAllocInterface* GetObjPool(uint16_t size, bool local, uint8_t align = 8);
static void FreeObjPool(ObjAllocInterface** pool);
explicit ObjAllocInterface(bool isGlobal) : m_global(isGlobal)
{}
virtual ~ObjAllocInterface();
virtual bool Initialize()
{
return true;
}
virtual void* Alloc() = 0;
template <typename T, class... Args>
inline T* Alloc(Args&&... args)
{
void* buf = Alloc();
if (unlikely(buf == nullptr))
return nullptr;
return new (buf) T(std::forward<Args>(args)...);
}
virtual void Release(void* ptr) = 0;
template <typename T>
inline void Release(T* obj)
{
if (likely(obj != nullptr)) {
obj->~T();
Release((void*)obj);
}
}
virtual void ClearThreadCache() = 0;
virtual void ClearFreeCache() = 0;
void GetStats(PoolStatsSt& stats);
void PrintStats(PoolStatsSt& stats, const char* prefix = "", LogLevel level = LogLevel::LL_DEBUG);
void Print(const char* prefix, LogLevel level = LogLevel::LL_DEBUG);
protected:
static MemBufferClass CalcBufferClass(uint16_t size);
DECLARE_CLASS_LOGGER();
};
// DO NOT CHANGE ORDER OF THE MEMBERS
class PACKED ObjPool {
public:
ObjPool* m_next;
ObjPool* m_prev;
uint16_t m_freeCount;
uint16_t m_totalCount;
int16_t m_owner;
uint16_t m_listCounter;
ObjPoolPtr m_objNext;
ObjAllocInterface* m_parent;
int m_notUsedBytes;
int m_overheadBytes;
ObjPoolSt m_head;
ObjPool(uint16_t size, MemBufferClass type, ObjAllocInterface* app)
{
m_parent = app;
m_owner = -1;
m_objNext = nullptr;
m_next = m_prev = nullptr;
*(uint32_t*)(&m_head.m_fill1[3]) = 0xDEADBEEF;
*(uint32_t*)(&m_head.m_fill2[3]) = 0xDEADBEEF;
m_overheadBytes = sizeof(ObjPool);
uint8_t* ptr = m_head.m_data;
uint8_t* end = ptr + (1024 * MemBufferClassToSizeKb(type)) - sizeof(ObjPool);
m_freeCount = m_totalCount = (uint16_t)((end - m_head.m_data) / m_parent->m_size);
uint8_t i = 0;
for (; i < m_totalCount; i++) {
m_head.m_objIndexArr[i] = i;
ptr += m_parent->m_size;
ptr[-1] = i;
}
for (; i < NUM_OBJS; i++) {
m_head.m_objIndexArr[i] = NOT_VALID;
}
m_head.m_objIndexArr[i] = NOT_VALID;
m_head.m_nextFreeObj = -1;
m_head.m_nextOccupiedObj = m_totalCount - 1;
m_overheadBytes += m_totalCount * OBJ_INDEX_SIZE;
m_notUsedBytes = (int)(end - ptr);
}
~ObjPool()
{}
inline void AllocNoLock(void** ret, PoolAllocStateT* state)
{
uint8_t ix = ++(m_head.m_nextFreeObj);
uint8_t oix = m_head.m_objIndexArr[ix];
m_head.m_objIndexArr[ix] = NOT_VALID;
*ret = (m_head.m_data + oix * m_parent->m_size);
((uint8_t*)(*ret))[m_parent->m_oixOffset] = oix;
--m_freeCount;
if (m_freeCount == 0)
*state = PAS_EMPTY;
}
inline void Alloc(void** ret, PoolAllocStateT* state)
{
uint8_t ix = ++(m_head.m_nextFreeObj);
while (m_head.m_objIndexArr[ix] == NOT_VALID) {
PAUSE
}
uint8_t oix = m_head.m_objIndexArr[ix];
m_head.m_objIndexArr[ix] = NOT_VALID;
*ret = (m_head.m_data + oix * m_parent->m_size);
((uint8_t*)(*ret))[m_parent->m_oixOffset] = oix;
uint16_t c = __sync_sub_and_fetch(&m_freeCount, 1);
if (c == 0)
*state = PAS_EMPTY;
}
inline void ReleaseNoLock(uint8_t oix, PoolAllocStateT* state)
{
++(m_head.m_nextOccupiedObj);
m_head.m_objIndexArr[m_head.m_nextOccupiedObj] = oix;
++m_freeCount;
if (m_freeCount == 1) {
*state = PAS_FIRST;
return;
}
}
void Release(uint8_t oix, PoolAllocStateT* state)
{
uint8_t ix = __sync_add_and_fetch(&m_head.m_nextOccupiedObj, 1);
m_head.m_objIndexArr[ix] = oix;
uint16_t c = __sync_add_and_fetch(&m_freeCount, 1);
if (c == 1) {
*state = PAS_FIRST;
return;
}
}
static ObjPool* GetObjPool(uint16_t size, ObjAllocInterface* app, MemBufferClass type, bool global)
{
#ifdef TEST_STAT_ALLOC
uint64_t start_time = GetSysClock();
#endif
#ifndef MEM_ACTIVE
void* p = (void*)malloc((1024 * MemBufferClassToSizeKb(type)));
#else
void* p;
if (global == true)
p = MemBufferAllocGlobal(type);
else
#ifdef MEM_SESSION_ACTIVE
{
uint32_t buffer_size = 1024 * MemBufferClassToSizeKb(type);
p = MemSessionAlloc(buffer_size);
if (p) {
DetailedMemoryStatisticsProvider::m_provider->AddLocalBuffersUsed(MOTCurrentNumaNodeId, type);
}
}
#else
p = MemBufferAllocLocal(type);
#endif // MEM_SESSION_ACTIVE
#endif // MEM_ACTIVE
#ifdef TEST_STAT_ALLOC
uint64_t end_time = GetSysClock();
MemoryStatisticsProvider::m_provider->AddMallocTime(
CpuCyclesLevelTime::CyclesToNanoseconds(end_time - start_time));
#endif
ObjPool* o = nullptr;
if (p) {
o = new (p) ObjPool(size, type, app);
} else {
MOT_REPORT_ERROR(MOT_ERROR_OOM,
"N/A",
"Failed to allocate %s %s buffer for object pool",
MemBufferClassToString(type),
global ? "global" : "local");
}
return o;
}
static void DelObjPool(void* ptr, MemBufferClass type, bool global)
{
#ifdef TEST_STAT_ALLOC
uint64_t start_time = GetSysClock();
#endif
#ifndef MEM_ACTIVE
free(ptr);
#else
if (global == true)
MemBufferFreeGlobal(ptr, type);
else
#ifdef MEM_SESSION_ACTIVE
{
MemSessionFree(ptr);
DetailedMemoryStatisticsProvider::m_provider->AddLocalBuffersFreed(MOTCurrentNumaNodeId, type);
}
#else
MemBufferFreeLocal(ptr, type);
#endif // MEM_SESSION_ACTIVE
#endif // MEM_ACTIVE
#ifdef TEST_STAT_ALLOC
uint64_t end_time = GetSysClock();
MemoryStatisticsProvider::m_provider->AddFreeTime(
CpuCyclesLevelTime::CyclesToNanoseconds(end_time - start_time));
#endif
}
private:
DECLARE_CLASS_LOGGER();
};
class LocalObjPool : public ObjAllocInterface {
public:
LocalObjPool(uint16_t sz, uint8_t align) : ObjAllocInterface(false)
@ -552,7 +50,7 @@ public:
for (int i = 0; i < INITIAL_NUM_OBJPOOL; i++) {
ObjPool* op = ObjPool::GetObjPool(m_size, this, m_type, false);
if (op == nullptr) {
// memory deallocated when object is destroyed (see ~ObjAllocInterface())
// memory de-allocated when object is destroyed (see ~ObjAllocInterface())
MOT_REPORT_ERROR(MOT_ERROR_OOM, "N/A", "Failed to initialize local object pool");
result = false;
break;
@ -936,13 +434,6 @@ private:
DECLARE_CLASS_LOGGER();
};
inline void ObjPoolPtr::operator++()
{
Get()->m_listCounter++;
m_data.m_slice[LIST_PTR_SLICE_IX] = Get()->m_listCounter;
MEMORY_BARRIER;
}
} // namespace MOT
#endif /* OBJECT_POOL_H */

View File

@ -26,7 +26,7 @@
#define OBJECT_POOL_COMPACT_H
#include <unordered_map>
#include "object_pool.h"
#include "object_pool_impl.h"
namespace MOT {
#define PTR_MASK (((uint64_t)-1) << 10)

View File

@ -0,0 +1,165 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* object_pool_impl.cpp
* Object pool implementation.
*
* IDENTIFICATION
* src/gausskernel/storage/mot/core/src/memory/object_pool_impl.cpp
*
* -------------------------------------------------------------------------
*/
#include "object_pool_impl.h"
#include "object_pool.h"
namespace MOT {
IMPLEMENT_CLASS_LOGGER(ObjAllocInterface, Memory)
IMPLEMENT_CLASS_LOGGER(ObjPool, Memory)
ObjPoolPtr::ObjPoolPtr(ObjPool* target)
{
m_data.m_ptr = target;
if (target != NULL)
m_data.m_slice[LIST_PTR_SLICE_IX] = target->m_listCounter;
}
ObjPoolPtr& ObjPoolPtr::operator=(ObjPool* right)
{
m_data.m_ptr = right;
if (right != NULL)
m_data.m_slice[LIST_PTR_SLICE_IX] = right->m_listCounter;
return *this;
}
ObjAllocInterface* ObjAllocInterface::GetObjPool(uint16_t size, bool local, uint8_t align)
{
ObjAllocInterface* result = NULL;
if (local) {
result = new (std::nothrow) LocalObjPool(size, align);
} else {
result = new (std::nothrow) GlobalObjPool(size, align);
}
if (result == NULL) {
MOT_REPORT_ERROR(MOT_ERROR_OOM,
"Allocate Object Pool",
"Failed to allocate memory for %s object pool",
local ? "local" : "global");
} else if (!result->Initialize()) {
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL,
"Allocate Object Pool",
"Failed to pre-allocate memory for %s object pool",
local ? "local" : "global");
delete result;
result = NULL;
}
return result;
}
void ObjAllocInterface::FreeObjPool(ObjAllocInterface** pool)
{
if (pool != NULL && *pool != NULL) {
delete *pool;
*pool = NULL;
}
}
ObjAllocInterface::~ObjAllocInterface()
{
ObjPool* p = m_objList;
while (p != NULL) {
ObjPool* tmp = p;
p = p->m_next;
ObjPool::DelObjPool(tmp, m_type, m_global);
}
}
inline MemBufferClass ObjAllocInterface::CalcBufferClass(uint16_t size)
{
int pool_size = sizeof(ObjPool) + NUM_OBJS * size;
// 1KB has 11 bit set (starting from less significant)
// we use 32 bit int for size, so first 1 bit will 32 - __builtin_clz(pool_size)
// the buffer classes start from 1KB
return MemBufferClassLowerBound(pool_size);
}
void ObjAllocInterface::GetStats(PoolStatsSt& stats)
{
ObjPoolPtr p;
if (stats.m_type == PoolStatsT::POOL_STATS_ALL)
p = m_objList;
else
p = m_nextFree;
stats.m_objSize = m_size;
stats.m_poolGrossSize = (1024 * MemBufferClassToSizeKb(m_type));
if (p.Get()) {
stats.m_perPoolTotalCount = p->m_totalCount;
stats.m_perPoolOverhead = p->m_overheadBytes;
stats.m_perPoolWaist = p->m_notUsedBytes;
}
while (p.Get() != NULL) {
stats.m_poolCount++;
if (p->m_totalCount == p->m_freeCount)
stats.m_poolFreeCount++;
stats.m_totalObjCount += p->m_totalCount;
stats.m_freeObjCount += p->m_freeCount;
if (stats.m_type == PoolStatsT::POOL_STATS_ALL)
p = p->m_next;
else
p = p->m_objNext;
}
if (stats.m_poolCount > 0)
stats.m_fragmentationPercent = (int16_t)(stats.m_poolFreeCount * 100 / stats.m_poolCount);
else
stats.m_fragmentationPercent = 0;
}
void ObjAllocInterface::PrintStats(PoolStatsSt& stats, const char* prefix, LogLevel level)
{
const char* hist_str = "";
MOT_LOG(level,
"%s: type: %d, size: %d, pools: %u(%u), total objects: %lu, free objects: %lu"
", overhead: %lu, waist: %lu"
"\n%s",
prefix,
m_type,
m_size,
stats.m_poolCount,
stats.m_poolFreeCount,
stats.m_totalObjCount,
stats.m_freeObjCount,
stats.m_poolCount * stats.m_perPoolOverhead,
stats.m_poolCount * stats.m_perPoolWaist,
hist_str);
}
void ObjAllocInterface::Print(const char* prefix, LogLevel level)
{
PoolStatsSt stats;
errno_t erc = memset_s(&stats, sizeof(PoolStatsSt), 0, sizeof(PoolStatsSt));
securec_check(erc, "\0", "\0");
stats.m_type = PoolStatsT::POOL_STATS_ALL;
GetStats(stats);
PrintStats(stats, prefix, level);
}
} // namespace MOT

View File

@ -0,0 +1,541 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* object_pool_impl.h
* Object pool implementation.
*
* IDENTIFICATION
* src/gausskernel/storage/mot/core/src/memory/object_pool_impl.h
*
* -------------------------------------------------------------------------
*/
#ifndef OBJECT_POOL_IMPL_H
#define OBJECT_POOL_IMPL_H
#include <new>
#include <atomic>
#include <signal.h>
#include <pthread.h>
#include <string.h>
#include <unordered_map>
#include "global.h"
#include "mot_atomic_ops.h"
#include "utilities.h"
#include "cycles.h"
#include "thread_id.h"
#include "mm_def.h"
#include "mm_buffer_api.h"
#include "mm_session_api.h"
#include "memory_statistics.h"
#include "mm_api.h"
#include "spin_lock.h"
namespace MOT {
#define MAX_THR_NUM 4096
#define INITIAL_NUM_OBJPOOL 1
#define NUM_OBJS (uint8_t)(255)
#define NOT_VALID (uint8_t)(-1)
#define G_THREAD_ID ((int16_t)MOTCurrThreadId)
#define OBJ_INDEX_SIZE 1
#define MEMORY_BARRIER asm volatile("" ::: "memory");
#define OBJ_RELEASE_START_NOMARK(ptr, size) \
uint8_t* p = (uint8_t*)ptr; \
uint8_t* oix_ptr = (p + size - 1); \
uint8_t oix = *oix_ptr; \
if (oix == NOT_VALID) { \
printf("Detected double free of pointer or corruption: 0x%lx\n", (uint64_t)ptr); \
MOTAbort((void*)ptr); \
} \
ObjPoolPtr op = (ObjPool*)(p - sizeof(ObjPool) - oix * size);
#define OBJ_RELEASE_MARK(ptr) (*(uint8_t*)ptr = NOT_VALID)
#define OBJ_RELEASE_START(ptr, size) \
uint8_t* p = (uint8_t*)ptr; \
uint8_t* oix_ptr = (p + size - 1); \
uint8_t oix = *oix_ptr; \
if (oix == NOT_VALID) { \
printf("Detected double free of pointer or corruption: 0x%lx\n", (uint64_t)ptr); \
MOTAbort(ptr); \
} else { \
if (!__sync_bool_compare_and_swap(oix_ptr, oix, NOT_VALID)) { \
printf("Detected double free of pointer or corruption: 0x%lx\n", (uint64_t)ptr); \
MOTAbort(ptr); \
} \
} \
ObjPoolPtr op = (ObjPool*)(p - sizeof(ObjPool) - oix * size);
#define CAS(ptr, oldval, newval) \
__sync_bool_compare_and_swap((uint64_t*)&ptr, *(uint64_t*)&(oldval), *(uint64_t*)&newval)
#define PUSH_NOLOCK(list, obj) \
{ \
obj->m_objNext = list; \
list = obj; \
}
#define POP_NOLOCK(list) \
{ \
if (list.Get() != nullptr) { \
list = (list)->m_objNext; \
} \
}
#define PUSH(list, obj) \
{ \
++obj; \
do { \
obj->m_objNext = list; \
} while (!CAS(list, obj->m_objNext, obj)); \
}
#define POP(list, obj) \
{ \
do { \
obj = list; \
if (obj.Get() == nullptr) \
break; \
} while (!CAS(list, obj, obj->m_objNext)); \
}
#define ADD_TO_LIST_NOLOCK(list, obj) \
{ \
obj->m_next = list; \
if (list != nullptr) \
list->m_prev = obj; \
list = obj; \
}
#define DEL_FROM_LIST_NOLOCK(list, obj) \
{ \
if (obj->m_prev != nullptr) { \
obj->m_prev->m_next = obj->m_next; \
} \
if (obj->m_next != nullptr) { \
obj->m_next->m_prev = obj->m_prev; \
} \
}
#define ADD_TO_LIST(list, obj) \
{ \
do { \
obj->m_next = list; \
} while (!CAS(list, obj->m_next, obj)); \
if (likely(obj->m_next != nullptr)) \
obj->m_next->m_prev = obj; \
}
#define DEL_FROM_LIST(locker, list, obj) \
{ \
do { \
if (list == obj) { \
if (CAS(list, obj, obj->m_next)) { \
obj->m_next = nullptr; \
obj->m_prev = nullptr; \
break; \
} \
} \
locker.lock(); \
DEL_FROM_LIST_NOLOCK(list, obj) \
locker.unlock(); \
} while (0); \
}
typedef enum PoolAllocState { PAS_FIRST, PAS_EMPTY, PAS_NONE } PoolAllocStateT;
class ObjPool;
// DO NOT CHANGE ORDER OF THE MEMBERS
typedef struct PACKED tagObjPoolSt {
public:
friend ObjPool;
uint8_t m_nextFreeObj;
private:
uint8_t m_fill1[7];
public:
uint8_t m_objIndexArr[NUM_OBJS + 1];
uint8_t m_nextOccupiedObj;
private:
uint8_t m_fill2[7];
public:
uint8_t m_data[0];
} ObjPoolSt;
typedef enum PoolStatsType : uint8_t { POOL_STATS_ALL = 0, POOL_STATS_FREE } PoolStatsT;
typedef struct tagPoolStatsSt {
PoolStatsT m_type;
uint16_t m_objSize;
uint16_t m_perPoolTotalCount;
uint32_t m_poolCount;
uint32_t m_poolFreeCount;
uint64_t m_totalObjCount;
uint64_t m_freeObjCount;
uint64_t m_poolGrossSize;
int16_t m_fragmentationPercent;
uint32_t m_perPoolOverhead;
uint32_t m_perPoolWaist;
} PoolStatsSt;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define LIST_PTR_SLICE_IX 3
#else
#define LIST_PTR_SLICE_IX 0
#endif
#define LIST_PTR_MASK 0xffffffffffff // usable address space is 48 bits
class PACKED ObjPoolPtr {
public:
/**
* @brief Default constructor for a NULL pointer.
*/
ObjPoolPtr()
{
m_data.m_ptr = nullptr;
}
/**
* @brief Constructs an objects on pre-allocated memory buffer.
* @param target Address of an object.
*/
ObjPoolPtr(ObjPool* target);
/**
* @brief Copy constructor.
* @param other The object.
*/
ObjPoolPtr(ObjPoolPtr& other)
{
m_data.m_ptr = other.m_data.m_ptr;
}
ObjPoolPtr(const ObjPoolPtr& other)
{
m_data.m_ptr = other.m_data.m_ptr;
}
/**
* @brief Retrieves a pointer to the managed object.
* @return A pointer to the object.
*/
inline ObjPool* Get()
{
return (ObjPool*)(((uint64_t)m_data.m_ptr) & LIST_PTR_MASK);
}
/**
* @brief Member access operator implementation.
* @return Retrieves a pointer to the managed object.
*/
inline ObjPool* operator->()
{
return Get();
}
/**
* @brief Retrieves a pointer to the managed object.
* @return A pointer to the object.
*/
inline ObjPool* Get() const
{
return Get();
}
/**
* @brief Member access operator implementation.
* @return Retrieves a pointer to the managed object.
*/
inline ObjPool* operator->() const
{
return Get();
}
inline void operator++();
ObjPoolPtr& operator=(const ObjPoolPtr& right)
{
m_data.m_ptr = right.m_data.m_ptr;
return *this;
}
ObjPoolPtr& operator=(ObjPool* right);
bool operator==(const ObjPoolPtr& right) const
{
return (m_data.m_ptr == right.m_data.m_ptr);
}
bool operator==(ObjPoolPtr& right) const
{
return (m_data.m_ptr == right.m_data.m_ptr);
}
/**
* @brief Destructor. Deallocates the object.
*/
~ObjPoolPtr()
{}
private:
union {
ObjPool* m_ptr;
uint16_t m_slice[4];
} m_data;
};
class ObjAllocInterface {
public:
friend class ObjPool;
spin_lock m_listLock;
ObjPool* m_objList;
ObjPoolPtr m_nextFree;
uint16_t m_size;
uint16_t m_oixOffset;
MemBufferClass m_type;
bool m_global;
static ObjAllocInterface* GetObjPool(uint16_t size, bool local, uint8_t align = 8);
static void FreeObjPool(ObjAllocInterface** pool);
explicit ObjAllocInterface(bool isGlobal) : m_global(isGlobal)
{}
virtual ~ObjAllocInterface();
virtual bool Initialize()
{
return true;
}
virtual void* Alloc() = 0;
template <typename T, class... Args>
inline T* Alloc(Args&&... args)
{
void* buf = Alloc();
if (unlikely(buf == nullptr))
return nullptr;
return new (buf) T(std::forward<Args>(args)...);
}
virtual void Release(void* ptr) = 0;
template <typename T>
inline void Release(T* obj)
{
if (likely(obj != nullptr)) {
obj->~T();
Release((void*)obj);
}
}
virtual void ClearThreadCache() = 0;
virtual void ClearFreeCache() = 0;
void GetStats(PoolStatsSt& stats);
void PrintStats(PoolStatsSt& stats, const char* prefix = "", LogLevel level = LogLevel::LL_DEBUG);
void Print(const char* prefix, LogLevel level = LogLevel::LL_DEBUG);
protected:
static MemBufferClass CalcBufferClass(uint16_t size);
DECLARE_CLASS_LOGGER();
};
// DO NOT CHANGE ORDER OF THE MEMBERS
class PACKED ObjPool {
public:
ObjPool* m_next;
ObjPool* m_prev;
uint16_t m_freeCount;
uint16_t m_totalCount;
int16_t m_owner;
uint16_t m_listCounter;
ObjPoolPtr m_objNext;
ObjAllocInterface* m_parent;
int m_notUsedBytes;
int m_overheadBytes;
ObjPoolSt m_head;
ObjPool(uint16_t size, MemBufferClass type, ObjAllocInterface* app)
{
m_parent = app;
m_owner = -1;
m_objNext = nullptr;
m_next = m_prev = nullptr;
*(uint32_t*)(&m_head.m_fill1[3]) = 0xDEADBEEF;
*(uint32_t*)(&m_head.m_fill2[3]) = 0xDEADBEEF;
m_overheadBytes = sizeof(ObjPool);
uint8_t* ptr = m_head.m_data;
uint8_t* end = ptr + (1024 * MemBufferClassToSizeKb(type)) - sizeof(ObjPool);
m_freeCount = m_totalCount = (uint16_t)((end - m_head.m_data) / m_parent->m_size);
uint8_t i = 0;
for (; i < m_totalCount; i++) {
m_head.m_objIndexArr[i] = i;
ptr += m_parent->m_size;
ptr[-1] = i;
}
for (; i < NUM_OBJS; i++) {
m_head.m_objIndexArr[i] = NOT_VALID;
}
m_head.m_objIndexArr[i] = NOT_VALID;
m_head.m_nextFreeObj = -1;
m_head.m_nextOccupiedObj = m_totalCount - 1;
m_overheadBytes += m_totalCount * OBJ_INDEX_SIZE;
m_notUsedBytes = (int)(end - ptr);
}
~ObjPool()
{}
inline void AllocNoLock(void** ret, PoolAllocStateT* state)
{
uint8_t ix = ++(m_head.m_nextFreeObj);
uint8_t oix = m_head.m_objIndexArr[ix];
m_head.m_objIndexArr[ix] = NOT_VALID;
*ret = (m_head.m_data + oix * m_parent->m_size);
((uint8_t*)(*ret))[m_parent->m_oixOffset] = oix;
--m_freeCount;
if (m_freeCount == 0) {
*state = PAS_EMPTY;
}
}
inline void Alloc(void** ret, PoolAllocStateT* state)
{
uint8_t ix = ++(m_head.m_nextFreeObj);
while (m_head.m_objIndexArr[ix] == NOT_VALID) {
PAUSE
}
uint8_t oix = m_head.m_objIndexArr[ix];
m_head.m_objIndexArr[ix] = NOT_VALID;
*ret = (m_head.m_data + oix * m_parent->m_size);
((uint8_t*)(*ret))[m_parent->m_oixOffset] = oix;
uint16_t c = __sync_sub_and_fetch(&m_freeCount, 1);
if (c == 0) {
*state = PAS_EMPTY;
}
}
inline void ReleaseNoLock(uint8_t oix, PoolAllocStateT* state)
{
++(m_head.m_nextOccupiedObj);
m_head.m_objIndexArr[m_head.m_nextOccupiedObj] = oix;
++m_freeCount;
if (m_freeCount == 1) {
*state = PAS_FIRST;
return;
}
}
inline void Release(uint8_t oix, PoolAllocStateT* state)
{
uint8_t ix = __sync_add_and_fetch(&m_head.m_nextOccupiedObj, 1);
m_head.m_objIndexArr[ix] = oix;
uint16_t c = __sync_add_and_fetch(&m_freeCount, 1);
if (c == 1) {
*state = PAS_FIRST;
return;
}
}
static ObjPool* GetObjPool(uint16_t size, ObjAllocInterface* app, MemBufferClass type, bool global)
{
#ifdef TEST_STAT_ALLOC
uint64_t start_time = GetSysClock();
#endif
#ifndef MEM_ACTIVE
void* p = (void*)malloc((1024 * MemBufferClassToSizeKb(type)));
#else
void* p;
if (global == true) {
p = MemBufferAllocGlobal(type);
} else {
#ifdef MEM_SESSION_ACTIVE
uint32_t bufferSize = 1024 * MemBufferClassToSizeKb(type);
p = MemSessionAlloc(bufferSize);
if (p) {
DetailedMemoryStatisticsProvider::m_provider->AddLocalBuffersUsed(MOTCurrentNumaNodeId, type);
}
#else
p = MemBufferAllocLocal(type);
#endif // MEM_SESSION_ACTIVE
}
#endif // MEM_ACTIVE
#ifdef TEST_STAT_ALLOC
uint64_t end_time = GetSysClock();
MemoryStatisticsProvider::m_provider->AddMallocTime(
CpuCyclesLevelTime::CyclesToNanoseconds(end_time - start_time));
#endif
ObjPool* o = nullptr;
if (p) {
o = new (p) ObjPool(size, type, app);
} else {
MOT_REPORT_ERROR(MOT_ERROR_OOM,
"N/A",
"Failed to allocate %s %s buffer for object pool",
MemBufferClassToString(type),
global ? "global" : "local");
}
return o;
}
static void DelObjPool(void* ptr, MemBufferClass type, bool global)
{
#ifdef TEST_STAT_ALLOC
uint64_t start_time = GetSysClock();
#endif
#ifndef MEM_ACTIVE
free(ptr);
#else
if (global == true) {
MemBufferFreeGlobal(ptr, type);
} else {
#ifdef MEM_SESSION_ACTIVE
MemSessionFree(ptr);
DetailedMemoryStatisticsProvider::m_provider->AddLocalBuffersFreed(MOTCurrentNumaNodeId, type);
#else
MemBufferFreeLocal(ptr, type);
#endif // MEM_SESSION_ACTIVE
}
#endif // MEM_ACTIVE
#ifdef TEST_STAT_ALLOC
uint64_t end_time = GetSysClock();
MemoryStatisticsProvider::m_provider->AddFreeTime(
CpuCyclesLevelTime::CyclesToNanoseconds(end_time - start_time));
#endif
}
private:
DECLARE_CLASS_LOGGER();
};
inline void ObjPoolPtr::operator++()
{
Get()->m_listCounter++;
m_data.m_slice[LIST_PTR_SLICE_IX] = Get()->m_listCounter;
MEMORY_BARRIER;
}
} // namespace MOT
#endif /* OBJECT_POOL_IMPL_H */

View File

@ -137,10 +137,7 @@ public:
* @brief Retrieves the currently iterated primary sentinel.
* @return The primary sentinel.
*/
virtual Sentinel* GetPrimarySentinel() const
{
return nullptr;
}
virtual Sentinel* GetPrimarySentinel() const = 0;
protected:
/**

View File

@ -111,18 +111,12 @@ public:
m_keyLen = newLen;
}
inline bool CpKey(const uint8_t* buf, uint16_t len)
inline void CpKey(const uint8_t* buf, uint16_t len)
{
if (unlikely(len > m_keyLen)) {
MOT_LOG_ERROR("Key length is too big");
return false;
} else {
errno_t erc = memcpy_s(const_cast<uint8_t*>(m_keyBuf), m_keyLen, buf, len);
securec_check(erc, "\0", "\0");
}
MOT_ASSERT(len <= m_keyLen);
errno_t erc = memcpy_s(const_cast<uint8_t*>(m_keyBuf), m_keyLen, buf, len);
securec_check(erc, "\0", "\0");
m_keyLen = len;
return true;
}
/**
@ -168,9 +162,9 @@ public:
return true;
}
inline bool CpKey(const Key& key)
inline void CpKey(const Key& key)
{
return CpKey(key.GetKeyBuf(), key.GetKeyLength());
CpKey(key.GetKeyBuf(), key.GetKeyLength());
}
void PrintKey() const

View File

@ -581,9 +581,11 @@ Row* Table::RemoveKeyFromIndex(Row* row, Sentinel* sentinel, uint64_t tid, GcMan
MOT_ASSERT(currSentinel->GetCounter() == 0);
#endif
currSentinel = ix->IndexRemove(&key, tid);
MOT_ASSERT(currSentinel == sentinel);
if (likely(gc != nullptr)) {
if (ix->GetIndexOrder() == IndexOrder::INDEX_ORDER_PRIMARY) {
OutputRow = currSentinel->GetData();
MOT_ASSERT(OutputRow != nullptr);
gc->GcRecordObject(ix->GetIndexId(), currSentinel, nullptr, Index::SentinelDtor, SENTINEL_SIZE(ix));
gc->GcRecordObject(ix->GetIndexId(), OutputRow, nullptr, Row::RowDtor, ROW_SIZE_FROM_POOL(this));
} else {
@ -1108,7 +1110,10 @@ void Table::Deserialize(const char* in)
CommonColumnMeta col;
for (uint32_t i = 0; i < saveFieldCount; i++) {
dataIn = DesrializeMeta(dataIn, col);
AddColumn(col.m_name, col.m_size, col.m_type, col.m_isNotNull);
if (AddColumn(col.m_name, col.m_size, col.m_type, col.m_isNotNull) != RC_OK) {
MOT_LOG_ERROR("Table::deserialize - failed to add column %u", i);
return;
}
}
if (!InitRowPool()) {

View File

@ -133,7 +133,6 @@ int CheckpointWorkerPool::Checkpoint(Buffer* buffer, Sentinel* sentinel, int fd,
if (mainRow != nullptr) {
bool headerLocked = sentinel->TryLock(threadId);
if (headerLocked == false) {
if (mainRow->GetTwoPhaseMode() == true) {
MOT_LOG_DEBUG("checkpoint: row %p is 2pc", mainRow);
@ -209,8 +208,9 @@ int CheckpointWorkerPool::Checkpoint(Buffer* buffer, Sentinel* sentinel, int fd,
sentinel->SetStable(nullptr);
}
if (mainRow != nullptr)
if (mainRow != nullptr) {
sentinel->Release();
}
return wrote;
}
@ -516,8 +516,7 @@ CheckpointWorkerPool::ErrCodes CheckpointWorkerPool::WriteTableDataFile(Table* t
curSegLen += table->GetTupleSize() + sizeof(CheckpointUtils::EntryHeader);
if (m_checkpointSegsize > 0 && curSegLen >= m_checkpointSegsize) {
if (buffer->Size() > 0) { // there is data in the buffer that needs to be written
if (CheckpointUtils::WriteFile(fd, (char*)buffer->Data(), buffer->Size()) !=
buffer->Size()) {
if (CheckpointUtils::WriteFile(fd, (char*)buffer->Data(), buffer->Size()) != buffer->Size()) {
MOT_LOG_ERROR(
"CheckpointWorkerPool::WriteTableDataFile: failed to write data file %u for table %u",
maxSegId,

View File

@ -99,8 +99,7 @@ private:
void WorkerFunc();
/**
* @brief Appends checkpoint data into a buffer. the buffer will
* be flushed in case it is full
* @brief Appends a row to the buffer. The buffer will be flushed in case it is full.
* @param buffer The buffer to fill.
* @param row The row to write.
* @param fd The file descriptor to write to.
@ -109,14 +108,13 @@ private:
bool Write(Buffer* buffer, Row* row, int fd);
/**
* @brief Checkpoints a row, according to whether a stable version
* exists or not.
* @brief Checkpoints a row, according to whether a stable version exists or not.
* @param buffer The buffer to fill.
* @param sentinel The sentinel that holds to row.
* @param fd The file descriptor to write to.
* @param threadId The thread id.
* @param isDeleted The row delete status.
* @return Int equal to -1 on error, 0 if nothing was written and 1 if the row was written.
* @return -1 on error, 0 if nothing was written and 1 if the row was written.
*/
int Checkpoint(Buffer* buffer, Sentinel* sentinel, int fd, uint16_t threadId, bool& isDeleted);

View File

@ -290,6 +290,8 @@ inline void Prefetch(const void* ptr)
#define MAX_KEY_COLUMNS (10U)
#define MAX_TUPLE_SIZE 16384 // in bytes
#define MAX_VARCHAR_LEN 1024
// Do not change this. Masstree assumes 15 for optimization purposes
#define BTREE_ORDER 15

View File

@ -945,9 +945,8 @@ uint64_t MOTEngine::GetHardMemoryLimitBytes()
return g_memGlobalCfg.m_maxGlobalMemoryMb * MEGA_BYTE;
}
bool MOTEngine::CheckPolicies()
void MOTEngine::CheckPolicies()
{
bool result = false;
std::ifstream inFile;
inFile.open("/proc/sys/kernel/numa_balancing");
@ -955,8 +954,6 @@ bool MOTEngine::CheckPolicies()
if ((inFile >> flagValue) && (flagValue != 0)) {
MOT_LOG_WARN(
"NUMA policy in the system is set to automatic. (/proc/sys/kernel/numa_balancing is %u)", flagValue);
result = true;
}
return result;
}
} // namespace MOT

View File

@ -593,9 +593,8 @@ private:
/**
* @brief This function is a checker of OS policies to locate if something is potentially not configured properly.
* System will proceed but print a message.
* @return True if the system is configured properly.
*/
bool CheckPolicies();
void CheckPolicies();
// logger macro
DECLARE_CLASS_LOGGER();

View File

@ -79,9 +79,10 @@ bool CheckpointRecovery::Recover()
int taskFillStat = FillTasksFromMapFile();
if (taskFillStat < 0) {
MOT_LOG_INFO("CheckpointRecovery:: failed to read map file");
return false; // error was already set
} else if (taskFillStat == 0) { // fresh install
MOT_LOG_ERROR("CheckpointRecovery:: failed to read map file");
return false;
} else if (taskFillStat == 0) {
// fresh install
return true;
}
@ -125,13 +126,16 @@ bool CheckpointRecovery::Recover()
return false;
}
}
if (!RecoverInProcessTxns()) {
MOT_LOG_ERROR("Failed to recover the in-process transactions from the checkpoint");
return false;
}
// set the current valid id in the checkpoint manager in case
// we will need to retrieve it before a new checkpoint is created
/*
* Set the current valid id in the checkpoint manager in case
* we will need to retrieve it before a new checkpoint is created.
*/
engine->GetCheckpointManager()->SetId(m_checkpointId);
MOT_LOG_INFO("Checkpoint Recovery: finished recovering %lu tables from checkpoint id: %lu",

View File

@ -71,13 +71,24 @@ bool RecoveryManager::RecoverDbStart()
MOT_LOG_INFO("Starting MOT recovery");
if (m_recoverFromCkptDone) {
/*
* This is switchover case.
* In case of CASCADE switchover (CASCADE node switchover with STANDBY node), we need to
* set the correct m_lsn to make sure that we skip any redo which are already replayed.
* After switchover, envelope will start sync from the previous ckpt position.
* In MOT engine, we should skip any redo before m_lastReplayLsn.
*/
if (m_lsn < m_lastReplayLsn) {
m_lsn = m_lastReplayLsn;
}
return true;
}
if (!m_checkpointRecovery.Recover()) {
return false;
}
SetLsn(m_checkpointRecovery.GetLsn());
m_lsn = m_checkpointRecovery.GetLsn();
m_recoverFromCkptDone = true;
return true;
}
@ -302,7 +313,7 @@ bool RecoveryManager::LogStats::FindIdx(uint64_t tableId, uint64_t& id)
{
id = m_numEntries;
std::map<uint64_t, int>::iterator it;
m_slock.lock();
std::lock_guard<spin_lock> lock(m_slock);
it = m_idToIdx.find(tableId);
if (it == m_idToIdx.end()) {
Entry* newEntry = new (std::nothrow) Entry(tableId);
@ -315,7 +326,6 @@ bool RecoveryManager::LogStats::FindIdx(uint64_t tableId, uint64_t& id)
} else {
id = it->second;
}
m_slock.unlock();
return true;
}
@ -481,7 +491,7 @@ bool RecoveryManager::IsTransactionIdCommitted(uint64_t xid)
bool RecoveryManager::IsRecoveryMemoryLimitReached(uint32_t numThreads)
{
uint64_t memoryRequiredBytes = numThreads * MEM_CHUNK_SIZE_MB * MEGA_BYTE;
uint64_t memoryRequiredBytes = (uint64_t)numThreads * MEM_CHUNK_SIZE_MB * MEGA_BYTE;
if (MOTEngine::GetInstance()->GetCurrentMemoryConsumptionBytes() + memoryRequiredBytes >=
MOTEngine::GetInstance()->GetHardMemoryLimitBytes()) {
MOT_LOG_WARN("IsRecoveryMemoryLimitReached: recovery memory limit reached "

View File

@ -341,11 +341,6 @@ private:
*/
void ApplySurrogate();
void SetLsn(uint64_t lsn)
{
m_lsn = lsn;
}
bool m_initialized;
bool m_recoverFromCkptDone;

View File

@ -40,10 +40,12 @@ TypedStatisticsGenerator<ThreadStatistics, EmptyGlobalStatistics> SystemStatisti
SystemStatisticsProvider* SystemStatisticsProvider::m_provider = nullptr;
SystemStatisticsProvider::SystemStatisticsProvider()
: StatisticsProvider("System", &m_generator, GetGlobalConfiguration().m_enableSystemStatistics, true)
{
SnapshotCpuStats(m_lastTotalUser, m_lastTotalUserLow, m_lastTotalSys, m_lastTotalIdle);
}
: StatisticsProvider("System", &m_generator, GetGlobalConfiguration().m_enableSystemStatistics, true),
m_lastTotalUser(0),
m_lastTotalUserLow(0),
m_lastTotalSys(0),
m_lastTotalIdle(0)
{}
void SystemStatisticsProvider::RegisterProvider()
{
@ -71,14 +73,22 @@ bool SystemStatisticsProvider::CreateInstance()
MOT_REPORT_ERROR(
MOT_ERROR_OOM, "Load Statistics", "Failed to allocate memory for System Statistics Provider, aborting");
} else {
result = m_provider->Initialize();
if (!result) {
if (!m_provider->Initialize()) {
MOT_REPORT_ERROR(
MOT_ERROR_INTERNAL, "Load Statistics", "Failed to initialize System Statistics Provider, aborting");
delete m_provider;
m_provider = nullptr;
} else {
m_provider->RegisterProvider();
result = m_provider->SnapshotInitialMetrics();
if (!result) {
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL,
"Load Statistics",
"Failed to take initial metrics snapshot in System Statistics Provider, aborting");
delete m_provider;
m_provider = nullptr;
} else {
m_provider->RegisterProvider();
}
}
}
}
@ -100,6 +110,11 @@ SystemStatisticsProvider& SystemStatisticsProvider::GetInstance()
return *m_provider;
}
bool SystemStatisticsProvider::SnapshotInitialMetrics()
{
return SnapshotCpuStats(m_lastTotalUser, m_lastTotalUserLow, m_lastTotalSys, m_lastTotalIdle);
}
void SystemStatisticsProvider::OnConfigChange()
{
if (m_enable != GetGlobalConfiguration().m_enableSystemStatistics) {

View File

@ -53,6 +53,9 @@ public:
*/
static SystemStatisticsProvider& GetInstance();
/** @brief Takes an initial snapshot of monitored system metrics. */
bool SnapshotInitialMetrics();
/**
* @brief Derives classes should react to a notification that configuration changed. New
* configuration is accessible via the ConfigManager.

View File

@ -26,7 +26,7 @@
#include <algorithm>
#include <unordered_map>
#include "../storage/table.h" // explicit path in order to solve collision with B header file with the same name
#include "table.h"
#include "mot_engine.h"
#include "redo_log_writer.h"
#include "sentinel.h"

View File

@ -24,7 +24,7 @@
#include <map>
#include "../storage/table.h"
#include "table.h"
#include "row.h"
#include "txn.h"
#include "txn_access.h"
@ -450,6 +450,17 @@ RC TxnAccess::AccessLookup(const AccessType type, Sentinel* const originalSentin
// Filter rows
switch (curr_acc->m_type) {
case AccessType::RD:
if (m_txnManager->GetTxnIsoLevel() == READ_COMMITED) {
// If Cached row is not valid, remove it!!
if (type == RD and curr_acc->m_stmtCount != m_txnManager->GetStmtCount()) {
auto it = m_rowsSet->find(curr_acc->m_origSentinel);
MOT_ASSERT(it != m_rowsSet->end());
m_rowsSet->erase(it);
ReleaseAccess(curr_acc);
return RC::RC_LOCAL_ROW_NOT_FOUND;
}
}
break;
case AccessType::RD_FOR_UPDATE:
case AccessType::WR:
break;
@ -525,11 +536,7 @@ Row* TxnAccess::AddInsertToLocalAccess(Sentinel* org_sentinel, Row* org_row, RC&
auto search = m_rowsSet->find(org_sentinel);
if (likely(search == m_rowsSet->end())) {
if (isUpgrade == true) {
if (org_sentinel->IsPrimaryIndex()) {
curr_access = GetNewRowAccess(org_sentinel->GetData(), INS, rc);
} else {
curr_access = GetNewRowAccess(org_row, INS, rc);
}
curr_access = GetNewRowAccess(org_sentinel->GetData(), INS, rc);
// Check if draft is valid
if (curr_access == nullptr) {
return nullptr;

View File

@ -51,7 +51,7 @@ public:
{}
inline RedoLogBuffer(uint32_t size)
: m_bufferSize(size), m_nextFree(sizeof(uint32_t)), m_allocated(false), m_next(nullptr)
: m_bufferSize(size), m_nextFree(sizeof(uint32_t)), m_buffer(nullptr), m_allocated(false), m_next(nullptr)
{
if (size == 0) {
size = REDO_DEFAULT_BUFFER_SIZE;

View File

@ -38,20 +38,18 @@ ENGINE_INC = $(top_builddir)/src/gausskernel/storage/mot/core/src
include $(top_builddir)/src/Makefile.global
OBJ_DIR = ../obj
OBJS = $(OBJ_DIR)/mot_fdw.o $(OBJ_DIR)/mot_internal.o $(OBJ_DIR)/mot_fdw_xlog.o $(OBJ_DIR)/mot_match_index.o
OBJS = $(OBJ_DIR)/mot_fdw.o $(OBJ_DIR)/mot_internal.o $(OBJ_DIR)/mot_fdw_xlog.o $(OBJ_DIR)/mot_match_index.o $(OBJ_DIR)/mot_fdw_error.o
DATA = mot_fdw.control mot_fdw--1.0.sql
DEPS := $(OBJ_DIR)/mot_fdw.d $(OBJ_DIR)/mot_internal.d $(OBJ_DIR)/mot_fdx_xlog.d $(OBJ_DIR)/mot_match_index.d
DEPS := $(OBJ_DIR)/mot_fdw.d $(OBJ_DIR)/mot_internal.d $(OBJ_DIR)/mot_fdx_xlog.d $(OBJ_DIR)/mot_match_index.d $(OBJ_DIR)/mot_fdw_error.d
# Shared library stuff
include $(top_srcdir)/src/gausskernel/common.mk
override CXXFLAGS += -DMOT_SECURE -I$(top_builddir)/src/gausskernel/storage/mot/jit_exec/src -I$(top_builddir)/src/gausskernel/storage/mot/fdw_adapter/src -I$(ENGINE_INC) -I$(ENGINE_INC)/storage -I$(ENGINE_INC)/system -I$(ENGINE_INC)/memory -I$(ENGINE_INC)/memory/garbage_collector
override CXXFLAGS += -I$(ENGINE_INC)/infra -I$(ENGINE_INC)/infra/config -I$(ENGINE_INC)/infra/containers -I$(ENGINE_INC)/infra/stats -I$(ENGINE_INC)/infra/synchronization -I$(ENGINE_INC)/concurrency_control -I$(ENGINE_INC)/storage/index -I$(ENGINE_INC)/system/transaction -I$(ENGINE_INC)/system/common -I$(ENGINE_INC)/system/statistics -I$(ENGINE_INC)/system/transaction_logger -I$(ENGINE_INC)/system/transaction_logger/asynchronous_redo_log -I$(ENGINE_INC)/system/transaction_logger/synchronous_redo_log -I$(ENGINE_INC)/system/transaction_logger/group_synchronous_redo_log -I$(ENGINE_INC)/system/checkpoint -I$(ENGINE_INC)/system/recovery -I$(ENGINE_INC)/utils
ifeq ($(CC_VERSION), 8.2.0)
override CXXFLAGS += -faligned-new
endif
override CXXFLAGS += -faligned-new
$(OBJS): | buildrepo

View File

@ -305,7 +305,7 @@ private:
memCfg.format("%" PRIu64 " MB", newLocalMemoryMb);
result = AddExtStringConfigItem("", "max_mot_local_memory", memCfg.c_str());
}
if (result) {
if (result && (motCfg.m_sessionLargeBufferStoreSizeMB != newSessionLargeStoreMemoryMb)) {
memCfg.format("%" PRIu64 " MB", newSessionLargeStoreMemoryMb);
result = AddExtStringConfigItem("", "session_large_buffer_store_size", memCfg.c_str());
}

View File

@ -41,7 +41,6 @@
#include "foreign/fdwapi.h"
#include "foreign/foreign.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/nodes.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/cost.h"
@ -189,22 +188,6 @@ static int MOTGetFdwType()
return MOT_ORC;
}
static inline void BitmapDeSerialize(uint8_t* bitmap, int16_t len, ListCell** cell)
{
for (int i = 0; i < len; i++) {
bitmap[i] = (uint8_t)((Const*)lfirst(*cell))->constvalue;
*cell = lnext(*cell);
}
}
static inline List* BitmapSerialize(List* result, uint8_t* bitmap, int16_t len)
{
for (int i = 0; i < len; i++)
result = lappend(result, makeConst(INT1OID, -1, InvalidOid, 1, Int8GetDatum(bitmap[i]), false, true));
return result;
}
void MOTRecover()
{
if (!MOTAdaptor::m_initialized) {
@ -1035,7 +1018,6 @@ static TupleTableSlot* MOTIterateForeignScan(ForeignScanState* node)
}
CleanQueryStatesOnError(festate->m_currTxn);
report_pg_error(rc,
festate->m_currTxn,
(void*)(festate->m_currTxn->m_errIx != nullptr ? festate->m_currTxn->m_errIx->GetName().c_str()
: "unknown"),
(void*)festate->m_currTxn->m_errMsgBuf);
@ -1083,7 +1065,6 @@ static TupleTableSlot* MOTIterateForeignScan(ForeignScanState* node)
CleanQueryStatesOnError(festate->m_currTxn);
report_pg_error(rc,
festate->m_currTxn,
(void*)(festate->m_currTxn->m_errIx != NULL ? festate->m_currTxn->m_errIx->GetName().c_str()
: "unknown"),
(void*)festate->m_currTxn->m_errMsgBuf);
@ -1410,7 +1391,7 @@ static TupleTableSlot* MOTExecForeignInsert(
fdwState->m_table = fdwState->m_currTxn->GetTableByExternalId(RelationGetRelid(resultRelInfo->ri_RelationDesc));
if (fdwState->m_table == nullptr) {
pfree(fdwState);
report_pg_error(MOT::RC_TABLE_NOT_FOUND, fdwState->m_currTxn);
report_pg_error(MOT::RC_TABLE_NOT_FOUND);
return nullptr;
}
fdwState->m_numAttrs = RelationGetNumberOfAttributes(resultRelInfo->ri_RelationDesc);
@ -1437,7 +1418,6 @@ static TupleTableSlot* MOTExecForeignInsert(
elog(DEBUG2, "Abort parent transaction from MOT insert, id %lu", fdwState->m_txnId);
CleanQueryStatesOnError(fdwState->m_currTxn);
report_pg_error(rc,
fdwState->m_currTxn,
(void*)(fdwState->m_currTxn->m_errIx != nullptr ? fdwState->m_currTxn->m_errIx->GetName().c_str()
: "unknown"),
(void*)fdwState->m_currTxn->m_errMsgBuf);
@ -1470,14 +1450,14 @@ static TupleTableSlot* MOTExecForeignUpdate(
planSlot->tts_nvalid,
(planSlot->tts_isnull[num] ? "NULL" : "NOT NULL"));
CleanQueryStatesOnError(fdwState->m_currTxn);
report_pg_error(MOT::RC_ERROR, fdwState->m_currTxn);
report_pg_error(MOT::RC_ERROR);
return nullptr;
}
if (currRow == nullptr) {
elog(ERROR, "MOTExecForeignUpdate failed to fetch row");
CleanQueryStatesOnError(fdwState->m_currTxn);
report_pg_error(((rc == MOT::RC_OK) ? MOT::RC_ERROR : rc), fdwState->m_currTxn);
report_pg_error(((rc == MOT::RC_OK) ? MOT::RC_ERROR : rc));
return nullptr;
}
@ -1496,7 +1476,6 @@ static TupleTableSlot* MOTExecForeignUpdate(
elog(DEBUG2, "Abort parent transaction from MOT update, id %lu", fdwState->m_txnId);
CleanQueryStatesOnError(fdwState->m_currTxn);
report_pg_error(rc,
fdwState->m_currTxn,
(void*)(fdwState->m_currTxn->m_errIx != nullptr ? fdwState->m_currTxn->m_errIx->GetName().c_str()
: "unknown"),
(void*)fdwState->m_currTxn->m_errMsgBuf);
@ -1524,7 +1503,7 @@ static TupleTableSlot* MOTExecForeignDelete(
planSlot->tts_nvalid,
(planSlot->tts_isnull[num] ? "NULL" : "NOT NULL"));
CleanQueryStatesOnError(fdwState->m_currTxn);
report_pg_error(MOT::RC_ERROR, fdwState->m_currTxn);
report_pg_error(MOT::RC_ERROR);
return nullptr;
}
@ -1535,7 +1514,7 @@ static TupleTableSlot* MOTExecForeignDelete(
}
elog(ERROR, "MOTExecForeignDelete failed to fetch row");
CleanQueryStatesOnError(fdwState->m_currTxn);
report_pg_error(((rc == MOT::RC_OK) ? MOT::RC_ERROR : rc), fdwState->m_currTxn);
report_pg_error(((rc == MOT::RC_OK) ? MOT::RC_ERROR : rc));
return nullptr;
}
@ -1553,7 +1532,6 @@ static TupleTableSlot* MOTExecForeignDelete(
elog(DEBUG2, "Abort parent transaction from MOT delete, id %lu", fdwState->m_txnId);
CleanQueryStatesOnError(fdwState->m_currTxn);
report_pg_error(rc,
fdwState->m_currTxn,
(void*)(fdwState->m_currTxn->m_errIx != nullptr ? fdwState->m_currTxn->m_errIx->GetName().c_str()
: "unknown"),
(void*)fdwState->m_currTxn->m_errMsgBuf);
@ -1692,7 +1670,7 @@ static void MOTXactCallback(XactEvent event, void* arg)
// commit this transaction. So we need to save the prepared transaction for further instructions from
// CN or gs_clean. If we failed to save it, it's a panic situation.
report_pg_error(
MOT::RC_PANIC, txn, (char*)"Failed to save prepared transaction data (FailedCommitPrepared)");
MOT::RC_PANIC, (char*)"Failed to save prepared transaction data (FailedCommitPrepared)");
}
return;
} else {
@ -1903,7 +1881,7 @@ static void MOTTruncateForeignTable(TruncateStmt* stmt, Relation rel)
errmodule(MOD_MOT),
errmsg("A checkpoint is in progress - cannot truncate table.")));
} else {
report_pg_error(rc, NULL, NULL, NULL, NULL, NULL, NULL);
report_pg_error(rc);
}
}
@ -1985,129 +1963,6 @@ static void InitMOTHandler()
}
}
MOTFdwStateSt* InitializeFdwState(void* fdwState, List** fdwExpr, uint64_t exTableID)
{
MOTFdwStateSt* state = (MOTFdwStateSt*)palloc0(sizeof(MOTFdwStateSt));
List* values = (List*)fdwState;
ListCell* cell = list_head(values);
state->m_allocInScan = true;
state->m_cmdOper = (CmdType)((Const*)lfirst(cell))->constvalue;
cell = lnext(cell);
state->m_order = (SORTDIR_ENUM)((Const*)lfirst(cell))->constvalue;
cell = lnext(cell);
state->m_hasForUpdate = (bool)((Const*)lfirst(cell))->constvalue;
cell = lnext(cell);
state->m_foreignTableId = ((Const*)lfirst(cell))->constvalue;
cell = lnext(cell);
state->m_numAttrs = ((Const*)lfirst(cell))->constvalue;
cell = lnext(cell);
state->m_ctidNum = ((Const*)lfirst(cell))->constvalue;
cell = lnext(cell);
state->m_numExpr = ((Const*)lfirst(cell))->constvalue;
cell = lnext(cell);
int len = BITMAP_GETLEN(state->m_numAttrs);
state->m_attrsUsed = (uint8_t*)palloc0(len);
state->m_attrsModified = (uint8_t*)palloc0(len);
BitmapDeSerialize(state->m_attrsUsed, len, &cell);
if (cell != NULL) {
state->m_bestIx = &state->m_bestIxBuf;
state->m_bestIx->Deserialize(cell, exTableID);
}
if (fdwExpr != NULL && *fdwExpr != NULL) {
ListCell* c = NULL;
int i = 0;
// divide fdw expr to param list and original expr
state->m_remoteCondsOrig = NULL;
foreach (c, *fdwExpr) {
if (i < state->m_numExpr) {
i++;
continue;
} else {
state->m_remoteCondsOrig = lappend(state->m_remoteCondsOrig, lfirst(c));
}
}
*fdwExpr = list_truncate(*fdwExpr, state->m_numExpr);
}
return state;
}
void* SerializeFdwState(MOTFdwStateSt* state)
{
List* result = NULL;
result = lappend(result, makeConst(INT4OID, -1, InvalidOid, 4, Int32GetDatum(state->m_cmdOper), false, true));
result = lappend(result, makeConst(INT1OID, -1, InvalidOid, 4, Int8GetDatum(state->m_order), false, true));
result = lappend(result, makeConst(BOOLOID, -1, InvalidOid, 1, BoolGetDatum(state->m_hasForUpdate), false, true));
result =
lappend(result, makeConst(INT4OID, -1, InvalidOid, 4, Int32GetDatum(state->m_foreignTableId), false, true));
result = lappend(result, makeConst(INT4OID, -1, InvalidOid, 4, Int32GetDatum(state->m_numAttrs), false, true));
result = lappend(result, makeConst(INT4OID, -1, InvalidOid, 4, Int32GetDatum(state->m_ctidNum), false, true));
result = lappend(result, makeConst(INT2OID, -1, InvalidOid, 2, Int16GetDatum(state->m_numExpr), false, true));
int len = BITMAP_GETLEN(state->m_numAttrs);
result = BitmapSerialize(result, state->m_attrsUsed, len);
if (state->m_bestIx != nullptr) {
state->m_bestIx->Serialize(&result);
}
ReleaseFdwState(state);
return result;
}
void CleanCursors(MOTFdwStateSt* state)
{
for (int i = 0; i < 2; i++) {
if (state->m_cursor[i]) {
state->m_cursor[i]->Invalidate();
state->m_cursor[i]->Destroy();
delete state->m_cursor[i];
state->m_cursor[i] = NULL;
}
}
}
void CleanQueryStatesOnError(MOT::TxnManager* txn)
{
if (txn != nullptr) {
for (auto& itr : txn->m_queryState) {
MOTFdwStateSt* state = (MOTFdwStateSt*)itr.second;
if (state != nullptr) {
CleanCursors(state);
}
}
}
}
void ReleaseFdwState(MOTFdwStateSt* state)
{
CleanCursors(state);
if (state->m_currTxn) {
state->m_currTxn->m_queryState.erase((uint64_t)state);
}
if (state->m_bestIx && state->m_bestIx != &state->m_bestIxBuf)
pfree(state->m_bestIx);
if (state->m_remoteCondsOrig != nullptr)
list_free(state->m_remoteCondsOrig);
if (state->m_attrsUsed != NULL)
pfree(state->m_attrsUsed);
if (state->m_attrsModified != NULL)
pfree(state->m_attrsModified);
state->m_table = NULL;
pfree(state);
}
void MOTCheckpointFetchLock()
{
MOT::MOTEngine* engine = MOT::MOTEngine::GetInstance();

View File

@ -0,0 +1,253 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* mot_fdw_error.cpp
* MOT Foreign Data Wrapper error reporting interfaces.
*
* IDENTIFICATION
* src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw_error.cpp
*
* -------------------------------------------------------------------------
*/
#include "mot_fdw_error.h"
#include "catalog/namespace.h"
#include "nodes/parsenodes.h"
#include "utils/elog.h"
#include "column.h"
#include "table.h"
// Error code mapping array from MOT to PG
static const MotErrToPGErrSt MM_ERRCODE_TO_PG[] = {
// RC_OK
{ERRCODE_SUCCESSFUL_COMPLETION, "Success", nullptr},
// RC_ERROR
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_ABORT
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_UNSUPPORTED_COL_TYPE
{ERRCODE_INVALID_COLUMN_DEFINITION,
"Column definition of %s is not supported",
"Column type %s is not supported yet"},
// RC_UNSUPPORTED_COL_TYPE_ARR
{ERRCODE_INVALID_COLUMN_DEFINITION,
"Column definition of %s is not supported",
"Column type Array of %s is not supported yet"},
// RC_EXCEEDS_MAX_ROW_SIZE
{ERRCODE_FEATURE_NOT_SUPPORTED,
"Column definition of %s is not supported",
"Column size %d exceeds max tuple size %u"},
// RC_COL_NAME_EXCEEDS_MAX_SIZE
{ERRCODE_INVALID_COLUMN_DEFINITION,
"Column definition of %s is not supported",
"Column name %s exceeds max name size %u"},
// RC_COL_SIZE_INVALID
{ERRCODE_INVALID_COLUMN_DEFINITION,
"Column definition of %s is not supported",
"Column size %d exceeds max size %u"},
// RC_TABLE_EXCEEDS_MAX_DECLARED_COLS
{ERRCODE_FEATURE_NOT_SUPPORTED, "Can't create table", "Can't add column %s, number of declared columns is less"},
// RC_INDEX_EXCEEDS_MAX_SIZE
{ERRCODE_FDW_KEY_SIZE_EXCEEDS_MAX_ALLOWED,
"Can't create index",
"Total columns size is greater than maximum index size %u"},
// RC_TABLE_EXCEEDS_MAX_INDEXES,
{ERRCODE_FDW_TOO_MANY_INDEXES,
"Can't create index",
"Total number of indexes for table %s is greater than the maximum number if indexes allowed %u"},
// RC_TXN_EXCEEDS_MAX_DDLS,
{ERRCODE_FDW_TOO_MANY_DDL_CHANGES_IN_TRANSACTION_NOT_ALLOWED,
"Cannot execute statement",
"Maximum number of DDLs per transactions reached the maximum %u"},
// RC_UNIQUE_VIOLATION
{ERRCODE_UNIQUE_VIOLATION, "duplicate key value violates unique constraint \"%s\"", "Key %s already exists."},
// RC_TABLE_NOT_FOUND
{ERRCODE_UNDEFINED_TABLE, "Table \"%s\" doesn't exist", nullptr},
// RC_INDEX_NOT_FOUND
{ERRCODE_UNDEFINED_TABLE, "Index \"%s\" doesn't exist", nullptr},
// RC_LOCAL_ROW_FOUND
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_LOCAL_ROW_NOT_FOUND
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_LOCAL_ROW_DELETED
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_INSERT_ON_EXIST
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_INDEX_RETRY_INSERT
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_INDEX_DELETE
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_LOCAL_ROW_NOT_VISIBLE
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_MEMORY_ALLOCATION_ERROR
{ERRCODE_OUT_OF_LOGICAL_MEMORY, "Memory is temporarily unavailable", nullptr},
// RC_ILLEGAL_ROW_STATE
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_NULL_VOILATION
{ERRCODE_FDW_ERROR,
"Null constraint violated",
"NULL value cannot be inserted into non-null column %s at table %s"},
// RC_PANIC
{ERRCODE_FDW_ERROR, "Critical error", "Critical error: %s"},
// RC_NA
{ERRCODE_FDW_OPERATION_NOT_SUPPORTED, "A checkpoint is in progress - cannot truncate table.", nullptr},
// RC_MAX_VALUE
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr}
};
static_assert(sizeof(MM_ERRCODE_TO_PG) / sizeof(MotErrToPGErrSt) == MOT::RC_MAX_VALUE + 1,
"Not all MOT engine error codes (RC) is mapped to PG error codes");
void report_pg_error(MOT::RC rc, void* arg1, void* arg2, void* arg3, void* arg4, void* arg5)
{
const MotErrToPGErrSt* err = &MM_ERRCODE_TO_PG[rc];
switch (rc) {
case MOT::RC_OK:
break;
case MOT::RC_ERROR:
ereport(ERROR, (errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg("%s", err->m_msg)));
break;
case MOT::RC_ABORT:
ereport(ERROR, (errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg("%s", err->m_msg)));
break;
case MOT::RC_UNSUPPORTED_COL_TYPE: {
ColumnDef* col = (ColumnDef*)arg1;
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg(err->m_msg, col->colname),
errdetail(err->m_detail, NameListToString(col->typname->names))));
break;
}
case MOT::RC_UNSUPPORTED_COL_TYPE_ARR: {
ColumnDef* col = (ColumnDef*)arg1;
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg(err->m_msg, col->colname),
errdetail(err->m_detail, strVal(llast(col->typname->names)))));
break;
}
case MOT::RC_COL_NAME_EXCEEDS_MAX_SIZE: {
ColumnDef* col = (ColumnDef*)arg1;
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg(err->m_msg, col->colname),
errdetail(err->m_detail, col->colname, (uint32_t)MOT::Column::MAX_COLUMN_NAME_LEN)));
break;
}
case MOT::RC_COL_SIZE_INVALID: {
ColumnDef* col = (ColumnDef*)arg1;
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg(err->m_msg, col->colname),
errdetail(err->m_detail, (uint32_t)(uint64_t)arg2, (uint32_t)MAX_VARCHAR_LEN)));
break;
}
case MOT::RC_EXCEEDS_MAX_ROW_SIZE: {
ColumnDef* col = (ColumnDef*)arg1;
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg(err->m_msg, col->colname),
errdetail(err->m_detail, (uint32_t)(uint64_t)arg2, (uint32_t)MAX_TUPLE_SIZE)));
break;
}
case MOT::RC_TABLE_EXCEEDS_MAX_DECLARED_COLS: {
ColumnDef* col = (ColumnDef*)arg1;
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg("%s", err->m_msg),
errdetail(err->m_detail, col->colname)));
break;
}
case MOT::RC_INDEX_EXCEEDS_MAX_SIZE:
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg("%s", err->m_msg),
errdetail(err->m_detail, MAX_KEY_SIZE)));
break;
case MOT::RC_TABLE_EXCEEDS_MAX_INDEXES:
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg("%s", err->m_msg),
errdetail(err->m_detail, ((MOT::Table*)arg1)->GetTableName(), MAX_NUM_INDEXES)));
break;
case MOT::RC_TXN_EXCEEDS_MAX_DDLS:
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg("%s", err->m_msg),
errdetail(err->m_detail, MAX_DDL_ACCESS_SIZE)));
break;
case MOT::RC_UNIQUE_VIOLATION:
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg(err->m_msg, (char*)arg1),
errdetail(err->m_detail, (char*)arg2)));
break;
case MOT::RC_TABLE_NOT_FOUND:
case MOT::RC_INDEX_NOT_FOUND:
ereport(ERROR, (errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg(err->m_msg, (char*)arg1)));
break;
// following errors are internal and should not get to an upper layer
case MOT::RC_LOCAL_ROW_FOUND:
case MOT::RC_LOCAL_ROW_NOT_FOUND:
case MOT::RC_LOCAL_ROW_DELETED:
case MOT::RC_INSERT_ON_EXIST:
case MOT::RC_INDEX_RETRY_INSERT:
case MOT::RC_INDEX_DELETE:
case MOT::RC_LOCAL_ROW_NOT_VISIBLE:
case MOT::RC_ILLEGAL_ROW_STATE:
ereport(ERROR, (errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg("%s", err->m_msg)));
break;
case MOT::RC_MEMORY_ALLOCATION_ERROR:
ereport(ERROR, (errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg("%s", err->m_msg)));
break;
case MOT::RC_NULL_VIOLATION: {
ColumnDef* col = (ColumnDef*)arg1;
MOT::Table* table = (MOT::Table*)arg2;
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg("%s", err->m_msg),
errdetail(err->m_detail, col->colname, table->GetLongTableName().c_str())));
break;
}
case MOT::RC_PANIC: {
char* msg = (char*)arg1;
ereport(PANIC,
(errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg("%s", err->m_msg), errdetail(err->m_detail, msg)));
break;
}
case MOT::RC_NA:
ereport(ERROR, (errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg("%s", err->m_msg)));
break;
case MOT::RC_MAX_VALUE:
default:
ereport(ERROR, (errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg("%s", err->m_msg)));
break;
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* mot_fdw_error.h
* MOT Foreign Data Wrapper error reporting interfaces.
*
* IDENTIFICATION
* src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw_error.h
*
* -------------------------------------------------------------------------
*/
#ifndef MOT_FDW_ERROR_H
#define MOT_FDW_ERROR_H
#include "global.h"
typedef struct tagMotErrToPGErrSt {
int m_pgErr;
const char* m_msg;
const char* m_detail;
} MotErrToPGErrSt;
void report_pg_error(MOT::RC rc, void* arg1 = nullptr, void* arg2 = nullptr, void* arg3 = nullptr, void* arg4 = nullptr,
void* arg5 = nullptr);
#endif /* MOT_FDW_ERROR_H */

View File

@ -241,227 +241,6 @@ static void CancelSessionCleanup()
static GaussdbConfigLoader* gaussdbConfigLoader = nullptr;
// Error code mapping array from MOT to PG
static const MotErrToPGErrSt MM_ERRCODE_TO_PG[] = {
// RC_OK
{ERRCODE_SUCCESSFUL_COMPLETION, "Success", nullptr},
// RC_ERROR
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_ABORT
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_UNSUPPORTED_COL_TYPE
{ERRCODE_INVALID_COLUMN_DEFINITION,
"Column definition of %s is not supported",
"Column type %s is not supported yet"},
// RC_UNSUPPORTED_COL_TYPE_ARR
{ERRCODE_INVALID_COLUMN_DEFINITION,
"Column definition of %s is not supported",
"Column type Array of %s is not supported yet"},
// RC_EXCEEDS_MAX_ROW_SIZE
{ERRCODE_FEATURE_NOT_SUPPORTED,
"Column definition of %s is not supported",
"Column size %d exceeds max tuple size %u"},
// RC_COL_NAME_EXCEEDS_MAX_SIZE
{ERRCODE_INVALID_COLUMN_DEFINITION,
"Column definition of %s is not supported",
"Column name %s exceeds max name size %u"},
// RC_COL_SIZE_INVALID
{ERRCODE_INVALID_COLUMN_DEFINITION,
"Column definition of %s is not supported",
"Column size %d exceeds max size %u"},
// RC_TABLE_EXCEEDS_MAX_DECLARED_COLS
{ERRCODE_FEATURE_NOT_SUPPORTED, "Can't create table", "Can't add column %s, number of declared columns is less"},
// RC_INDEX_EXCEEDS_MAX_SIZE
{ERRCODE_FDW_KEY_SIZE_EXCEEDS_MAX_ALLOWED,
"Can't create index",
"Total columns size is greater than maximum index size %u"},
// RC_TABLE_EXCEEDS_MAX_INDEXES,
{ERRCODE_FDW_TOO_MANY_INDEXES,
"Can't create index",
"Total number of indexes for table %s is greater than the maximum number if indexes allowed %u"},
// RC_TXN_EXCEEDS_MAX_DDLS,
{ERRCODE_FDW_TOO_MANY_DDL_CHANGES_IN_TRANSACTION_NOT_ALLOWED,
"Cannot execute statement",
"Maximum number of DDLs per transactions reached the maximum %u"},
// RC_UNIQUE_VIOLATION
{ERRCODE_UNIQUE_VIOLATION, "duplicate key value violates unique constraint \"%s\"", "Key %s already exists."},
// RC_TABLE_NOT_FOUND
{ERRCODE_UNDEFINED_TABLE, "Table \"%s\" doesn't exist", nullptr},
// RC_INDEX_NOT_FOUND
{ERRCODE_UNDEFINED_TABLE, "Index \"%s\" doesn't exist", nullptr},
// RC_LOCAL_ROW_FOUND
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_LOCAL_ROW_NOT_FOUND
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_LOCAL_ROW_DELETED
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_INSERT_ON_EXIST
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_INDEX_RETRY_INSERT
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_INDEX_DELETE
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_LOCAL_ROW_NOT_VISIBLE
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_MEMORY_ALLOCATION_ERROR
{ERRCODE_OUT_OF_LOGICAL_MEMORY, "Memory is temporarily unavailable", nullptr},
// RC_ILLEGAL_ROW_STATE
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr},
// RC_NULL_VOILATION
{ERRCODE_FDW_ERROR,
"Null constraint violated",
"NULL value cannot be inserted into non-null column %s at table %s"},
// RC_PANIC
{ERRCODE_FDW_ERROR, "Critical error", "Critical error: %s"},
// RC_NA
{ERRCODE_FDW_OPERATION_NOT_SUPPORTED, "A checkpoint is in progress - cannot truncate table.", nullptr},
// RC_MAX_VALUE
{ERRCODE_FDW_ERROR, "Unknown error has occurred", nullptr}};
static_assert(sizeof(MM_ERRCODE_TO_PG) / sizeof(MotErrToPGErrSt) == MOT::RC_MAX_VALUE + 1,
"Not all MOT engine error codes (RC) is mapped to PG error codes");
void report_pg_error(MOT::RC rc, MOT::TxnManager* txn, void* arg1, void* arg2, void* arg3, void* arg4, void* arg5)
{
const MotErrToPGErrSt* err = &MM_ERRCODE_TO_PG[rc];
switch (rc) {
case MOT::RC_OK:
break;
case MOT::RC_ERROR:
ereport(ERROR, (errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg("%s", err->m_msg)));
break;
case MOT::RC_ABORT:
ereport(ERROR, (errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg("%s", err->m_msg)));
break;
case MOT::RC_UNSUPPORTED_COL_TYPE: {
ColumnDef* col = (ColumnDef*)arg1;
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg(err->m_msg, col->colname),
errdetail(err->m_detail, NameListToString(col->typname->names))));
break;
}
case MOT::RC_UNSUPPORTED_COL_TYPE_ARR: {
ColumnDef* col = (ColumnDef*)arg1;
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg(err->m_msg, col->colname),
errdetail(err->m_detail, strVal(llast(col->typname->names)))));
break;
}
case MOT::RC_COL_NAME_EXCEEDS_MAX_SIZE: {
ColumnDef* col = (ColumnDef*)arg1;
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg(err->m_msg, col->colname),
errdetail(err->m_detail, col->colname, (uint32_t)MOT::Column::MAX_COLUMN_NAME_LEN)));
break;
}
case MOT::RC_COL_SIZE_INVALID: {
ColumnDef* col = (ColumnDef*)arg1;
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg(err->m_msg, col->colname),
errdetail(err->m_detail, (uint32_t)(uint64_t)arg2, (uint32_t)MAX_VARCHAR_LEN)));
break;
}
case MOT::RC_EXCEEDS_MAX_ROW_SIZE: {
ColumnDef* col = (ColumnDef*)arg1;
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg(err->m_msg, col->colname),
errdetail(err->m_detail, (uint32_t)(uint64_t)arg2, (uint32_t)MAX_TUPLE_SIZE)));
break;
}
case MOT::RC_TABLE_EXCEEDS_MAX_DECLARED_COLS: {
ColumnDef* col = (ColumnDef*)arg1;
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg("%s", err->m_msg),
errdetail(err->m_detail, col->colname)));
break;
}
case MOT::RC_INDEX_EXCEEDS_MAX_SIZE:
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg("%s", err->m_msg),
errdetail(err->m_detail, MAX_KEY_SIZE)));
break;
case MOT::RC_TABLE_EXCEEDS_MAX_INDEXES:
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg("%s", err->m_msg),
errdetail(err->m_detail, ((MOT::Table*)arg1)->GetTableName(), MAX_NUM_INDEXES)));
break;
case MOT::RC_TXN_EXCEEDS_MAX_DDLS:
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg("%s", err->m_msg),
errdetail(err->m_detail, MAX_DDL_ACCESS_SIZE)));
break;
case MOT::RC_UNIQUE_VIOLATION:
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg(err->m_msg, (char*)arg1),
errdetail(err->m_detail, (char*)arg2)));
break;
case MOT::RC_TABLE_NOT_FOUND:
case MOT::RC_INDEX_NOT_FOUND:
ereport(ERROR, (errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg(err->m_msg, (char*)arg1)));
break;
// following errors are internal and should not get to an upper layer
case MOT::RC_LOCAL_ROW_FOUND:
case MOT::RC_LOCAL_ROW_NOT_FOUND:
case MOT::RC_LOCAL_ROW_DELETED:
case MOT::RC_INSERT_ON_EXIST:
case MOT::RC_INDEX_RETRY_INSERT:
case MOT::RC_INDEX_DELETE:
case MOT::RC_LOCAL_ROW_NOT_VISIBLE:
case MOT::RC_ILLEGAL_ROW_STATE:
ereport(ERROR, (errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg("%s", err->m_msg)));
break;
case MOT::RC_MEMORY_ALLOCATION_ERROR:
ereport(ERROR, (errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg("%s", err->m_msg)));
break;
case MOT::RC_NULL_VIOLATION: {
ColumnDef* col = (ColumnDef*)arg1;
MOT::Table* table = (MOT::Table*)arg2;
ereport(ERROR,
(errmodule(MOD_MOT),
errcode(err->m_pgErr),
errmsg("%s", err->m_msg),
errdetail(err->m_detail, col->colname, table->GetLongTableName().c_str())));
break;
}
case MOT::RC_PANIC: {
char* msg = (char*)arg1;
ereport(PANIC,
(errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg("%s", err->m_msg), errdetail(err->m_detail, msg)));
break;
}
case MOT::RC_NA:
ereport(ERROR, (errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg("%s", err->m_msg)));
break;
case MOT::RC_MAX_VALUE:
default:
ereport(ERROR, (errmodule(MOD_MOT), errcode(err->m_pgErr), errmsg("%s", err->m_msg)));
break;
}
}
bool MOTAdaptor::m_initialized = false;
bool MOTAdaptor::m_callbacks_initialized = false;
@ -1328,7 +1107,7 @@ MOT::RC MOTAdaptor::CreateIndex(IndexStmt* index, ::TransactionId tid)
ix = MOT::IndexFactory::CreateIndex(index_order, indexing_method, flavor);
if (ix == nullptr) {
report_pg_error(MOT::RC_ABORT, txn);
report_pg_error(MOT::RC_ABORT);
return MOT::RC_ABORT;
}
ix->SetExtId(index->indexOid);
@ -1392,7 +1171,7 @@ MOT::RC MOTAdaptor::CreateIndex(IndexStmt* index, ::TransactionId tid)
if ((res = ix->IndexInit(keyLength, index->unique, index->idxname, nullptr)) != MOT::RC_OK) {
delete ix;
report_pg_error(res, txn);
report_pg_error(res);
return res;
}
@ -1406,7 +1185,7 @@ MOT::RC MOTAdaptor::CreateIndex(IndexStmt* index, ::TransactionId tid)
errmsg("Can not create index, max number of indexes %u reached", MAX_NUM_INDEXES)));
return MOT::RC_TABLE_EXCEEDS_MAX_INDEXES;
} else {
report_pg_error(txn->m_err, txn, index->idxname, txn->m_errMsgBuf);
report_pg_error(txn->m_err, index->idxname, txn->m_errMsgBuf);
return MOT::RC_UNIQUE_VIOLATION;
}
}
@ -1464,7 +1243,7 @@ MOT::RC MOTAdaptor::CreateTable(CreateForeignTableStmt* table, ::TransactionId t
table->base.relation->relname, tname.c_str(), columnCount, table->base.relation->foreignOid)) {
delete currentTable;
currentTable = nullptr;
report_pg_error(MOT::RC_MEMORY_ALLOCATION_ERROR, txn);
report_pg_error(MOT::RC_MEMORY_ALLOCATION_ERROR);
break;
}
@ -1474,7 +1253,7 @@ MOT::RC MOTAdaptor::CreateTable(CreateForeignTableStmt* table, ::TransactionId t
if (res != MOT::RC_OK) {
delete currentTable;
currentTable = nullptr;
report_pg_error(MOT::RC_MEMORY_ALLOCATION_ERROR, txn);
report_pg_error(MOT::RC_MEMORY_ALLOCATION_ERROR);
break;
}
@ -1501,7 +1280,7 @@ MOT::RC MOTAdaptor::CreateTable(CreateForeignTableStmt* table, ::TransactionId t
if (res != MOT::RC_OK) {
delete currentTable;
currentTable = nullptr;
report_pg_error(res, txn, colDef, (void*)(int64)typeLen);
report_pg_error(res, colDef, (void*)(int64)typeLen);
break;
}
hasBlob |= isBlob;
@ -1555,7 +1334,7 @@ MOT::RC MOTAdaptor::CreateTable(CreateForeignTableStmt* table, ::TransactionId t
if (res != MOT::RC_OK) {
delete currentTable;
currentTable = nullptr;
report_pg_error(res, txn, colDef, (void*)(int64)typeLen);
report_pg_error(res, colDef, (void*)(int64)typeLen);
break;
}
}
@ -1583,7 +1362,7 @@ MOT::RC MOTAdaptor::CreateTable(CreateForeignTableStmt* table, ::TransactionId t
if (!currentTable->InitRowPool()) {
delete currentTable;
currentTable = nullptr;
report_pg_error(MOT::RC_MEMORY_ALLOCATION_ERROR, txn);
report_pg_error(MOT::RC_MEMORY_ALLOCATION_ERROR);
break;
}
@ -1598,7 +1377,7 @@ MOT::RC MOTAdaptor::CreateTable(CreateForeignTableStmt* table, ::TransactionId t
if (res != MOT::RC_OK) {
delete currentTable;
currentTable = nullptr;
report_pg_error(res, txn);
report_pg_error(res);
break;
}
@ -1613,7 +1392,7 @@ MOT::RC MOTAdaptor::CreateTable(CreateForeignTableStmt* table, ::TransactionId t
if (rc != MOT::RC_OK) {
delete currentTable;
currentTable = nullptr;
report_pg_error(rc, txn);
report_pg_error(rc);
break;
}
primaryIdx->SetExtId(table->base.relation->foreignOid + 1);
@ -2168,6 +1947,137 @@ void MOTAdaptor::DatumToMOT(MOT::Column* col, Datum datum, Oid type, uint8_t* da
}
}
inline void MOTAdaptor::VarcharToMOTKey(
MOT::Column* col, ExprState* expr, Datum datum, Oid type, uint8_t* data, size_t len, KEY_OPER oper, uint8_t fill)
{
if (expr != nullptr) { // LLVM passes nullptr for expr parameter
bool noValue = false;
switch (expr->resultType) {
case BYTEAOID:
case TEXTOID:
case VARCHAROID:
case CLOBOID:
case BPCHAROID:
break;
default:
noValue = true;
errno_t erc = memset_s(data, len, 0x00, len);
securec_check(erc, "\0", "\0");
break;
}
if (noValue) {
return;
}
}
bytea* txt = DatumGetByteaP(datum);
size_t size = VARSIZE(txt); // includes header len VARHDRSZ
char* src = VARDATA(txt);
if (size > len) {
size = len;
}
size -= VARHDRSZ;
if (oper == KEY_OPER::READ_KEY_LIKE) {
if (src[size - 1] == '%') {
size -= 1;
} else {
// switch to equal
if (type == BPCHAROID) {
fill = 0x20; // space ' ' == 0x20
} else {
fill = 0x00;
}
}
} else if (type == BPCHAROID) { // handle padding for blank-padded type
fill = 0x20;
}
col->PackKey(data, (uintptr_t)src, size, fill);
if ((char*)datum != (char*)txt) {
pfree(txt);
}
}
inline void MOTAdaptor::FloatToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, uint8_t* data)
{
if (expr != nullptr) { // LLVM passes nullptr for expr parameter
if (expr->resultType == FLOAT8OID) {
MOT::DoubleConvT dc;
MOT::FloatConvT fc;
dc.m_r = (uint64_t)datum;
fc.m_v = (float)dc.m_v;
uint64_t u = (uint64_t)fc.m_r;
col->PackKey(data, u, col->m_size);
} else {
col->PackKey(data, datum, col->m_size);
}
} else {
col->PackKey(data, datum, col->m_size);
}
}
inline void MOTAdaptor::NumericToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, uint8_t* data)
{
Numeric n = DatumGetNumeric(datum);
char buf[DECIMAL_MAX_SIZE];
MOT::DecimalSt* d = (MOT::DecimalSt*)buf;
PGNumericToMOT(n, *d);
col->PackKey(data, (uintptr_t)d, DECIMAL_SIZE(d));
}
inline void MOTAdaptor::TimestampToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, uint8_t* data)
{
if (expr != nullptr) {
if (expr->resultType == TIMESTAMPTZOID) {
Timestamp result = DatumGetTimestamp(DirectFunctionCall1(timestamptz_timestamp, datum));
col->PackKey(data, result, col->m_size);
} else if (expr->resultType == DATEOID) {
Timestamp result = DatumGetTimestamp(DirectFunctionCall1(date_timestamp, datum));
col->PackKey(data, result, col->m_size);
} else {
col->PackKey(data, datum, col->m_size);
}
} else {
col->PackKey(data, datum, col->m_size);
}
}
inline void MOTAdaptor::TimestampTzToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, uint8_t* data)
{
if (expr != nullptr) {
if (expr->resultType == TIMESTAMPOID) {
TimestampTz result = DatumGetTimestampTz(DirectFunctionCall1(timestamp_timestamptz, datum));
col->PackKey(data, result, col->m_size);
} else if (expr->resultType == DATEOID) {
TimestampTz result = DatumGetTimestampTz(DirectFunctionCall1(date_timestamptz, datum));
col->PackKey(data, result, col->m_size);
} else {
col->PackKey(data, datum, col->m_size);
}
} else {
col->PackKey(data, datum, col->m_size);
}
}
inline void MOTAdaptor::DateToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, uint8_t* data)
{
if (expr != nullptr) {
if (expr->resultType == TIMESTAMPOID) {
DateADT result = DatumGetDateADT(DirectFunctionCall1(timestamp_date, datum));
col->PackKey(data, result, col->m_size);
} else if (expr->resultType == TIMESTAMPTZOID) {
DateADT result = DatumGetDateADT(DirectFunctionCall1(timestamptz_date, datum));
col->PackKey(data, result, col->m_size);
} else {
col->PackKey(data, datum, col->m_size);
}
} else {
col->PackKey(data, datum, col->m_size);
}
}
void MOTAdaptor::DatumToMOTKey(
MOT::Column* col, ExprState* expr, Datum datum, Oid type, uint8_t* data, size_t len, KEY_OPER oper, uint8_t fill)
{
@ -2177,132 +2087,135 @@ void MOTAdaptor::DatumToMOTKey(
case TEXTOID:
case VARCHAROID:
case CLOBOID:
case BPCHAROID: {
if (expr != nullptr) { // LLVM passes nullptr for expr parameter
bool noValue = false;
switch (expr->resultType) {
case BYTEAOID:
case TEXTOID:
case VARCHAROID:
case CLOBOID:
case BPCHAROID:
break;
default:
noValue = true;
errno_t erc = memset_s(data, len, 0x00, len);
securec_check(erc, "\0", "\0");
break;
}
if (noValue) {
break;
}
}
bytea* txt = DatumGetByteaP(datum);
size_t size = VARSIZE(txt); // includes header len VARHDRSZ
char* src = VARDATA(txt);
if (size > len)
size = len;
size -= VARHDRSZ;
if (oper == KEY_OPER::READ_KEY_LIKE) {
if (src[size - 1] == '%') {
size -= 1;
} else {
// switch to equal
if (type == BPCHAROID) {
fill = 0x20; // space ' ' == 0x20
} else {
fill = 0x00;
}
}
} else if (type == BPCHAROID) { // handle padding for blank-padded type
fill = 0x20;
}
col->PackKey(data, (uintptr_t)src, size, fill);
if ((char*)datum != (char*)txt) {
pfree(txt);
}
case BPCHAROID:
VarcharToMOTKey(col, expr, datum, type, data, len, oper, fill);
break;
}
case FLOAT4OID: {
if (expr != nullptr) { // LLVM passes nullptr for expr parameter
if (expr->resultType == FLOAT8OID) {
MOT::DoubleConvT dc;
MOT::FloatConvT fc;
dc.m_r = (uint64_t)datum;
fc.m_v = (float)dc.m_v;
uint64_t u = (uint64_t)fc.m_r;
col->PackKey(data, u, col->m_size);
} else {
col->PackKey(data, datum, col->m_size);
}
} else {
col->PackKey(data, datum, col->m_size);
}
case FLOAT4OID:
FloatToMOTKey(col, expr, datum, data);
break;
}
case NUMERICOID: {
Numeric n = DatumGetNumeric(datum);
char buf[DECIMAL_MAX_SIZE];
MOT::DecimalSt* d = (MOT::DecimalSt*)buf;
PGNumericToMOT(n, *d);
col->PackKey(data, (uintptr_t)d, DECIMAL_SIZE(d));
case NUMERICOID:
NumericToMOTKey(col, expr, datum, data);
break;
}
case TIMESTAMPOID: {
if (expr != nullptr) {
if (expr->resultType == TIMESTAMPTZOID) {
Timestamp result = DatumGetTimestamp(DirectFunctionCall1(timestamptz_timestamp, datum));
col->PackKey(data, result, col->m_size);
} else if (expr->resultType == DATEOID) {
Timestamp result = DatumGetTimestamp(DirectFunctionCall1(date_timestamp, datum));
col->PackKey(data, result, col->m_size);
} else {
col->PackKey(data, datum, col->m_size);
}
} else {
col->PackKey(data, datum, col->m_size);
}
case TIMESTAMPOID:
TimestampToMOTKey(col, expr, datum, data);
break;
}
case TIMESTAMPTZOID: {
if (expr != nullptr) {
if (expr->resultType == TIMESTAMPOID) {
TimestampTz result = DatumGetTimestampTz(DirectFunctionCall1(timestamp_timestamptz, datum));
col->PackKey(data, result, col->m_size);
} else if (expr->resultType == DATEOID) {
TimestampTz result = DatumGetTimestampTz(DirectFunctionCall1(date_timestamptz, datum));
col->PackKey(data, result, col->m_size);
} else {
col->PackKey(data, datum, col->m_size);
}
} else {
col->PackKey(data, datum, col->m_size);
}
case TIMESTAMPTZOID:
TimestampTzToMOTKey(col, expr, datum, data);
break;
}
case DATEOID: {
if (expr != nullptr) {
if (expr->resultType == TIMESTAMPOID) {
DateADT result = DatumGetDateADT(DirectFunctionCall1(timestamp_date, datum));
col->PackKey(data, result, col->m_size);
} else if (expr->resultType == TIMESTAMPTZOID) {
DateADT result = DatumGetDateADT(DirectFunctionCall1(timestamptz_date, datum));
col->PackKey(data, result, col->m_size);
} else {
col->PackKey(data, datum, col->m_size);
}
} else {
col->PackKey(data, datum, col->m_size);
}
case DATEOID:
DateToMOTKey(col, expr, datum, data);
break;
}
default:
col->PackKey(data, datum, col->m_size);
break;
}
}
MOTFdwStateSt* InitializeFdwState(void* fdwState, List** fdwExpr, uint64_t exTableID)
{
MOTFdwStateSt* state = (MOTFdwStateSt*)palloc0(sizeof(MOTFdwStateSt));
List* values = (List*)fdwState;
state->m_allocInScan = true;
state->m_foreignTableId = exTableID;
if (list_length(values) > 0) {
ListCell* cell = list_head(values);
int type = ((Const*)lfirst(cell))->constvalue;
if (type != FDW_LIST_STATE) {
return state;
}
cell = lnext(cell);
state->m_cmdOper = (CmdType)((Const*)lfirst(cell))->constvalue;
cell = lnext(cell);
state->m_order = (SORTDIR_ENUM)((Const*)lfirst(cell))->constvalue;
cell = lnext(cell);
state->m_hasForUpdate = (bool)((Const*)lfirst(cell))->constvalue;
cell = lnext(cell);
state->m_foreignTableId = ((Const*)lfirst(cell))->constvalue;
cell = lnext(cell);
state->m_numAttrs = ((Const*)lfirst(cell))->constvalue;
cell = lnext(cell);
state->m_ctidNum = ((Const*)lfirst(cell))->constvalue;
cell = lnext(cell);
state->m_numExpr = ((Const*)lfirst(cell))->constvalue;
cell = lnext(cell);
int len = BITMAP_GETLEN(state->m_numAttrs);
state->m_attrsUsed = (uint8_t*)palloc0(len);
state->m_attrsModified = (uint8_t*)palloc0(len);
BitmapDeSerialize(state->m_attrsUsed, len, &cell);
if (cell != NULL) {
state->m_bestIx = &state->m_bestIxBuf;
state->m_bestIx->Deserialize(cell, exTableID);
}
if (fdwExpr != NULL && *fdwExpr != NULL) {
ListCell* c = NULL;
int i = 0;
// divide fdw expr to param list and original expr
state->m_remoteCondsOrig = NULL;
foreach (c, *fdwExpr) {
if (i < state->m_numExpr) {
i++;
continue;
} else {
state->m_remoteCondsOrig = lappend(state->m_remoteCondsOrig, lfirst(c));
}
}
*fdwExpr = list_truncate(*fdwExpr, state->m_numExpr);
}
}
return state;
}
void* SerializeFdwState(MOTFdwStateSt* state)
{
List* result = NULL;
// set list type to FDW_LIST_STATE
result = lappend(result, makeConst(INT4OID, -1, InvalidOid, 4, FDW_LIST_STATE, false, true));
result = lappend(result, makeConst(INT4OID, -1, InvalidOid, 4, Int32GetDatum(state->m_cmdOper), false, true));
result = lappend(result, makeConst(INT1OID, -1, InvalidOid, 4, Int8GetDatum(state->m_order), false, true));
result = lappend(result, makeConst(BOOLOID, -1, InvalidOid, 1, BoolGetDatum(state->m_hasForUpdate), false, true));
result =
lappend(result, makeConst(INT4OID, -1, InvalidOid, 4, Int32GetDatum(state->m_foreignTableId), false, true));
result = lappend(result, makeConst(INT4OID, -1, InvalidOid, 4, Int32GetDatum(state->m_numAttrs), false, true));
result = lappend(result, makeConst(INT4OID, -1, InvalidOid, 4, Int32GetDatum(state->m_ctidNum), false, true));
result = lappend(result, makeConst(INT2OID, -1, InvalidOid, 2, Int16GetDatum(state->m_numExpr), false, true));
int len = BITMAP_GETLEN(state->m_numAttrs);
result = BitmapSerialize(result, state->m_attrsUsed, len);
if (state->m_bestIx != nullptr) {
state->m_bestIx->Serialize(&result);
}
ReleaseFdwState(state);
return result;
}
void ReleaseFdwState(MOTFdwStateSt* state)
{
CleanCursors(state);
if (state->m_currTxn) {
state->m_currTxn->m_queryState.erase((uint64_t)state);
}
if (state->m_bestIx && state->m_bestIx != &state->m_bestIxBuf)
pfree(state->m_bestIx);
if (state->m_remoteCondsOrig != nullptr)
list_free(state->m_remoteCondsOrig);
if (state->m_attrsUsed != NULL)
pfree(state->m_attrsUsed);
if (state->m_attrsModified != NULL)
pfree(state->m_attrsModified);
state->m_table = NULL;
pfree(state);
}

View File

@ -22,18 +22,20 @@
* -------------------------------------------------------------------------
*/
#ifndef MOT_INT_H
#define MOT_INT_H
#ifndef MOT_INTERNAL_H
#define MOT_INTERNAL_H
#include <map>
#include <string>
#include "catalog_column_types.h"
#include "foreign/fdwapi.h"
#include "nodes/nodes.h"
#include "nodes/makefuncs.h"
#include "utils/numeric.h"
#include "utils/numeric_gs.h"
#include "pgstat.h"
#include "global.h"
#include "mot_fdw_error.h"
#include "mot_fdw_xlog.h"
#include "system/mot_engine.h"
#include "bitmapset.h"
@ -92,18 +94,8 @@ class MOTEngine;
typedef struct MOTFdwState_St MOTFdwStateSt;
#endif
typedef struct MotErrToPGErr_St {
int m_pgErr;
const char* m_msg;
const char* m_detail;
} MotErrToPGErrSt;
void report_pg_error(MOT::RC rc, MOT::TxnManager* txn, void* arg1 = nullptr, void* arg2 = nullptr, void* arg3 = nullptr,
void* arg4 = nullptr, void* arg5 = nullptr);
#define MAX_VARCHAR_LEN 1024
typedef enum : uint8_t { SORTDIR_NONE = 0, SORTDIR_ASC = 1, SORTDIR_DESC = 2 } SORTDIR_ENUM;
typedef enum : uint8_t { FDW_LIST_STATE = 1, FDW_LIST_BITMAP = 2 } FDW_LIST_TYPE;
typedef struct Order_St {
SORTDIR_ENUM m_order;
@ -311,6 +303,15 @@ public:
static MOT::MOTEngine* m_engine;
static bool m_initialized;
static bool m_callbacks_initialized;
private:
static void VarcharToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, Oid type, uint8_t* data, size_t len,
KEY_OPER oper, uint8_t fill);
static void FloatToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, uint8_t* data);
static void NumericToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, uint8_t* data);
static void TimestampToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, uint8_t* data);
static void TimestampTzToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, uint8_t* data);
static void DateToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, uint8_t* data);
};
inline MOT::TxnManager* GetSafeTxn(const char* callerSrc, ::TransactionId txn_id = 0)
@ -322,7 +323,7 @@ inline MOT::TxnManager* GetSafeTxn(const char* callerSrc, ::TransactionId txn_id
u_sess->mot_cxt.txn_manager->SetTransactionId(txn_id);
}
} else {
report_pg_error(MOT_GET_ROOT_ERROR_RC(), nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
report_pg_error(MOT_GET_ROOT_ERROR_RC());
}
}
return u_sess->mot_cxt.txn_manager;
@ -330,4 +331,56 @@ inline MOT::TxnManager* GetSafeTxn(const char* callerSrc, ::TransactionId txn_id
extern void EnsureSafeThreadAccess();
#endif // MOT_INT_H
inline List* BitmapSerialize(List* result, uint8_t* bitmap, int16_t len)
{
// set list type to FDW_LIST_BITMAP
result = lappend(result, makeConst(INT4OID, -1, InvalidOid, 4, FDW_LIST_BITMAP, false, true));
for (int i = 0; i < len; i++)
result = lappend(result, makeConst(INT1OID, -1, InvalidOid, 1, Int8GetDatum(bitmap[i]), false, true));
return result;
}
inline void BitmapDeSerialize(uint8_t* bitmap, int16_t len, ListCell** cell)
{
if (cell != nullptr && *cell != nullptr) {
int type = ((Const*)lfirst(*cell))->constvalue;
if (type == FDW_LIST_BITMAP) {
*cell = lnext(*cell);
for (int i = 0; i < len; i++) {
bitmap[i] = (uint8_t)((Const*)lfirst(*cell))->constvalue;
*cell = lnext(*cell);
}
}
}
}
inline void CleanCursors(MOTFdwStateSt* state)
{
for (int i = 0; i < 2; i++) {
if (state->m_cursor[i]) {
state->m_cursor[i]->Invalidate();
state->m_cursor[i]->Destroy();
delete state->m_cursor[i];
state->m_cursor[i] = NULL;
}
}
}
inline void CleanQueryStatesOnError(MOT::TxnManager* txn)
{
if (txn != nullptr) {
for (auto& itr : txn->m_queryState) {
MOTFdwStateSt* state = (MOTFdwStateSt*)itr.second;
if (state != nullptr) {
CleanCursors(state);
}
}
}
}
MOTFdwStateSt* InitializeFdwState(void* fdwState, List** fdwExpr, uint64_t exTableID);
void* SerializeFdwState(MOTFdwStateSt* state);
void ReleaseFdwState(MOTFdwStateSt* state);
#endif // MOT_INTERNAL_H

View File

@ -44,9 +44,7 @@ include $(top_srcdir)/src/gausskernel/common.mk
override CXXFLAGS += -DMOT_SECURE -I$(top_builddir)/src/gausskernel/storage/mot/jit_exec/src -I$(top_builddir)/src/gausskernel/storage/mot/fdw_adapter/src -I$(ENGINE_INC) -I$(ENGINE_INC)/storage -I$(ENGINE_INC)/system -I$(ENGINE_INC)/memory -I$(ENGINE_INC)/memory/garbage_collector
override CXXFLAGS += -I$(ENGINE_INC)/infra -I$(ENGINE_INC)/infra/config -I$(ENGINE_INC)/infra/containers -I$(ENGINE_INC)/infra/stats -I$(ENGINE_INC)/infra/synchronization -I$(ENGINE_INC)/concurrency_control -I$(ENGINE_INC)/storage/index -I$(ENGINE_INC)/system/transaction -I$(ENGINE_INC)/system/common -I$(ENGINE_INC)/system/statistics -I$(ENGINE_INC)/system/transaction_logger -I$(ENGINE_INC)/system/transaction_logger/asynchronous_redo_log -I$(ENGINE_INC)/system/transaction_logger/synchronous_redo_log -I$(ENGINE_INC)/system/transaction_logger/group_synchronous_redo_log -I$(ENGINE_INC)/system/checkpoint -I$(ENGINE_INC)/system/recovery -I$(ENGINE_INC)/utils
ifeq ($(CC_VERSION), 8.2.0)
override CXXFLAGS += -faligned-new -fno-rtti
endif
override CXXFLAGS += -faligned-new -fno-rtti
override CXXFLAGS += -D__STDC_FORMAT_MACROS
@ -74,7 +72,7 @@ buildrepo:
@$(call make-repo)
$(OBJ_DIR)/%.o: %.cpp
$(COMPILE.cpp) -std=c++11 -MMD -MP -MF"$(patsubst %.o,%.d,$@)" -MT"$@" -o $@ $<
$(COMPILE.cpp) -MMD -MP -MF"$(patsubst %.o,%.d,$@)" -MT"$@" -o $@ $<
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)

View File

@ -22,9 +22,16 @@
* -------------------------------------------------------------------------
*/
#include "global.h"
/*
* ATTENTION:
* 1. Be sure to include gscodegen.h before anything else to avoid clash with PM definition in datetime.h.
* 2. Be sure to include libintl.h before gscodegen.h to avoid problem with gettext.
*/
#include "libintl.h"
#include "codegen/gscodegen.h"
#include "postgres.h"
#include "catalog/pg_operator.h"
#include "global.h"
#include "jit_common.h"
#include "utilities.h"
#include "jit_plan.h"
@ -247,7 +254,7 @@ static bool IsEqualsWhereOperator(int whereOp)
#ifdef MOT_JIT_ADVANCED_WHERE_OP
|| (whereOp == INT24EQOID) || (whereOp == INT42EQOID) || (whereOp == INT84EQOID) || (whereOp == INT48EQOID) ||
(whereOp == INT82EQOID) || (whereOp == INT28EQOID) || (whereOp == FLOAT48EQOID) || (whereOp == FLOAT84EQOID) ||
(whereOp == 1108 /* time_eq */) || (whereOp == TIMETZEQOID)(whereOp == 5550 /* smalldatetime_eq */) ||
(whereOp == 1108 /* time_eq */) || (whereOp == TIMETZEQOID) || (whereOp == 5550 /* smalldatetime_eq */) ||
(whereOp == 2347 /* date_eq_timestamp */) || (whereOp == 2373 /* timestamp_eq_date */) ||
(whereOp == 2360 /* date_eq_timestamptz */) || (whereOp == 2386 /* timestamptz_eq_date */) ||
(whereOp == 2536 /* timestamp_eq_timestamptz */) || (whereOp == 2542 /* timestamptz_eq_timestamp */) ||
@ -272,11 +279,11 @@ static bool IsLessThanWhereOperator(int whereOp)
#ifdef MOT_JIT_ADVANCED_WHERE_OP
|| (whereOp == INT24LTOID) || (whereOp == INT42LTOID) || (whereOp == INT84LTOID) || (whereOp == INT48LTOID) ||
(whereOp == INT82LTOID) || (whereOp == INT28LTOID) || (whereOp == FLOAT48LTOID) || (whereOp == FLOAT84LTOID) ||
(whereOp == 1108 /* time_lt */) || (whereOp == 1552 /* timetz_lt */)(whereOp == 5550 /* smalldatetime_lt */) ||
(whereOp == 2347 /* date_lt_timestamp */) || (whereOp == 2373 /* timestamp_lt_date */) ||
(whereOp == 2360 /* date_lt_timestamptz */) || (whereOp == 2386 /* timestamptz_lt_date */) ||
(whereOp == 2536 /* timestamp_lt_timestamptz */) || (whereOp == 2542 /* timestamptz_lt_timestamp */) ||
(whereOp == 1332 /* interval_lt */)
(whereOp == 1108 /* time_lt */) || (whereOp == 1552 /* timetz_lt */) ||
(whereOp == 5550 /* smalldatetime_lt */) || (whereOp == 2347 /* date_lt_timestamp */) ||
(whereOp == 2373 /* timestamp_lt_date */) || (whereOp == 2360 /* date_lt_timestamptz */) ||
(whereOp == 2386 /* timestamptz_lt_date */) || (whereOp == 2536 /* timestamp_lt_timestamptz */) ||
(whereOp == 2542 /* timestamptz_lt_timestamp */) || (whereOp == 1332 /* interval_lt */)
#endif
) {
result = true;
@ -297,11 +304,11 @@ static bool IsGreaterThanWhereOperator(int whereOp)
#ifdef MOT_JIT_ADVANCED_WHERE_OP
|| (whereOp == INT24GTOID) || (whereOp == INT42GTOID) || (whereOp == INT84GTOID) || (whereOp == INT48GTOID) ||
(whereOp == INT82GTOID) || (whereOp == INT28GTOID) || (whereOp == FLOAT48GTOID) || (whereOp == FLOAT84GTOID) ||
(whereOp == 1112 /* time_gt */) || (whereOp == 1554 /* timetz_gt */)(whereOp == 5554 /* smalldatetime_gt */) ||
(whereOp == 2349 /* date_gt_timestamp */) || (whereOp == 2375 /* timestamp_gt_date */) ||
(whereOp == 2362 /* date_gt_timestamptz */) || (whereOp == 2388 /* timestamptz_gt_date */) ||
(whereOp == 2538 /* timestamp_gt_timestamptz */) || (whereOp == 2544 /* timestamptz_gt_timestamp */) ||
(whereOp == 1334 /* interval_gt */)
(whereOp == 1112 /* time_gt */) || (whereOp == 1554 /* timetz_gt */) ||
(whereOp == 5554 /* smalldatetime_gt */) || (whereOp == 2349 /* date_gt_timestamp */) ||
(whereOp == 2375 /* timestamp_gt_date */) || (whereOp == 2362 /* date_gt_timestamptz */) ||
(whereOp == 2388 /* timestamptz_gt_date */) || (whereOp == 2538 /* timestamp_gt_timestamptz */) ||
(whereOp == 2544 /* timestamptz_gt_timestamp */) || (whereOp == 1334 /* interval_gt */)
#endif
) {
result = true;
@ -322,11 +329,11 @@ static bool IsLessEqualsWhereOperator(int whereOp)
#ifdef MOT_JIT_ADVANCED_WHERE_OP
|| (whereOp == INT24LEOID) || (whereOp == INT42LEOID) || (whereOp == INT84LEOID) || (whereOp == INT48LEOID) ||
(whereOp == INT82LEOID) || (whereOp == INT28LEOID) || (whereOp == FLOAT48LEOID) || (whereOp == FLOAT84LEOID) ||
(whereOp == 1111 /* time_le */) || (whereOp == 1553 /* timetz_le */)(whereOp == 5553 /* smalldatetime_le */) ||
(whereOp == 2346 /* date_le_timestamp */) || (whereOp == 2372 /* timestamp_le_date */) ||
(whereOp == 2359 /* date_le_timestamptz */) || (whereOp == 2385 /* timestamptz_le_date */) ||
(whereOp == 2535 /* timestamp_le_timestamptz */) || (whereOp == 2541 /* timestamptz_le_timestamp */) ||
(whereOp == 1333 /* interval_le */)
(whereOp == 1111 /* time_le */) || (whereOp == 1553 /* timetz_le */) ||
(whereOp == 5553 /* smalldatetime_le */) || (whereOp == 2346 /* date_le_timestamp */) ||
(whereOp == 2372 /* timestamp_le_date */) || (whereOp == 2359 /* date_le_timestamptz */) ||
(whereOp == 2385 /* timestamptz_le_date */) || (whereOp == 2535 /* timestamp_le_timestamptz */) ||
(whereOp == 2541 /* timestamptz_le_timestamp */) || (whereOp == 1333 /* interval_le */)
#endif
) {
result = true;
@ -347,11 +354,11 @@ static bool IsGreaterEqualsWhereOperator(int whereOp)
#ifdef MOT_JIT_ADVANCED_WHERE_OP
|| (whereOp == INT24GEOID) || (whereOp == INT42GEOID) || (whereOp == INT84GEOID) || (whereOp == INT48GEOID) ||
(whereOp == INT82GEOID) || (whereOp == INT28GEOID) || (whereOp == FLOAT48GEOID) || (whereOp == FLOAT84GEOID) ||
(whereOp == 1113 /* time_ge */) || (whereOp == 1555 /* timetz_ge */)(whereOp == 5549 /* smalldatetime_ge */) ||
(whereOp == 2348 /* date_ge_timestamp */) || (whereOp == 2374 /* timestamp_ge_date */) ||
(whereOp == 2361 /* date_ge_timestamptz */) || (whereOp == 2387 /* timestamptz_ge_date */) ||
(whereOp == 2537 /* timestamp_ge_timestamptz */) || (whereOp == 2543 /* timestamptz_ge_timestamp */) ||
(whereOp == 1335 /* interval_ge */)
(whereOp == 1113 /* time_ge */) || (whereOp == 1555 /* timetz_ge */) ||
(whereOp == 5549 /* smalldatetime_ge */) || (whereOp == 2348 /* date_ge_timestamp */) ||
(whereOp == 2374 /* timestamp_ge_date */) || (whereOp == 2361 /* date_ge_timestamptz */) ||
(whereOp == 2387 /* timestamptz_ge_date */) || (whereOp == 2537 /* timestamp_ge_timestamptz */) ||
(whereOp == 2543 /* timestamptz_ge_timestamp */) || (whereOp == 1335 /* interval_ge */)
#endif
) {
result = true;

View File

@ -22,10 +22,17 @@
* -------------------------------------------------------------------------
*/
#include "global.h"
/*
* ATTENTION:
* 1. Be sure to include gscodegen.h before anything else to avoid clash with PM definition in datetime.h.
* 2. Be sure to include libintl.h before gscodegen.h to avoid problem with gettext.
*/
#include "libintl.h"
#include "codegen/gscodegen.h"
#include "postgres.h"
#include "knl/knl_session.h"
#include "storage/ipc.h"
#include "global.h"
#include "jit_context.h"
#include "jit_context_pool.h"
#include "jit_common.h"

View File

@ -62,7 +62,9 @@ extern bool InitJitContextPool(JitContextPool* contextPool, JitContextUsage usag
poolSize,
allocSize,
usage == JIT_CONTEXT_GLOBAL ? "global" : "session-local");
pthread_spin_destroy(&contextPool->m_lock);
if (usage == JIT_CONTEXT_GLOBAL) {
pthread_spin_destroy(&contextPool->m_lock);
}
return false;
}
errno_t erc = memset_s(contextPool->m_contextPool, allocSize, 0, allocSize);

View File

@ -22,8 +22,12 @@
* -------------------------------------------------------------------------
*/
// be careful to include gscodegen.h before anything else to avoid clash with PM definition in datetime.h
#include "global.h"
/*
* ATTENTION:
* 1. Be sure to include gscodegen.h before anything else to avoid clash with PM definition in datetime.h.
* 2. Be sure to include libintl.h before gscodegen.h to avoid problem with gettext.
*/
#include "libintl.h"
#include "codegen/gscodegen.h"
#include "codegen/builtinscodegen.h"
#include "catalog/pg_operator.h"
@ -51,11 +55,9 @@
#include "mot_engine.h"
#include "utilities.h"
#include "mot_internal.h"
#include "catalog_column_types.h"
#include "mot_error.h"
#include "utilities.h"
#include "mot_internal.h"
#include "cycles.h"
#include <assert.h>
@ -191,7 +193,7 @@ static void ProcessJitResult(MOT::RC result, JitContext* jitContext, int newScan
} else {
JitStatisticsProvider::GetInstance().AddFailExecQuery();
}
report_pg_error(result, currTxn, (void*)arg1, (void*)arg2);
report_pg_error(result, (void*)arg1, (void*)arg2);
}
}
@ -201,10 +203,11 @@ static JitContext* GenerateJitContext(Query* query, const char* queryString, Jit
JitContext* sourceJitContext = nullptr;
uint64_t startTime = GetSysClock();
if (JitCanInitThreadCodeGen() && !IsMotPseudoCodegenForced()) {
if (g_instance.mot_cxt.jitExecMode == JIT_EXEC_MODE_LLVM) {
MOT_LOG_TRACE("Generating LLVM JIT context for query: %s", queryString);
sourceJitContext = JitCodegenLlvmQuery(query, queryString, jitPlan);
} else {
MOT_ASSERT(g_instance.mot_cxt.jitExecMode == JIT_EXEC_MODE_TVM);
MOT_LOG_TRACE("Generating TVM JIT context for query: %s", queryString);
sourceJitContext = JitCodegenTvmQuery(query, queryString, jitPlan);
}
@ -365,7 +368,7 @@ extern int JitExecQuery(
"Execute JIT",
"Cannot execute jitted function: function is null. Aborting transaction.");
JitStatisticsProvider::GetInstance().AddFailExecQuery();
report_pg_error(MOT::RC_ERROR, NULL); // execution control ends, calls ereport(error,...)
report_pg_error(MOT::RC_ERROR); // execution control ends, calls ereport(error,...)
}
// when running under thread-pool, it is possible to be executed from a thread that hasn't yet executed any MOT code
@ -380,7 +383,7 @@ extern int JitExecQuery(
"Execute JIT",
"Cannot execute jitted code: Current transaction is undefined. Aborting transaction.");
JitStatisticsProvider::GetInstance().AddFailExecQuery();
report_pg_error(MOT::RC_MEMORY_ALLOCATION_ERROR, NULL); // execution control ends, calls ereport(error,...)
report_pg_error(MOT::RC_MEMORY_ALLOCATION_ERROR); // execution control ends, calls ereport(error,...)
}
// during the very first invocation of the query we need to setup the reusable search keys
@ -391,7 +394,7 @@ extern int JitExecQuery(
MOT_REPORT_ERROR(
MOT_ERROR_OOM, "Execute JIT", "Failed to prepare for executing jitted code, aborting transaction");
JitStatisticsProvider::GetInstance().AddFailExecQuery();
report_pg_error(MOT::RC_MEMORY_ALLOCATION_ERROR, NULL); // execution control ends, calls ereport(error,...)
report_pg_error(MOT::RC_MEMORY_ALLOCATION_ERROR); // execution control ends, calls ereport(error,...)
}
}
@ -494,35 +497,26 @@ extern bool JitInitialize()
if (JitCanInitThreadCodeGen()) {
if (IsMotPseudoCodegenForced()) {
MOT_LOG_INFO("Forcing TVM on LLVM natively supported platform");
MOT_LOG_INFO("Forcing TVM on LLVM natively supported platform by user configuration");
g_instance.mot_cxt.jitExecMode = JIT_EXEC_MODE_TVM;
} else {
PrintNativeLlvmStartupInfo();
g_instance.mot_cxt.jitExecMode = JIT_EXEC_MODE_LLVM;
}
} else {
MOT_LOG_INFO("Using TVM on LLVM natively unsupported platform");
if (IsMotPseudoCodegenForced()) {
MOT_LOG_INFO("Forcing TVM on LLVM natively unsupported platform by user configuration");
} else {
MOT_LOG_WARN("Defaulting to TVM on LLVM natively unsupported platform");
}
g_instance.mot_cxt.jitExecMode = JIT_EXEC_MODE_TVM;
}
enum InitState {
JIT_INIT,
JIT_ARM_LOCK_INIT,
JIT_CTX_POOL_INIT,
JIT_SRC_POOL_INIT,
JIT_INIT_DONE
} initState = JIT_INIT;
enum InitState { JIT_INIT, JIT_CTX_POOL_INIT, JIT_SRC_POOL_INIT, JIT_INIT_DONE } initState = JIT_INIT;
bool result = true;
// instead of goto
do {
// initialize ARM compile lock
#ifdef __aarch64__
result = InitArmCompileLock();
#endif
if (!result) {
MOT_REPORT_ERROR(MOT_ERROR_INTERNAL, "JIT Initialization", "Failed to initialize compilation lock for ARM");
break;
}
initState = JIT_ARM_LOCK_INIT;
// initialize global JIT context pool
result = InitGlobalJitContextPool();
if (!result) {
@ -565,11 +559,6 @@ extern bool JitInitialize()
case JIT_CTX_POOL_INIT:
DestroyGlobalJitContextPool();
// fall through
case JIT_ARM_LOCK_INIT:
#ifdef __aarch64__
DestroyArmCompileLock();
#endif
// fall through
case JIT_INIT:
default:
break;
@ -583,14 +572,11 @@ extern void JitDestroy()
DestroyJitSourceMap();
DestroyJitSourcePool();
DestroyGlobalJitContextPool();
#ifdef __aarch64__
DestroyArmCompileLock();
#endif
}
extern bool IsMotCodegenEnabled()
{
return MOT_ATOMIC_LOAD(MOT::GetGlobalConfiguration().m_enableCodegen);
return MOT::GetGlobalConfiguration().m_enableCodegen;
}
extern bool IsMotPseudoCodegenForced()
@ -607,9 +593,4 @@ extern uint32_t GetMotCodegenLimit()
{
return MOT::GetGlobalConfiguration().m_codegenLimit;
}
extern void DisableMotCodegen()
{
MOT_ATOMIC_STORE(MOT::GetGlobalConfiguration().m_enableCodegen, false);
}
} // namespace JitExec

View File

@ -22,8 +22,12 @@
* -------------------------------------------------------------------------
*/
// be careful to include gscodegen.h before anything else to avoid clash with PM definition in datetime.h
#include "global.h"
/*
* ATTENTION:
* 1. Be sure to include gscodegen.h before anything else to avoid clash with PM definition in datetime.h.
* 2. Be sure to include libintl.h before gscodegen.h to avoid problem with gettext.
*/
#include "libintl.h"
#include "codegen/gscodegen.h"
#include "access/xact.h"
#include "utils/array.h"

View File

@ -22,11 +22,12 @@
* -------------------------------------------------------------------------
*/
// Be sure to include global.h before postgres.h to avoid conflict between libintl.h (included in global.h)
// and c.h (included in postgres.h).
#include "global.h"
// be careful to include gscodegen.h before anything else to avoid clash with PM definition in datetime.h
/*
* ATTENTION:
* 1. Be sure to include gscodegen.h before anything else to avoid clash with PM definition in datetime.h.
* 2. Be sure to include libintl.h before gscodegen.h to avoid problem with gettext.
*/
#include "libintl.h"
#include "codegen/gscodegen.h"
#include "pgxc/pgxc.h"
#include "storage/mot/jit_exec.h"
@ -42,83 +43,20 @@ DECLARE_LOGGER(JitLlvm, JitExec);
using namespace dorado;
#ifdef __aarch64__
// on ARM platforms we experienced instability during concurrent JIT compilation, so we use a spin-lock
/** @var The global ARM compilation lock. */
static pthread_spinlock_t _arm_compile_lock;
/** @var Denotes whether the global ARM compilation lock initialization was already attempted. */
static int _arm_compile_lock_initialized = 0;
/** @var Denote the global ARM compilation lock is initialized and ready for use. */
static bool _arm_compile_lock_ready = false;
/** @brief Initializes the global ARM compilation lock. */
bool InitArmCompileLock()
{
bool result = true;
if (MOT_ATOMIC_CAS(_arm_compile_lock_initialized, 0, 1)) {
int res = pthread_spin_init(&_arm_compile_lock, 0);
if (res != 0) {
MOT_REPORT_SYSTEM_ERROR_CODE(
res, pthread_spin_init, "Initialize LLVM", "Failed to initialize compile spin-lock for ARM platform");
// turn off JIT
DisableMotCodegen();
result = false;
} else {
_arm_compile_lock_ready = true;
}
}
return result;
}
/** @brief Destroys the global ARM compilation lock. */
void DestroyArmCompileLock()
{
if (_arm_compile_lock_ready) {
int res = pthread_spin_destroy(&_arm_compile_lock);
if (res != 0) {
MOT_REPORT_SYSTEM_ERROR_CODE(
res, pthread_spin_init, "Initialize LLVM", "Failed to destroy compile spin-lock for ARM platform");
} else {
_arm_compile_lock_ready = false;
MOT_ATOMIC_STORE(_arm_compile_lock_initialized, 0);
}
}
}
/** @brief Locks the global ARM compilation lock. */
bool AcquireArmCompileLock()
{
bool result = false;
int res = pthread_spin_lock(&_arm_compile_lock);
if (res != 0) {
MOT_REPORT_SYSTEM_ERROR_CODE(
res, pthread_spin_init, "Compile LLVM", "Failed to acquire compile spin-lock for ARM platform");
} else {
result = true;
}
return result;
}
/** @brief Unlocks the global ARM compilation lock. */
bool ReleaseArmCompileLock()
{
bool result = false;
int res = pthread_spin_unlock(&_arm_compile_lock);
if (res != 0) {
MOT_REPORT_SYSTEM_ERROR_CODE(
res, pthread_spin_init, "Compile LLVM", "Failed to release compile spin-lock for ARM platform");
} else {
result = true;
}
return result;
}
#endif
/** @brief Checks whether the current platforms natively supports LLVM. */
extern bool JitCanInitThreadCodeGen()
bool JitCanInitThreadCodeGen()
{
// Make sure that system type is not generic.
llvm::StringRef hostCPUName = llvm::sys::getHostCPUName();
MOT_LOG_INFO("LLVM library detected CPU: %s", hostCPUName.str().c_str());
if (hostCPUName.empty() || hostCPUName.equals("generic")) {
MOT_LOG_WARN("LLVM library detected unknown generic system: disabling native LLVM");
MOT_LOG_WARN("LLVM default target triple is: %s, process triple is: %s",
llvm::sys::getDefaultTargetTriple().c_str(),
llvm::sys::getProcessTriple().c_str());
return false;
}
#ifdef __aarch64__
return true; // Using native llvm on ARM
#else
@ -126,9 +64,7 @@ extern bool JitCanInitThreadCodeGen()
if (IS_PGXC_DATANODE && IsMotCodegenEnabled()) {
canInit = GlobalCodeGenEnvironmentSuccess;
if (!canInit) {
// turn off JIT
DisableMotCodegen();
MOT_LOG_WARN("SSE4.2 is not supported, disable codegen.");
MOT_LOG_WARN("LLVM environment is not initialized, native LLVM will not be used.");
}
}
return canInit;
@ -138,23 +74,7 @@ extern bool JitCanInitThreadCodeGen()
/** @brief Prepares for code generation. */
GsCodeGen* SetupCodegenEnv()
{
// verify that native LLVM is supported
if (!t_thrd.mot_cxt.init_codegen_once) {
t_thrd.mot_cxt.init_codegen_once = true;
if (!JitCanInitThreadCodeGen()) {
return nullptr;
}
}
// on ARM platform we need to make sure that the compile lock was initialized properly
#ifdef __aarch64__
if (!_arm_compile_lock_ready) {
MOT_LOG_TRACE("Previous attempt to initialize compilation lock on ARM failed. Code generation is disabled.");
// turn off JIT
DisableMotCodegen();
return nullptr;
}
#endif
MOT_ASSERT(g_instance.mot_cxt.jitExecMode == JIT_EXEC_MODE_LLVM);
// create GsCodeGen object for LLVM code generation
GsCodeGen* code_gen = New(g_instance.instance_context) GsCodeGen();

View File

@ -62,28 +62,11 @@ typedef int (*JitFunc)(MOT::Table* table, MOT::Index* index, MOT::Key* key, MOT:
// the number of arguments in the jitted function
#define MOT_JIT_FUNC_ARG_COUNT 14
#ifdef __aarch64__
/**
* @brief Initializes the global spin-lock used for synchronizing native-LLVM compilation.
* @return True if operation succeeded, otherwise false.
*/
bool InitArmCompileLock();
/** @brief Destroys the global spin-lock used for synchronizing native-LLVM compilation. */
void DestroyArmCompileLock();
/** @brief Locks the global ARM compilation lock. */
bool AcquireArmCompileLock();
/** @brief Unlocks the global ARM compilation lock. */
bool ReleaseArmCompileLock();
#endif
/** @brief Prints startup information regarding LLVM version. */
void PrintNativeLlvmStartupInfo();
/** @brief Checks whether the current platforms natively supports LLVM. */
extern bool JitCanInitThreadCodeGen();
bool JitCanInitThreadCodeGen();
/** @brief Allocates a GsCodeGen object. */
dorado::GsCodeGen* SetupCodegenEnv();

View File

@ -22,14 +22,33 @@
* -------------------------------------------------------------------------
*/
#include "jit_llvm_funcs.h"
/*
* ATTENTION: Be sure to include jit_llvm_query.h before anything else because of gscodegen.h
* (jit_llvm_blocks.h includes jit_llvm_query.h before anything else).
* See jit_llvm_query.h for more details.
*/
#include "jit_llvm_blocks.h"
#include "jit_llvm_funcs.h"
#include "jit_util.h"
#include "mot_error.h"
#include "utilities.h"
#include "catalog/pg_aggregate.h"
using namespace dorado;
namespace JitExec {
DECLARE_LOGGER(JitLlvmBlocks, JitExec)
static bool ProcessJoinOpExpr(
JitLlvmCodeGenContext* ctx, const OpExpr* op_expr, int* column_count, int* column_array, int* max_arg);
static bool ProcessJoinBoolExpr(
JitLlvmCodeGenContext* ctx, const BoolExpr* boolexpr, int* column_count, int* column_array, int* max_arg);
static llvm::Value* ProcessFilterExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitFilter* filter, int* max_arg);
static llvm::Value* ProcessExpr(
JitLlvmCodeGenContext* ctx, Expr* expr, int& result_type, int arg_pos, int depth, int* max_arg);
static llvm::Value* ProcessExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitExpr* expr, int* max_arg);
/*--------------------------- Helpers to generate compound LLVM code ---------------------------*/
/** @brief Builds a code segment for checking if soft memory limit has been reached. */
void buildIsSoftMemoryLimitReached(JitLlvmCodeGenContext* ctx)
@ -45,7 +64,7 @@ void buildIsSoftMemoryLimitReached(JitLlvmCodeGenContext* ctx)
}
/** @brief Builds a code segment for writing datum value to a column. */
void buildWriteDatumColumn(JitLlvmCodeGenContext* ctx, llvm::Value* row, int colid, llvm::Value* datum_value)
static void buildWriteDatumColumn(JitLlvmCodeGenContext* ctx, llvm::Value* row, int colid, llvm::Value* datum_value)
{
llvm::Value* set_null_bit_res = AddSetExprResultNullBit(ctx, row, colid);
IssueDebugLog("Set null bit");
@ -85,7 +104,7 @@ void buildWriteRow(JitLlvmCodeGenContext* ctx, llvm::Value* row, bool isPKey, Ji
}
/** @brief Process a join expression (WHERE clause) and generate code to build a search key. */
bool ProcessJoinExpr(JitLlvmCodeGenContext* ctx, Expr* expr, int* column_count, int* column_array, int* max_arg)
static bool ProcessJoinExpr(JitLlvmCodeGenContext* ctx, Expr* expr, int* column_count, int* column_array, int* max_arg)
{
bool result = false;
if (expr->type == T_OpExpr) {
@ -99,7 +118,7 @@ bool ProcessJoinExpr(JitLlvmCodeGenContext* ctx, Expr* expr, int* column_count,
}
/** @brief Process an operator expression (process only "COLUMN equals EXPR" operators). */
bool ProcessJoinOpExpr(
static bool ProcessJoinOpExpr(
JitLlvmCodeGenContext* ctx, const OpExpr* op_expr, int* column_count, int* column_array, int* max_arg)
{
bool result = false;
@ -171,7 +190,7 @@ bool ProcessJoinOpExpr(
/** @brief Process a boolean operator (process only AND operators, since we handle only point queries, or full-prefix
* range update). */
bool ProcessJoinBoolExpr(
static bool ProcessJoinBoolExpr(
JitLlvmCodeGenContext* ctx, const BoolExpr* boolexpr, int* column_count, int* column_array, int* max_arg)
{
bool result = false;
@ -289,7 +308,7 @@ llvm::Value* buildSearchRow(JitLlvmCodeGenContext* ctx, MOT::AccessType access_t
return row;
}
llvm::Value* buildFilter(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitFilter* filter, int* max_arg)
static llvm::Value* buildFilter(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitFilter* filter, int* max_arg)
{
llvm::Value* result = nullptr;
llvm::Value* lhs_expr = ProcessExpr(ctx, row, filter->_lhs_operand, max_arg);
@ -365,8 +384,8 @@ void buildDeleteRow(JitLlvmCodeGenContext* ctx)
}
/** @brief Adds code to search for an iterator. */
llvm::Value* buildSearchIterator(JitLlvmCodeGenContext* ctx, JitIndexScanDirection index_scan_direction,
JitRangeBoundMode range_bound_mode, JitRangeScanType range_scan_type, int subQueryIndex /* = -1 */)
static llvm::Value* buildSearchIterator(JitLlvmCodeGenContext* ctx, JitIndexScanDirection index_scan_direction,
JitRangeBoundMode range_bound_mode, JitRangeScanType range_scan_type, int subQueryIndex = -1)
{
// search the row
IssueDebugLog("Searching range start");
@ -383,8 +402,8 @@ llvm::Value* buildSearchIterator(JitLlvmCodeGenContext* ctx, JitIndexScanDirecti
}
/** @brief Adds code to search for an iterator. */
llvm::Value* buildBeginIterator(
JitLlvmCodeGenContext* ctx, JitRangeScanType rangeScanType, int subQueryIndex /* = -1 */)
static llvm::Value* buildBeginIterator(
JitLlvmCodeGenContext* ctx, JitRangeScanType rangeScanType, int subQueryIndex = -1)
{
// search the row
IssueDebugLog("Getting begin iterator for full-scan");
@ -421,7 +440,7 @@ llvm::Value* buildGetRowFromIterator(JitLlvmCodeGenContext* ctx, llvm::BasicBloc
}
/** @brief Process constant expression. */
llvm::Value* ProcessConstExpr(
static llvm::Value* ProcessConstExpr(
JitLlvmCodeGenContext* ctx, const Const* const_value, int& result_type, int arg_pos, int depth, int* max_arg)
{
llvm::Value* result = nullptr;
@ -446,7 +465,7 @@ llvm::Value* ProcessConstExpr(
}
/** @brief Process Param expression. */
llvm::Value* ProcessParamExpr(
static llvm::Value* ProcessParamExpr(
JitLlvmCodeGenContext* ctx, const Param* param, int& result_type, int arg_pos, int depth, int* max_arg)
{
llvm::Value* result = nullptr;
@ -470,7 +489,7 @@ llvm::Value* ProcessParamExpr(
}
/** @brief Process Relabel expression as Param expression. */
llvm::Value* ProcessRelabelExpr(
static llvm::Value* ProcessRelabelExpr(
JitLlvmCodeGenContext* ctx, RelabelType* relabel_type, int& result_type, int arg_pos, int depth, int* max_arg)
{
llvm::Value* result = nullptr;
@ -486,7 +505,7 @@ llvm::Value* ProcessRelabelExpr(
}
/** @brief Proess Var expression. */
llvm::Value* ProcessVarExpr(
static llvm::Value* ProcessVarExpr(
JitLlvmCodeGenContext* ctx, const Var* var, int& result_type, int arg_pos, int depth, int* max_arg)
{
llvm::Value* result = nullptr;
@ -511,7 +530,7 @@ llvm::Value* ProcessVarExpr(
}
/** @brief Adds call to PG unary operator. */
llvm::Value* AddExecUnaryOperator(
static llvm::Value* AddExecUnaryOperator(
JitLlvmCodeGenContext* ctx, llvm::Value* param, llvm::Constant* unary_operator, int arg_pos)
{
llvm::Constant* arg_pos_value = llvm::ConstantInt::get(ctx->INT32_T, arg_pos, true);
@ -519,7 +538,7 @@ llvm::Value* AddExecUnaryOperator(
}
/** @brief Adds call to PG binary operator. */
llvm::Value* AddExecBinaryOperator(JitLlvmCodeGenContext* ctx, llvm::Value* lhs_param, llvm::Value* rhs_param,
static llvm::Value* AddExecBinaryOperator(JitLlvmCodeGenContext* ctx, llvm::Value* lhs_param, llvm::Value* rhs_param,
llvm::Constant* binary_operator, int arg_pos)
{
llvm::Constant* arg_pos_value = llvm::ConstantInt::get(ctx->INT32_T, arg_pos, true);
@ -527,7 +546,7 @@ llvm::Value* AddExecBinaryOperator(JitLlvmCodeGenContext* ctx, llvm::Value* lhs_
}
/** @brief Adds call to PG ternary operator. */
llvm::Value* AddExecTernaryOperator(JitLlvmCodeGenContext* ctx, llvm::Value* param1, llvm::Value* param2,
static llvm::Value* AddExecTernaryOperator(JitLlvmCodeGenContext* ctx, llvm::Value* param1, llvm::Value* param2,
llvm::Value* param3, llvm::Constant* ternary_operator, int arg_pos)
{
llvm::Constant* arg_pos_value = llvm::ConstantInt::get(ctx->INT32_T, arg_pos, true);
@ -557,7 +576,7 @@ llvm::Value* AddExecTernaryOperator(JitLlvmCodeGenContext* ctx, llvm::Value* par
#define APPLY_TERNARY_CAST_OPERATOR(funcid, name) APPLY_TERNARY_OPERATOR(funcid, name)
/** @brief Process operator expression. */
llvm::Value* ProcessOpExpr(
static llvm::Value* ProcessOpExpr(
JitLlvmCodeGenContext* ctx, const OpExpr* op_expr, int& result_type, int arg_pos, int depth, int* max_arg)
{
llvm::Value* result = nullptr;
@ -568,7 +587,7 @@ llvm::Value* ProcessOpExpr(
}
if (list_length(op_expr->args) > 3) {
MOT_LOG_TRACE("Unsupported operator %d: too many arguments", op_expr->opno);
MOT_LOG_TRACE("Unsupported operator %u: too many arguments", op_expr->opno);
return nullptr;
}
@ -605,7 +624,7 @@ llvm::Value* ProcessOpExpr(
}
/** @brief Process function expression. */
llvm::Value* ProcessFuncExpr(
static llvm::Value* ProcessFuncExpr(
JitLlvmCodeGenContext* ctx, const FuncExpr* func_expr, int& result_type, int arg_pos, int depth, int* max_arg)
{
llvm::Value* result = nullptr;
@ -678,7 +697,7 @@ llvm::Value* ProcessFuncExpr(
MOT_LOG_TRACE("Unexpected call in filter expression to ternary cast builtin: " #name); \
break;
llvm::Value* ProcessFilterExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitFilter* filter, int* max_arg)
static llvm::Value* ProcessFilterExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitFilter* filter, int* max_arg)
{
llvm::Value* result = nullptr;
@ -716,7 +735,8 @@ llvm::Value* ProcessFilterExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, Jit
#undef APPLY_TERNARY_CAST_OPERATOR
/** @brief Process an expression. Generates code to evaluate the expression. */
llvm::Value* ProcessExpr(JitLlvmCodeGenContext* ctx, Expr* expr, int& result_type, int arg_pos, int depth, int* max_arg)
static llvm::Value* ProcessExpr(
JitLlvmCodeGenContext* ctx, Expr* expr, int& result_type, int arg_pos, int depth, int* max_arg)
{
llvm::Value* result = nullptr;
MOT_LOG_DEBUG("%*s --> Processing expression %d", depth, "", (int)expr->type);
@ -747,7 +767,7 @@ llvm::Value* ProcessExpr(JitLlvmCodeGenContext* ctx, Expr* expr, int& result_typ
return result;
}
llvm::Value* ProcessConstExpr(JitLlvmCodeGenContext* ctx, const JitConstExpr* expr, int* max_arg)
static llvm::Value* ProcessConstExpr(JitLlvmCodeGenContext* ctx, const JitConstExpr* expr, int* max_arg)
{
AddSetExprArgIsNull(ctx, expr->_arg_pos, expr->_is_null); // mark expression null status
llvm::Value* result = llvm::ConstantInt::get(ctx->INT64_T, expr->_value, true);
@ -757,7 +777,7 @@ llvm::Value* ProcessConstExpr(JitLlvmCodeGenContext* ctx, const JitConstExpr* ex
return result;
}
llvm::Value* ProcessParamExpr(JitLlvmCodeGenContext* ctx, const JitParamExpr* expr, int* max_arg)
static llvm::Value* ProcessParamExpr(JitLlvmCodeGenContext* ctx, const JitParamExpr* expr, int* max_arg)
{
llvm::Value* result = AddGetDatumParam(ctx, expr->_param_id, expr->_arg_pos);
if (max_arg && (expr->_arg_pos > *max_arg)) {
@ -766,7 +786,7 @@ llvm::Value* ProcessParamExpr(JitLlvmCodeGenContext* ctx, const JitParamExpr* ex
return result;
}
llvm::Value* ProcessVarExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, const JitVarExpr* expr, int* max_arg)
static llvm::Value* ProcessVarExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, const JitVarExpr* expr, int* max_arg)
{
llvm::Value* result = nullptr;
if (row == nullptr) {
@ -804,7 +824,7 @@ llvm::Value* ProcessVarExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, const
#define APPLY_BINARY_CAST_OPERATOR(funcid, name) APPLY_BINARY_OPERATOR(funcid, name)
#define APPLY_TERNARY_CAST_OPERATOR(funcid, name) APPLY_TERNARY_OPERATOR(funcid, name)
llvm::Value* ProcessOpExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitOpExpr* expr, int* max_arg)
static llvm::Value* ProcessOpExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitOpExpr* expr, int* max_arg)
{
llvm::Value* result = nullptr;
@ -830,7 +850,7 @@ llvm::Value* ProcessOpExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitOpEx
return result;
}
llvm::Value* ProcessFuncExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitFuncExpr* expr, int* max_arg)
static llvm::Value* ProcessFuncExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitFuncExpr* expr, int* max_arg)
{
llvm::Value* result = nullptr;
@ -863,12 +883,12 @@ llvm::Value* ProcessFuncExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitFu
#undef APPLY_BINARY_CAST_OPERATOR
#undef APPLY_TERNARY_CAST_OPERATOR
llvm::Value* ProcessSubLinkExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitSubLinkExpr* expr, int* max_arg)
static llvm::Value* ProcessSubLinkExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitSubLinkExpr* expr, int* max_arg)
{
return AddSelectSubQueryResult(ctx, expr->_sub_query_index);
}
llvm::Value* ProcessBoolExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitBoolExpr* expr, int* maxArg)
static llvm::Value* ProcessBoolExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitBoolExpr* expr, int* maxArg)
{
llvm::Value* result = nullptr;
@ -909,7 +929,7 @@ llvm::Value* ProcessBoolExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitBo
return result;
}
llvm::Value* ProcessExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitExpr* expr, int* max_arg)
static llvm::Value* ProcessExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitExpr* expr, int* max_arg)
{
llvm::Value* result = nullptr;
@ -1064,7 +1084,7 @@ bool selectRowColumns(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitSelectExp
return result;
}
bool buildClosedRangeScan(JitLlvmCodeGenContext* ctx, JitIndexScan* index_scan, int* max_arg,
static bool buildClosedRangeScan(JitLlvmCodeGenContext* ctx, JitIndexScan* index_scan, int* max_arg,
JitRangeScanType range_scan_type, llvm::Value* outer_row, int subQueryIndex)
{
// a closed range scan starts just like a point scan (without enough search expressions) and then adds key patterns
@ -1699,7 +1719,7 @@ bool prepareAggregateCount(JitLlvmCodeGenContext* ctx, JitAggregate* aggregate)
return true;
}
bool prepareDistinctSet(JitLlvmCodeGenContext* ctx, const JitAggregate* aggregate)
static bool prepareDistinctSet(JitLlvmCodeGenContext* ctx, const JitAggregate* aggregate)
{
// we need a hash-set according to the aggregated type (preferably but not necessarily linear-probing hash)
// we use an opaque datum type, with a tailor-made hash-function and equals function
@ -1746,7 +1766,7 @@ bool prepareAggregate(JitLlvmCodeGenContext* ctx, JitAggregate* aggregate)
return result;
}
llvm::Value* buildAggregateAvg(
static llvm::Value* buildAggregateAvg(
JitLlvmCodeGenContext* ctx, const JitAggregate* aggregate, llvm::Value* current_aggregate, llvm::Value* var_expr)
{
llvm::Value* aggregate_expr = nullptr;
@ -1802,7 +1822,7 @@ llvm::Value* buildAggregateAvg(
return aggregate_expr;
}
llvm::Value* buildAggregateSum(
static llvm::Value* buildAggregateSum(
JitLlvmCodeGenContext* ctx, const JitAggregate* aggregate, llvm::Value* current_aggregate, llvm::Value* var_expr)
{
llvm::Value* aggregate_expr = nullptr;
@ -1845,7 +1865,7 @@ llvm::Value* buildAggregateSum(
return aggregate_expr;
}
llvm::Value* buildAggregateMax(
static llvm::Value* buildAggregateMax(
JitLlvmCodeGenContext* ctx, const JitAggregate* aggregate, llvm::Value* current_aggregate, llvm::Value* var_expr)
{
llvm::Value* aggregate_expr = nullptr;
@ -1913,7 +1933,7 @@ llvm::Value* buildAggregateMax(
return aggregate_expr;
}
llvm::Value* buildAggregateMin(
static llvm::Value* buildAggregateMin(
JitLlvmCodeGenContext* ctx, const JitAggregate* aggregate, llvm::Value* current_aggregate, llvm::Value* var_expr)
{
llvm::Value* aggregate_expr = nullptr;
@ -1977,7 +1997,7 @@ llvm::Value* buildAggregateMin(
return aggregate_expr;
}
llvm::Value* buildAggregateCount(
static llvm::Value* buildAggregateCount(
JitLlvmCodeGenContext* ctx, const JitAggregate* aggregate, llvm::Value* count_aggregate)
{
llvm::Value* aggregate_expr = nullptr;
@ -2000,7 +2020,7 @@ llvm::Value* buildAggregateCount(
return aggregate_expr;
}
bool buildAggregateMaxMin(JitLlvmCodeGenContext* ctx, JitAggregate* aggregate, llvm::Value* var_expr)
static bool buildAggregateMaxMin(JitLlvmCodeGenContext* ctx, JitAggregate* aggregate, llvm::Value* var_expr)
{
bool result = true;
@ -2033,7 +2053,7 @@ bool buildAggregateMaxMin(JitLlvmCodeGenContext* ctx, JitAggregate* aggregate, l
return result;
}
bool buildAggregateTuple(JitLlvmCodeGenContext* ctx, JitAggregate* aggregate, llvm::Value* var_expr)
static bool buildAggregateTuple(JitLlvmCodeGenContext* ctx, JitAggregate* aggregate, llvm::Value* var_expr)
{
bool result = false;

View File

@ -25,32 +25,21 @@
#ifndef JIT_LLVM_BLOCKS_H
#define JIT_LLVM_BLOCKS_H
// Be sure to include jit_llvm_query.h before anything else because of global.h.
// See jit_llvm_query.h for more details.
/*
* ATTENTION: Be sure to include jit_llvm_query.h before anything else because of gscodegen.h
* See jit_llvm_query.h for more details.
*/
#include "jit_llvm_query.h"
#include "jit_plan.h"
#include "jit_llvm_util.h"
namespace JitExec {
/** @brief Builds a code segment for checking if soft memory limit has been reached. */
void buildIsSoftMemoryLimitReached(JitLlvmCodeGenContext* ctx);
/** @brief Builds a code segment for writing datum value to a column. */
void buildWriteDatumColumn(JitLlvmCodeGenContext* ctx, llvm::Value* row, int colid, llvm::Value* datum_value);
/** @brief Builds a code segment for writing a row. */
void buildWriteRow(JitLlvmCodeGenContext* ctx, llvm::Value* row, bool isPKey, JitLlvmRuntimeCursor* cursor);
/** @brief Process a join expression (WHERE clause) and generate code to build a search key. */
bool ProcessJoinExpr(JitLlvmCodeGenContext* ctx, Expr* expr, int* column_count, int* column_array, int* max_arg);
/** @brief Process an operator expression (process only "COLUMN equals EXPR" operators). */
bool ProcessJoinOpExpr(
JitLlvmCodeGenContext* ctx, const OpExpr* op_expr, int* column_count, int* column_array, int* max_arg);
/** @brief Process a boolean operator (process only AND operators, since we handle only point queries, or full-prefix
* range update). */
bool ProcessJoinBoolExpr(
JitLlvmCodeGenContext* ctx, const BoolExpr* boolexpr, int* column_count, int* column_array, int* max_arg);
/** @brief Creates a jitted function for code generation. Builds prototype and entry block. */
void CreateJittedFunction(JitLlvmCodeGenContext* ctx, const char* function_name);
@ -67,8 +56,6 @@ llvm::Value* buildCreateNewRow(JitLlvmCodeGenContext* ctx);
llvm::Value* buildSearchRow(
JitLlvmCodeGenContext* ctx, MOT::AccessType access_type, JitRangeScanType range_scan_type, int subQueryIndex = -1);
llvm::Value* buildFilter(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitFilter* filter, int* max_arg);
bool buildFilterRow(
JitLlvmCodeGenContext* ctx, llvm::Value* row, JitFilterArray* filters, int* max_arg, llvm::BasicBlock* next_block);
@ -78,76 +65,11 @@ void buildInsertRow(JitLlvmCodeGenContext* ctx, llvm::Value* row);
/** @brief Adds code to delete a row. */
void buildDeleteRow(JitLlvmCodeGenContext* ctx);
/** @brief Adds code to search for an iterator. */
llvm::Value* buildSearchIterator(JitLlvmCodeGenContext* ctx, JitIndexScanDirection index_scan_direction,
JitRangeBoundMode range_bound_mode, JitRangeScanType range_scan_type, int subQueryIndex = -1);
/** @brief Adds code to search for an iterator. */
llvm::Value* buildBeginIterator(JitLlvmCodeGenContext* ctx, JitRangeScanType rangeScanType, int subQueryIndex = -1);
/** @brief Adds code to get row from iterator. */
llvm::Value* buildGetRowFromIterator(JitLlvmCodeGenContext* ctx, llvm::BasicBlock* endLoopBlock,
MOT::AccessType access_mode, JitIndexScanDirection index_scan_direction, JitLlvmRuntimeCursor* cursor,
JitRangeScanType range_scan_type, int subQueryIndex = -1);
/** @brief Process constant expression. */
llvm::Value* ProcessConstExpr(
JitLlvmCodeGenContext* ctx, const Const* const_value, int& result_type, int arg_pos, int depth, int* max_arg);
/** @brief Process Param expression. */
llvm::Value* ProcessParamExpr(
JitLlvmCodeGenContext* ctx, const Param* param, int& result_type, int arg_pos, int depth, int* max_arg);
/** @brief Process Relabel expression as Param expression. */
llvm::Value* ProcessRelabelExpr(
JitLlvmCodeGenContext* ctx, RelabelType* relabel_type, int& result_type, int arg_pos, int depth, int* max_arg);
/** @brief Proess Var expression. */
llvm::Value* ProcessVarExpr(
JitLlvmCodeGenContext* ctx, const Var* var, int& result_type, int arg_pos, int depth, int* max_arg);
/** @brief Adds call to PG unary operator. */
llvm::Value* AddExecUnaryOperator(
JitLlvmCodeGenContext* ctx, llvm::Value* param, llvm::Constant* unary_operator, int arg_pos);
/** @brief Adds call to PG binary operator. */
llvm::Value* AddExecBinaryOperator(JitLlvmCodeGenContext* ctx, llvm::Value* lhs_param, llvm::Value* rhs_param,
llvm::Constant* binary_operator, int arg_pos);
/** @brief Adds call to PG ternary operator. */
llvm::Value* AddExecTernaryOperator(JitLlvmCodeGenContext* ctx, llvm::Value* param1, llvm::Value* param2,
llvm::Value* param3, llvm::Constant* ternary_operator, int arg_pos);
/** @brief Process operator expression. */
llvm::Value* ProcessOpExpr(
JitLlvmCodeGenContext* ctx, const OpExpr* op_expr, int& result_type, int arg_pos, int depth, int* max_arg);
/** @brief Process function expression. */
llvm::Value* ProcessFuncExpr(
JitLlvmCodeGenContext* ctx, const FuncExpr* func_expr, int& result_type, int arg_pos, int depth, int* max_arg);
llvm::Value* ProcessFilterExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitFilter* filter, int* max_arg);
/** @brief Process an expression. Generates code to evaluate the expression. */
llvm::Value* ProcessExpr(
JitLlvmCodeGenContext* ctx, Expr* expr, int& result_type, int arg_pos, int depth, int* max_arg);
llvm::Value* ProcessConstExpr(JitLlvmCodeGenContext* ctx, const JitConstExpr* expr, int* max_arg);
llvm::Value* ProcessParamExpr(JitLlvmCodeGenContext* ctx, const JitParamExpr* expr, int* max_arg);
llvm::Value* ProcessVarExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, const JitVarExpr* expr, int* max_arg);
llvm::Value* ProcessOpExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitOpExpr* expr, int* max_arg);
llvm::Value* ProcessFuncExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitFuncExpr* expr, int* max_arg);
llvm::Value* ProcessSubLinkExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitSubLinkExpr* expr, int* max_arg);
llvm::Value* ProcessBoolExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitBoolExpr* expr, int* maxArg);
llvm::Value* ProcessExpr(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitExpr* expr, int* max_arg);
bool buildScanExpression(JitLlvmCodeGenContext* ctx, JitColumnExpr* expr, int* max_arg,
JitRangeIteratorType range_itr_type, JitRangeScanType range_scan_type, llvm::Value* outer_row, int subQueryIndex);
@ -160,9 +82,6 @@ bool writeRowColumns(
bool selectRowColumns(JitLlvmCodeGenContext* ctx, llvm::Value* row, JitSelectExprArray* expr_array, int* max_arg,
JitRangeScanType range_scan_type, int subQueryIndex = -1);
bool buildClosedRangeScan(JitLlvmCodeGenContext* ctx, JitIndexScan* index_scan, int* max_arg,
JitRangeScanType range_scan_type, llvm::Value* outer_row, int subQueryIndex);
bool buildSemiOpenRangeScan(JitLlvmCodeGenContext* ctx, JitIndexScan* indexScan, int* maxArg,
JitRangeScanType rangeScanType, JitRangeBoundMode* beginRangeBound, JitRangeBoundMode* endRangeBound,
llvm::Value* outerRow, int subQueryIndex);
@ -197,29 +116,8 @@ bool prepareAggregateMaxMin(JitLlvmCodeGenContext* ctx, JitAggregate* aggregate)
bool prepareAggregateCount(JitLlvmCodeGenContext* ctx, JitAggregate* aggregate);
bool prepareDistinctSet(JitLlvmCodeGenContext* ctx, const JitAggregate* aggregate);
bool prepareAggregate(JitLlvmCodeGenContext* ctx, JitAggregate* aggregate);
llvm::Value* buildAggregateAvg(
JitLlvmCodeGenContext* ctx, const JitAggregate* aggregate, llvm::Value* current_aggregate, llvm::Value* var_expr);
llvm::Value* buildAggregateSum(
JitLlvmCodeGenContext* ctx, const JitAggregate* aggregate, llvm::Value* current_aggregate, llvm::Value* var_expr);
llvm::Value* buildAggregateMax(
JitLlvmCodeGenContext* ctx, const JitAggregate* aggregate, llvm::Value* current_aggregate, llvm::Value* var_expr);
llvm::Value* buildAggregateMin(
JitLlvmCodeGenContext* ctx, const JitAggregate* aggregate, llvm::Value* current_aggregate, llvm::Value* var_expr);
llvm::Value* buildAggregateCount(
JitLlvmCodeGenContext* ctx, const JitAggregate* aggregate, llvm::Value* count_aggregate);
bool buildAggregateMaxMin(JitLlvmCodeGenContext* ctx, JitAggregate* aggregate, llvm::Value* var_expr);
bool buildAggregateTuple(JitLlvmCodeGenContext* ctx, JitAggregate* aggregate, llvm::Value* var_expr);
bool buildAggregateRow(
JitLlvmCodeGenContext* ctx, JitAggregate* aggregate, llvm::Value* row, llvm::BasicBlock* next_block);

View File

@ -25,9 +25,14 @@
#ifndef JIT_LLVM_FUNCS_H
#define JIT_LLVM_FUNCS_H
// Be sure to include jit_llvm_query.h before anything else because of global.h.
// See jit_llvm_query.h for more details.
/*
* ATTENTION: Be sure to include jit_llvm_query.h before anything else because of gscodegen.h
* See jit_llvm_query.h for more details.
*/
#include "jit_llvm_query.h"
#include "jit_plan.h"
#include <vector>
namespace JitExec {
/** @brief Gets a key from the execution context. */
@ -664,7 +669,7 @@ inline void AddInitSearchKey(JitLlvmCodeGenContext* ctx, JitRangeScanType rangeS
AddInitKey(ctx, ctx->inner_key_value, ctx->inner_index_value);
} else if (rangeScanType == JIT_RANGE_SCAN_MAIN) {
AddInitKey(ctx, ctx->key_value, ctx->index_value);
} else if (rangeScanType == JIT_RANGE_SCAN_MAIN) {
} else if (rangeScanType == JIT_RANGE_SCAN_SUB_QUERY) {
AddInitKey(ctx, ctx->m_subQueryData[subQueryIndex].m_searchKey, ctx->m_subQueryData[subQueryIndex].m_index);
}
}

View File

@ -25,44 +25,19 @@
#ifndef JIT_LLVM_QUERY_H
#define JIT_LLVM_QUERY_H
// Be sure to include global.h before postgres.h to avoid conflict between libintl.h (included in global.h)
// and c.h (included in postgres.h).
#include "global.h"
// be careful to include gscodegen.h before anything else to avoid clash with PM definition in datetime.h
/*
* ATTENTION:
* 1. Be sure to include gscodegen.h before anything else to avoid clash with PM definition in datetime.h.
* 2. Be sure to include libintl.h before gscodegen.h to avoid problem with gettext.
*/
#include "libintl.h"
#include "codegen/gscodegen.h"
#include "codegen/builtinscodegen.h"
#include "catalog/pg_operator.h"
#include "codegen/datecodegen.h"
#include "codegen/timestampcodegen.h"
#include "utils/fmgroids.h"
#include "nodes/parsenodes.h"
#include "storage/ipc.h"
#include "nodes/pg_list.h"
#include "tcop/dest.h"
#include "utils/numeric.h"
#include "utils/numeric_gs.h"
#include "catalog/pg_aggregate.h"
#include "mot_internal.h"
#include "storage/mot/jit_exec.h"
#include "jit_common.h"
#include "jit_plan.h"
#include "jit_llvm_util.h"
#include "jit_util.h"
#include "mot_engine.h"
#include "utilities.h"
#include "mot_internal.h"
#include "catalog_column_types.h"
#include "mot_error.h"
#include "utilities.h"
#include <vector>
#include <cassert>
// for checking if LLVM_ENABLE_DUMP is defined and for using LLVM_VERSION_STRING
#include "llvm/Config/llvm-config.h"
namespace JitExec {
/** @struct Holds instructions that evaluate in runtime to begin and end iterators of a cursor. */

View File

@ -22,13 +22,21 @@
* -------------------------------------------------------------------------
*/
// Be sure to include jit_llvm_query.h before anything else because of global.h.
// See jit_llvm_query.h for more details.
/*
* ATTENTION: Be sure to include jit_llvm_query.h before anything else because of gscodegen.h
* See jit_llvm_query.h for more details.
*/
#include "jit_llvm_query.h"
#include "jit_llvm_query_codegen.h"
#include "jit_llvm.h"
#include "jit_llvm_funcs.h"
#include "jit_llvm_blocks.h"
#include "jit_util.h"
#include "mot_error.h"
#include "utilities.h"
// for checking if LLVM_ENABLE_DUMP is defined and for using LLVM_VERSION_STRING
#include "llvm/Config/llvm-config.h"
namespace JitExec {
DECLARE_LOGGER(JitLlvmQueryCodegen, JitExec)
@ -274,7 +282,7 @@ static bool InitCompoundCodeGenContext(JitLlvmCodeGenContext* ctx, GsCodeGen* co
"Failed to allocate %u bytes for %u sub-query table information objects in code-generation context",
allocSize,
(unsigned)ctx->m_subQueryCount);
DestroyTableInfo(&ctx->_table_info);
DestroyCodeGenContext(ctx);
return false;
}
@ -302,12 +310,7 @@ static bool InitCompoundCodeGenContext(JitLlvmCodeGenContext* ctx, GsCodeGen* co
result = false;
}
if (!result) {
for (uint32_t j = 0; j < i; ++j) {
DestroyTableInfo(&ctx->m_subQueryTableInfo[j]);
}
MOT::MemSessionFree(ctx->m_subQueryTableInfo);
ctx->m_subQueryTableInfo = nullptr;
DestroyTableInfo(&ctx->_table_info);
DestroyCodeGenContext(ctx);
return false;
}
}
@ -322,6 +325,7 @@ static bool InitCompoundCodeGenContext(JitLlvmCodeGenContext* ctx, GsCodeGen* co
allocSize,
(unsigned)ctx->m_subQueryCount);
DestroyCodeGenContext(ctx);
return false;
}
errno_t erc = memset_s(ctx->m_subQueryData, allocSize, 0, allocSize);
securec_check(erc, "\0", "\0");
@ -341,6 +345,10 @@ static void DestroyCodeGenContext(JitLlvmCodeGenContext* ctx)
MOT::MemSessionFree(ctx->m_subQueryData);
ctx->m_subQueryData = nullptr;
}
if (ctx->m_subQueryTableInfo != nullptr) {
MOT::MemSessionFree(ctx->m_subQueryTableInfo);
ctx->m_subQueryTableInfo = nullptr;
}
if (ctx->_code_gen != nullptr) {
ctx->_code_gen->releaseResource();
delete ctx->_code_gen;
@ -381,30 +389,12 @@ static JitContext* FinalizeCodegen(JitLlvmCodeGenContext* ctx, int max_arg, JitC
MOT_LOG_DEBUG("Adding function to MCJit");
ctx->_code_gen->addFunctionToMCJit(ctx->m_jittedQuery, (void**)&jit_context->m_llvmFunction);
// on ARM platform we must ensure compilation is synchronized
#ifdef __aarch64__
if (!AcquireArmCompileLock()) {
MOT_LOG_TRACE("Failed to acquire compilation lock on ARM platform");
FreeJitContext(jit_context);
return nullptr;
}
#endif
MOT_LOG_DEBUG("Generating code...");
ctx->_code_gen->enableOptimizations(true);
ctx->_code_gen->compileCurrentModule(false);
MOT_LOG_DEBUG(
"MOT jitted query: code generated at %p --> %p", &jit_context->m_llvmFunction, jit_context->m_llvmFunction);
// on ARM platform we must ensure compilation is synchronized
#ifdef __aarch64__
if (!ReleaseArmCompileLock()) {
MOT_LOG_TRACE("Failed to release compilation lock on ARM platform");
FreeJitContext(jit_context);
return nullptr;
}
#endif
// setup execution details
jit_context->m_table = ctx->_table_info.m_table;
jit_context->m_index = ctx->_table_info.m_index;

View File

@ -22,8 +22,8 @@
* -------------------------------------------------------------------------
*/
#include "global.h"
#include "jit_llvm_util.h"
#include "global.h"
#include "utilities.h"
#include "knl/knl_session.h"
#include "utils/elog.h"
@ -125,7 +125,12 @@ void JitStatement::EvalNot(llvm::Value* value, llvm::BasicBlock* successBlock, l
bool JitStatement::CurrentBlockEndsInBranch()
{
return m_builder->GetInsertBlock()->back().isTerminator();
bool result = false;
llvm::BasicBlock* currentBlock = m_builder->GetInsertBlock();
if (!currentBlock->empty()) {
result = currentBlock->back().isTerminator();
}
return result;
}
JitIf::JitIf(

View File

@ -25,6 +25,12 @@
#ifndef JIT_LLVM_UTIL_H
#define JIT_LLVM_UTIL_H
/*
* ATTENTION:
* 1. Be sure to include gscodegen.h before anything else to avoid clash with PM definition in datetime.h.
* 2. Be sure to include libintl.h before gscodegen.h to avoid problem with gettext.
*/
#include "libintl.h"
#include "codegen/gscodegen.h"
#include "jit_common.h"

View File

@ -25,9 +25,6 @@
#ifndef JIT_PGPROC_H
#define JIT_PGPROC_H
// make sure to include these headers when using APPLY_OPERATORS macro.
// due to collision with LLVM definitions, make sure to include the following files in this order:
#include "codegen/gscodegen.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/int8.h"

View File

@ -22,10 +22,10 @@
* -------------------------------------------------------------------------
*/
#include <algorithm>
// Be sure to include global.h before postgres.h to avoid conflict between libintl.h (included in global.h)
// and c.h (included in postgres.h).
/*
* ATTENTION: Be sure to include global.h before postgres.h to avoid conflict between libintl.h (included in global.h)
* and c.h (included in postgres.h).
*/
#include "global.h"
#include "jit_plan.h"
#include "jit_common.h"
@ -34,6 +34,8 @@
#include "nodes/pg_list.h"
#include "catalog/pg_aggregate.h"
#include <algorithm>
namespace JitExec {
DECLARE_LOGGER(JitPlan, JitExec)
@ -1571,6 +1573,7 @@ static JitPlan* JitPrepareCompoundPlan(Query* query, Query* subQuery)
// verify plan yields a single result
if (!IsSingleResultPlan(sub_query_plan)) {
MOT_LOG_TRACE("Disqualifying sub-query plan: yielding more than one result");
JitDestroyPlan(sub_query_plan);
return nullptr;
}

View File

@ -22,8 +22,10 @@
* -------------------------------------------------------------------------
*/
// Be sure to include global.h before postgres.h to avoid conflict between libintl.h (included in global.h)
// and c.h (included in postgres.h).
/*
* ATTENTION: Be sure to include global.h before postgres.h to avoid conflict between libintl.h (included in global.h)
* and c.h (included in postgres.h).
*/
#include "global.h"
#include "jit_plan_expr.h"

View File

@ -32,6 +32,8 @@
#include "jit_common.h"
#include "utilities.h"
#include <algorithm>
namespace JitExec {
/** @enum Index scan direction constants. */
enum JitIndexScanDirection {

View File

@ -29,6 +29,8 @@
#include "utilities.h"
#include "mot_error.h"
#include <algorithm>
DECLARE_LOGGER(TVM, JitExec)
namespace tvm {
@ -996,6 +998,9 @@ Instruction* Builder::addInstruction(Instruction* instruction)
if (instruction->GetType() == Instruction::Regular) {
instruction->SetRegisterRef(_next_register_ref);
result = new (std::nothrow) RegisterRefInstruction(_next_register_ref);
if (result == nullptr) {
return nullptr;
}
_current_block->recordRegisterReferenceDefinition(_next_register_ref); // for later validation
_current_function->addInstruction(result); // for cleanup only
++_next_register_ref;

View File

@ -22,23 +22,42 @@
* -------------------------------------------------------------------------
*/
// Be sure to include jit_tvm_query.h before anything else because of global.h.
// See jit_tvm_query.h for more details.
#include "jit_tvm_funcs.h"
/*
* ATTENTION: Be sure to include jit_tvm_query.h before anything else because of libintl.h
* (jit_tvm_blocks.h includes jit_tvm_query.h before anything else).
* See jit_tvm_query.h for more details.
*/
#include "jit_tvm_blocks.h"
#include "jit_tvm_funcs.h"
#include "jit_tvm_util.h"
#include "jit_util.h"
#include "mot_error.h"
#include "utilities.h"
#include "catalog/pg_aggregate.h"
using namespace tvm;
namespace JitExec {
DECLARE_LOGGER(JitTvmBlocks, JitExec)
static bool ProcessJoinOpExpr(
JitTvmCodeGenContext* ctx, const OpExpr* op_expr, int* column_count, int* column_array, int* max_arg);
static bool ProcessJoinBoolExpr(
JitTvmCodeGenContext* ctx, const BoolExpr* boolexpr, int* column_count, int* column_array, int* max_arg);
static Instruction* buildExpression(JitTvmCodeGenContext* ctx, Expression* expr);
static Expression* ProcessExpr(
JitTvmCodeGenContext* ctx, Expr* expr, int& result_type, int arg_pos, int depth, int* max_arg);
static Expression* ProcessFilterExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitFilter* filter, int* max_arg);
static Expression* ProcessExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitExpr* expr, int* max_arg);
void CreateJittedFunction(JitTvmCodeGenContext* ctx, const char* function_name, const char* query_string)
{
ctx->m_jittedQuery = ctx->_builder->createFunction(function_name, query_string);
IssueDebugLog("Starting execution of jitted function");
}
bool ProcessJoinExpr(JitTvmCodeGenContext* ctx, Expr* expr, int* column_count, int* column_array, int* max_arg)
static bool ProcessJoinExpr(JitTvmCodeGenContext* ctx, Expr* expr, int* column_count, int* column_array, int* max_arg)
{
bool result = false;
if (expr->type == T_OpExpr) {
@ -51,7 +70,7 @@ bool ProcessJoinExpr(JitTvmCodeGenContext* ctx, Expr* expr, int* column_count, i
return result;
}
bool ProcessJoinOpExpr(
static bool ProcessJoinOpExpr(
JitTvmCodeGenContext* ctx, const OpExpr* op_expr, int* column_count, int* column_array, int* max_arg)
{
bool result = false;
@ -123,7 +142,7 @@ bool ProcessJoinOpExpr(
return result;
}
bool ProcessJoinBoolExpr(
static bool ProcessJoinBoolExpr(
JitTvmCodeGenContext* ctx, const BoolExpr* boolexpr, int* column_count, int* column_array, int* max_arg)
{
bool result = false;
@ -161,7 +180,7 @@ void buildIsSoftMemoryLimitReached(JitTvmCodeGenContext* ctx)
JIT_IF_END()
}
Instruction* buildExpression(JitTvmCodeGenContext* ctx, Expression* expr)
static Instruction* buildExpression(JitTvmCodeGenContext* ctx, Expression* expr)
{
Instruction* expr_value = ctx->_builder->addExpression(expr);
@ -181,7 +200,7 @@ Instruction* buildExpression(JitTvmCodeGenContext* ctx, Expression* expr)
return expr_value;
}
void buildWriteDatumColumn(JitTvmCodeGenContext* ctx, Instruction* row, int colid, Instruction* datum_value)
static void buildWriteDatumColumn(JitTvmCodeGenContext* ctx, Instruction* row, int colid, Instruction* datum_value)
{
// ATTENTION: The datum_value expression-instruction MUST be already evaluated before this code is executed
// That is the reason why the expression-instruction was added to the current block and now we
@ -261,7 +280,7 @@ Instruction* buildSearchRow(JitTvmCodeGenContext* ctx, MOT::AccessType access_ty
return row;
}
Expression* buildFilter(JitTvmCodeGenContext* ctx, Instruction* row, JitFilter* filter, int* max_arg)
static Expression* buildFilter(JitTvmCodeGenContext* ctx, Instruction* row, JitFilter* filter, int* max_arg)
{
Expression* result = nullptr;
Expression* lhs_expr = ProcessExpr(ctx, row, filter->_lhs_operand, max_arg);
@ -339,8 +358,8 @@ void buildDeleteRow(JitTvmCodeGenContext* ctx)
IssueDebugLog("Row deleted");
}
Instruction* buildSearchIterator(JitTvmCodeGenContext* ctx, JitIndexScanDirection index_scan_direction,
JitRangeBoundMode range_bound_mode, JitRangeScanType range_scan_type, int subQueryIndex /* = -1 */)
static Instruction* buildSearchIterator(JitTvmCodeGenContext* ctx, JitIndexScanDirection index_scan_direction,
JitRangeBoundMode range_bound_mode, JitRangeScanType range_scan_type, int subQueryIndex = -1)
{
// search the row
IssueDebugLog("Searching range start");
@ -357,7 +376,8 @@ Instruction* buildSearchIterator(JitTvmCodeGenContext* ctx, JitIndexScanDirectio
}
/** @brief Adds code to search for an iterator. */
Instruction* buildBeginIterator(JitTvmCodeGenContext* ctx, JitRangeScanType rangeScanType, int subQueryIndex /* = -1 */)
static Instruction* buildBeginIterator(
JitTvmCodeGenContext* ctx, JitRangeScanType rangeScanType, int subQueryIndex = -1)
{
// search the row
IssueDebugLog("Getting begin iterator for full-scan");
@ -392,7 +412,7 @@ Instruction* buildGetRowFromIterator(JitTvmCodeGenContext* ctx, BasicBlock* endL
return row;
}
Expression* ProcessConstExpr(
static Expression* ProcessConstExpr(
JitTvmCodeGenContext* ctx, const Const* const_value, int& result_type, int arg_pos, int depth, int* max_arg)
{
Expression* result = nullptr;
@ -416,7 +436,7 @@ Expression* ProcessConstExpr(
return result;
}
Expression* ProcessParamExpr(
static Expression* ProcessParamExpr(
JitTvmCodeGenContext* ctx, const Param* param, int& result_type, int arg_pos, int depth, int* max_arg)
{
Expression* result = nullptr;
@ -440,7 +460,7 @@ Expression* ProcessParamExpr(
return result;
}
Expression* ProcessRelabelExpr(
static Expression* ProcessRelabelExpr(
JitTvmCodeGenContext* ctx, RelabelType* relabel_type, int& result_type, int arg_pos, int depth, int* max_arg)
{
MOT_LOG_DEBUG("Processing RELABEL expression");
@ -448,7 +468,7 @@ Expression* ProcessRelabelExpr(
return ProcessParamExpr(ctx, param, result_type, arg_pos, depth, max_arg);
}
Expression* ProcessVarExpr(
static Expression* ProcessVarExpr(
JitTvmCodeGenContext* ctx, const Var* var, int& result_type, int arg_pos, int depth, int* max_arg)
{
Expression* result = nullptr;
@ -509,7 +529,7 @@ Expression* ProcessVarExpr(
result = new (std::nothrow) name##Operator(args[0], args[1], args[2], arg_pos); \
break;
Expression* ProcessOpExpr(
static Expression* ProcessOpExpr(
JitTvmCodeGenContext* ctx, const OpExpr* op_expr, int& result_type, int arg_pos, int depth, int* max_arg)
{
Expression* result = nullptr;
@ -555,7 +575,7 @@ Expression* ProcessOpExpr(
return result;
}
Expression* ProcessFuncExpr(
static Expression* ProcessFuncExpr(
JitTvmCodeGenContext* ctx, const FuncExpr* func_expr, int& result_type, int arg_pos, int depth, int* max_arg)
{
Expression* result = nullptr;
@ -608,7 +628,8 @@ Expression* ProcessFuncExpr(
#undef APPLY_BINARY_CAST_OPERATOR
#undef APPLY_TERNARY_CAST_OPERATOR
Expression* ProcessExpr(JitTvmCodeGenContext* ctx, Expr* expr, int& result_type, int arg_pos, int depth, int* max_arg)
static Expression* ProcessExpr(
JitTvmCodeGenContext* ctx, Expr* expr, int& result_type, int arg_pos, int depth, int* max_arg)
{
Expression* result = nullptr;
MOT_LOG_DEBUG("%*s --> Processing expression %d", depth, "", (int)expr->type);
@ -639,7 +660,7 @@ Expression* ProcessExpr(JitTvmCodeGenContext* ctx, Expr* expr, int& result_type,
return result;
}
Expression* ProcessConstExpr(JitTvmCodeGenContext* ctx, const JitConstExpr* expr, int* max_arg)
static Expression* ProcessConstExpr(JitTvmCodeGenContext* ctx, const JitConstExpr* expr, int* max_arg)
{
AddSetExprArgIsNull(ctx, expr->_arg_pos, (expr->_is_null ? 1 : 0)); // mark expression null status
Expression* result = new (std::nothrow) ConstExpression(expr->_value, expr->_arg_pos, (int)(expr->_is_null));
@ -649,7 +670,7 @@ Expression* ProcessConstExpr(JitTvmCodeGenContext* ctx, const JitConstExpr* expr
return result;
}
Expression* ProcessParamExpr(JitTvmCodeGenContext* ctx, const JitParamExpr* expr, int* max_arg)
static Expression* ProcessParamExpr(JitTvmCodeGenContext* ctx, const JitParamExpr* expr, int* max_arg)
{
Expression* result = AddGetDatumParam(ctx, expr->_param_id, expr->_arg_pos);
if (max_arg && (expr->_arg_pos > *max_arg)) {
@ -658,7 +679,7 @@ Expression* ProcessParamExpr(JitTvmCodeGenContext* ctx, const JitParamExpr* expr
return result;
}
Expression* ProcessVarExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitVarExpr* expr, int* max_arg)
static Expression* ProcessVarExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitVarExpr* expr, int* max_arg)
{
Expression* result = nullptr;
if (row == nullptr) {
@ -708,7 +729,7 @@ Expression* ProcessVarExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitVarEx
result = new (std::nothrow) name##Operator(args[0], args[1], args[2], arg_pos); \
break;
Expression* ProcessOpExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitOpExpr* expr, int* max_arg)
static Expression* ProcessOpExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitOpExpr* expr, int* max_arg)
{
Expression* result = nullptr;
@ -737,7 +758,7 @@ Expression* ProcessOpExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitOpExpr
return result;
}
Expression* ProcessFuncExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitFuncExpr* expr, int* max_arg)
static Expression* ProcessFuncExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitFuncExpr* expr, int* max_arg)
{
Expression* result = nullptr;
@ -792,7 +813,7 @@ Expression* ProcessFuncExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitFunc
MOT_LOG_TRACE("Unexpected call in filter expression to ternary cast builtin: " #name); \
break;
Expression* ProcessFilterExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitFilter* filter, int* max_arg)
static Expression* ProcessFilterExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitFilter* filter, int* max_arg)
{
Expression* result = nullptr;
@ -830,12 +851,12 @@ Expression* ProcessFilterExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitFi
#undef APPLY_BINARY_CAST_OPERATOR
#undef APPLY_TERNARY_CAST_OPERATOR
Expression* ProcessSubLinkExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitSubLinkExpr* expr, int* max_arg)
static Expression* ProcessSubLinkExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitSubLinkExpr* expr, int* max_arg)
{
return AddSelectSubQueryResult(ctx, expr->_sub_query_index);
}
Expression* ProcessBoolExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitBoolExpr* expr, int* maxArg)
static Expression* ProcessBoolExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitBoolExpr* expr, int* maxArg)
{
Expression* result = nullptr;
@ -871,7 +892,7 @@ Expression* ProcessBoolExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitBool
return result;
}
Expression* ProcessExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitExpr* expr, int* max_arg)
static Expression* ProcessExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitExpr* expr, int* max_arg)
{
Expression* result = nullptr;
@ -897,7 +918,7 @@ Expression* ProcessExpr(JitTvmCodeGenContext* ctx, Instruction* row, JitExpr* ex
return result;
}
bool buildScanExpression(JitTvmCodeGenContext* ctx, JitColumnExpr* expr, int* max_arg,
static bool buildScanExpression(JitTvmCodeGenContext* ctx, JitColumnExpr* expr, int* max_arg,
JitRangeIteratorType range_itr_type, JitRangeScanType range_scan_type, Instruction* outer_row, int subQueryIndex)
{
Expression* value_expr = ProcessExpr(ctx, outer_row, expr->_expr, max_arg);
@ -1025,7 +1046,7 @@ bool selectRowColumns(JitTvmCodeGenContext* ctx, Instruction* row, JitSelectExpr
return true;
}
bool buildClosedRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* indexScan, int* maxArg,
static bool buildClosedRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* indexScan, int* maxArg,
JitRangeScanType rangeScanType, Instruction* outerRow, int subQueryIndex)
{
// a closed range scan starts just like a point scan (with not enough search expressions) and then adds key patterns
@ -1079,7 +1100,7 @@ bool buildClosedRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* indexScan, in
return result;
}
bool buildSemiOpenRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* index_scan, int* max_arg,
static bool buildSemiOpenRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* index_scan, int* max_arg,
JitRangeScanType range_scan_type, JitRangeBoundMode* begin_range_bound, JitRangeBoundMode* end_range_bound,
Instruction* outer_row, int subQueryIndex)
{
@ -1205,7 +1226,7 @@ bool buildSemiOpenRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* index_scan,
return result;
}
bool buildOpenRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* index_scan, int* max_arg,
static bool buildOpenRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* index_scan, int* max_arg,
JitRangeScanType range_scan_type, JitRangeBoundMode* begin_range_bound, JitRangeBoundMode* end_range_bound,
Instruction* outer_row, int subQueryIndex)
{
@ -1368,9 +1389,9 @@ bool buildOpenRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* index_scan, int
return result;
}
bool buildRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* indexScan, int* maxArg, JitRangeScanType rangeScanType,
JitRangeBoundMode* beginRangeBound, JitRangeBoundMode* endRangeBound, Instruction* outerRow,
int subQueryIndex /* = -1 */)
static bool buildRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* indexScan, int* maxArg,
JitRangeScanType rangeScanType, JitRangeBoundMode* beginRangeBound, JitRangeBoundMode* endRangeBound,
Instruction* outerRow, int subQueryIndex = -1)
{
bool result = false;
@ -1402,7 +1423,7 @@ bool buildRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* indexScan, int* max
return result;
}
bool buildPrepareStateScan(JitTvmCodeGenContext* ctx, JitIndexScan* index_scan, int* max_arg,
static bool buildPrepareStateScan(JitTvmCodeGenContext* ctx, JitIndexScan* index_scan, int* max_arg,
JitRangeScanType range_scan_type, Instruction* outer_row)
{
JitRangeBoundMode begin_range_bound = JIT_RANGE_BOUND_NONE;
@ -1445,7 +1466,7 @@ bool buildPrepareStateScan(JitTvmCodeGenContext* ctx, JitIndexScan* index_scan,
return true;
}
bool buildPrepareStateRow(JitTvmCodeGenContext* ctx, MOT::AccessType access_mode, JitIndexScan* index_scan,
static bool buildPrepareStateRow(JitTvmCodeGenContext* ctx, MOT::AccessType access_mode, JitIndexScan* index_scan,
int* max_arg, JitRangeScanType range_scan_type, BasicBlock* next_block)
{
MOT_LOG_DEBUG("Generating select code for stateful range select");
@ -1570,7 +1591,7 @@ JitTvmRuntimeCursor buildRangeCursor(JitTvmCodeGenContext* ctx, JitIndexScan* in
return result;
}
bool prepareAggregateAvg(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate)
static bool prepareAggregateAvg(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate)
{
// although we already have this information in the aggregate descriptor, we still check again
switch (aggregate->_func_id) {
@ -1601,7 +1622,7 @@ bool prepareAggregateAvg(JitTvmCodeGenContext* ctx, const JitAggregate* aggregat
return true;
}
bool prepareAggregateSum(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate)
static bool prepareAggregateSum(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate)
{
switch (aggregate->_func_id) {
case INT8SUMFUNCOID:
@ -1637,13 +1658,13 @@ bool prepareAggregateSum(JitTvmCodeGenContext* ctx, const JitAggregate* aggregat
return true;
}
bool prepareAggregateMaxMin(JitTvmCodeGenContext* ctx, JitAggregate* aggregate)
static bool prepareAggregateMaxMin(JitTvmCodeGenContext* ctx, JitAggregate* aggregate)
{
AddResetAggMaxMinNull(ctx);
return true;
}
bool prepareAggregateCount(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate)
static bool prepareAggregateCount(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate)
{
switch (aggregate->_func_id) {
case 2147: // int8inc_any
@ -1659,7 +1680,7 @@ bool prepareAggregateCount(JitTvmCodeGenContext* ctx, const JitAggregate* aggreg
return true;
}
bool prepareDistinctSet(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate)
static bool prepareDistinctSet(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate)
{
// we need a hash-set according to the aggregated type (preferably but not necessarily linear-probing hash)
// we use an opaque datum type, with a tailor-made hash-function and equals function
@ -1706,7 +1727,7 @@ bool prepareAggregate(JitTvmCodeGenContext* ctx, JitAggregate* aggregate)
return result;
}
Expression* buildAggregateAvg(
static Expression* buildAggregateAvg(
JitTvmCodeGenContext* ctx, const JitAggregate* aggregate, Expression* current_aggregate, Expression* var_expr)
{
Expression* aggregate_expr = nullptr;
@ -1761,7 +1782,7 @@ Expression* buildAggregateAvg(
return aggregate_expr;
}
Expression* buildAggregateSum(
static Expression* buildAggregateSum(
JitTvmCodeGenContext* ctx, const JitAggregate* aggregate, Expression* current_aggregate, Expression* var_expr)
{
Expression* aggregate_expr = nullptr;
@ -1804,7 +1825,7 @@ Expression* buildAggregateSum(
return aggregate_expr;
}
Expression* buildAggregateMax(
static Expression* buildAggregateMax(
JitTvmCodeGenContext* ctx, const JitAggregate* aggregate, Expression* current_aggregate, Expression* var_expr)
{
Expression* aggregate_expr = nullptr;
@ -1872,7 +1893,7 @@ Expression* buildAggregateMax(
return aggregate_expr;
}
Expression* buildAggregateMin(
static Expression* buildAggregateMin(
JitTvmCodeGenContext* ctx, const JitAggregate* aggregate, Expression* current_aggregate, Expression* var_expr)
{
Expression* aggregate_expr = nullptr;
@ -1935,7 +1956,8 @@ Expression* buildAggregateMin(
return aggregate_expr;
}
Expression* buildAggregateCount(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate, Expression* count_aggregate)
static Expression* buildAggregateCount(
JitTvmCodeGenContext* ctx, const JitAggregate* aggregate, Expression* count_aggregate)
{
Expression* aggregate_expr = nullptr;
switch (aggregate->_func_id) {
@ -1957,7 +1979,7 @@ Expression* buildAggregateCount(JitTvmCodeGenContext* ctx, const JitAggregate* a
return aggregate_expr;
}
bool buildAggregateMaxMin(JitTvmCodeGenContext* ctx, JitAggregate* aggregate, Expression* var_expr)
static bool buildAggregateMaxMin(JitTvmCodeGenContext* ctx, JitAggregate* aggregate, Expression* var_expr)
{
bool result = true;
@ -1990,7 +2012,7 @@ bool buildAggregateMaxMin(JitTvmCodeGenContext* ctx, JitAggregate* aggregate, Ex
return result;
}
bool buildAggregateTuple(JitTvmCodeGenContext* ctx, JitAggregate* aggregate, Expression* var_expr)
static bool buildAggregateTuple(JitTvmCodeGenContext* ctx, JitAggregate* aggregate, Expression* var_expr)
{
bool result = false;

View File

@ -25,27 +25,18 @@
#ifndef JIT_TVM_BLOCKS_H
#define JIT_TVM_BLOCKS_H
// Be sure to include jit_tvm_query.h before anything else because of global.h.
// See jit_tvm_query.h for more details.
/*
* ATTENTION: Be sure to include jit_tvm_query.h before anything else because of libintl.h
* See jit_tvm_query.h for more details.
*/
#include "jit_tvm_query.h"
#include "jit_plan.h"
namespace JitExec {
void CreateJittedFunction(JitTvmCodeGenContext* ctx, const char* function_name, const char* query_string);
bool ProcessJoinExpr(JitTvmCodeGenContext* ctx, Expr* expr, int* column_count, int* column_array, int* max_arg);
bool ProcessJoinOpExpr(
JitTvmCodeGenContext* ctx, const OpExpr* op_expr, int* column_count, int* column_array, int* max_arg);
bool ProcessJoinBoolExpr(
JitTvmCodeGenContext* ctx, const BoolExpr* boolexpr, int* column_count, int* column_array, int* max_arg);
void buildIsSoftMemoryLimitReached(JitTvmCodeGenContext* ctx);
tvm::Instruction* buildExpression(JitTvmCodeGenContext* ctx, tvm::Expression* expr);
void buildWriteDatumColumn(JitTvmCodeGenContext* ctx, tvm::Instruction* row, int colid, tvm::Instruction* datum_value);
void buildWriteRow(JitTvmCodeGenContext* ctx, tvm::Instruction* row, bool isPKey, JitTvmRuntimeCursor* cursor);
void buildResetRowsProcessed(JitTvmCodeGenContext* ctx);
@ -57,8 +48,6 @@ tvm::Instruction* buildCreateNewRow(JitTvmCodeGenContext* ctx);
tvm::Instruction* buildSearchRow(
JitTvmCodeGenContext* ctx, MOT::AccessType access_type, JitRangeScanType range_scan_type, int subQueryIndex = -1);
tvm::Expression* buildFilter(JitTvmCodeGenContext* ctx, tvm::Instruction* row, JitFilter* filter, int* max_arg);
bool buildFilterRow(JitTvmCodeGenContext* ctx, tvm::Instruction* row, JitFilterArray* filters, int* max_arg,
tvm::BasicBlock* next_block);
@ -66,60 +55,10 @@ void buildInsertRow(JitTvmCodeGenContext* ctx, tvm::Instruction* row);
void buildDeleteRow(JitTvmCodeGenContext* ctx);
tvm::Instruction* buildSearchIterator(JitTvmCodeGenContext* ctx, JitIndexScanDirection index_scan_direction,
JitRangeBoundMode range_bound_mode, JitRangeScanType range_scan_type, int subQueryIndex = -1);
/** @brief Adds code to search for an iterator. */
tvm::Instruction* buildBeginIterator(JitTvmCodeGenContext* ctx, JitRangeScanType rangeScanType, int subQueryIndex = -1);
tvm::Instruction* buildGetRowFromIterator(JitTvmCodeGenContext* ctx, tvm::BasicBlock* endLoopBlock,
MOT::AccessType access_mode, JitIndexScanDirection index_scan_direction, JitTvmRuntimeCursor* cursor,
JitRangeScanType range_scan_type, int subQueryIndex = -1);
tvm::Expression* ProcessConstExpr(
JitTvmCodeGenContext* ctx, const Const* const_value, int& result_type, int arg_pos, int depth, int* max_arg);
tvm::Expression* ProcessParamExpr(
JitTvmCodeGenContext* ctx, const Param* param, int& result_type, int arg_pos, int depth, int* max_arg);
tvm::Expression* ProcessRelabelExpr(
JitTvmCodeGenContext* ctx, RelabelType* relabel_type, int& result_type, int arg_pos, int depth, int* max_arg);
tvm::Expression* ProcessVarExpr(
JitTvmCodeGenContext* ctx, const Var* var, int& result_type, int arg_pos, int depth, int* max_arg);
tvm::Expression* ProcessOpExpr(
JitTvmCodeGenContext* ctx, const OpExpr* op_expr, int& result_type, int arg_pos, int depth, int* max_arg);
tvm::Expression* ProcessFuncExpr(
JitTvmCodeGenContext* ctx, const FuncExpr* func_expr, int& result_type, int arg_pos, int depth, int* max_arg);
tvm::Expression* ProcessExpr(
JitTvmCodeGenContext* ctx, Expr* expr, int& result_type, int arg_pos, int depth, int* max_arg);
tvm::Expression* ProcessConstExpr(JitTvmCodeGenContext* ctx, const JitConstExpr* expr, int* max_arg);
tvm::Expression* ProcessParamExpr(JitTvmCodeGenContext* ctx, const JitParamExpr* expr, int* max_arg);
tvm::Expression* ProcessVarExpr(JitTvmCodeGenContext* ctx, tvm::Instruction* row, JitVarExpr* expr, int* max_arg);
tvm::Expression* ProcessOpExpr(JitTvmCodeGenContext* ctx, tvm::Instruction* row, JitOpExpr* expr, int* max_arg);
tvm::Expression* ProcessFuncExpr(JitTvmCodeGenContext* ctx, tvm::Instruction* row, JitFuncExpr* expr, int* max_arg);
tvm::Expression* ProcessFilterExpr(JitTvmCodeGenContext* ctx, tvm::Instruction* row, JitFilter* filter, int* max_arg);
tvm::Expression* ProcessSubLinkExpr(
JitTvmCodeGenContext* ctx, tvm::Instruction* row, JitSubLinkExpr* expr, int* max_arg);
tvm::Expression* ProcessBoolExpr(JitTvmCodeGenContext* ctx, tvm::Instruction* row, JitBoolExpr* expr, int* maxArg);
tvm::Expression* ProcessExpr(JitTvmCodeGenContext* ctx, tvm::Instruction* row, JitExpr* expr, int* max_arg);
bool buildScanExpression(JitTvmCodeGenContext* ctx, JitColumnExpr* expr, int* max_arg,
JitRangeIteratorType range_itr_type, JitRangeScanType range_scan_type, tvm::Instruction* outer_row,
int subQueryIndex);
bool buildPointScan(JitTvmCodeGenContext* ctx, JitColumnExprArray* expr_array, int* max_arg,
JitRangeScanType range_scan_type, tvm::Instruction* outer_row, int expr_count = -1, int subQueryIndex = -1);
@ -129,27 +68,6 @@ bool writeRowColumns(
bool selectRowColumns(JitTvmCodeGenContext* ctx, tvm::Instruction* row, JitSelectExprArray* expr_array, int* max_arg,
JitRangeScanType range_scan_type, int subQueryIndex = -1);
bool buildClosedRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* indexScan, int* maxArg,
JitRangeScanType rangeScanType, tvm::Instruction* outerRow, int subQueryIndex);
bool buildSemiOpenRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* index_scan, int* max_arg,
JitRangeScanType range_scan_type, JitRangeBoundMode* begin_range_bound, JitRangeBoundMode* end_range_bound,
tvm::Instruction* outer_row, int subQueryIndex);
bool buildOpenRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* index_scan, int* max_arg,
JitRangeScanType range_scan_type, JitRangeBoundMode* begin_range_bound, JitRangeBoundMode* end_range_bound,
tvm::Instruction* outer_row, int subQueryIndex);
bool buildRangeScan(JitTvmCodeGenContext* ctx, JitIndexScan* indexScan, int* maxArg, JitRangeScanType rangeScanType,
JitRangeBoundMode* beginRangeBound, JitRangeBoundMode* endRangeBound, tvm::Instruction* outerRow,
int subQueryIndex = -1);
bool buildPrepareStateScan(JitTvmCodeGenContext* ctx, JitIndexScan* index_scan, int* max_arg,
JitRangeScanType range_scan_type, tvm::Instruction* outer_row);
bool buildPrepareStateRow(JitTvmCodeGenContext* ctx, MOT::AccessType access_mode, JitIndexScan* index_scan,
int* max_arg, JitRangeScanType range_scan_type, tvm::BasicBlock* next_block);
tvm::Instruction* buildPrepareStateScanRow(JitTvmCodeGenContext* ctx, JitIndexScan* index_scan,
JitRangeScanType range_scan_type, MOT::AccessType access_mode, int* max_arg, tvm::Instruction* outer_row,
tvm::BasicBlock* next_block, tvm::BasicBlock** loop_block);
@ -158,37 +76,8 @@ JitTvmRuntimeCursor buildRangeCursor(JitTvmCodeGenContext* ctx, JitIndexScan* in
JitRangeScanType rangeScanType, JitIndexScanDirection indexScanDirection, tvm::Instruction* outerRow,
int subQueryIndex = -1);
bool prepareAggregateAvg(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate);
bool prepareAggregateSum(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate);
bool prepareAggregateMaxMin(JitTvmCodeGenContext* ctx, JitAggregate* aggregate);
bool prepareAggregateCount(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate);
bool prepareDistinctSet(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate);
bool prepareAggregate(JitTvmCodeGenContext* ctx, JitAggregate* aggregate);
tvm::Expression* buildAggregateAvg(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate,
tvm::Expression* current_aggregate, tvm::Expression* var_expr);
tvm::Expression* buildAggregateSum(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate,
tvm::Expression* current_aggregate, tvm::Expression* var_expr);
tvm::Expression* buildAggregateMax(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate,
tvm::Expression* current_aggregate, tvm::Expression* var_expr);
tvm::Expression* buildAggregateMin(JitTvmCodeGenContext* ctx, const JitAggregate* aggregate,
tvm::Expression* current_aggregate, tvm::Expression* var_expr);
tvm::Expression* buildAggregateCount(
JitTvmCodeGenContext* ctx, const JitAggregate* aggregate, tvm::Expression* count_aggregate);
bool buildAggregateMaxMin(JitTvmCodeGenContext* ctx, JitAggregate* aggregate, tvm::Expression* var_expr);
bool buildAggregateTuple(JitTvmCodeGenContext* ctx, JitAggregate* aggregate, tvm::Expression* var_expr);
bool buildAggregateRow(
JitTvmCodeGenContext* ctx, JitAggregate* aggregate, tvm::Instruction* row, tvm::BasicBlock* next_block);

View File

@ -25,9 +25,12 @@
#ifndef JIT_TVM_FUNCS_H
#define JIT_TVM_FUNCS_H
// Be sure to include jit_tvm_query.h before anything else because of global.h.
// See jit_tvm_query.h for more details.
/*
* ATTENTION: Be sure to include jit_tvm_query.h before anything else because of libintl.h
* See jit_tvm_query.h for more details.
*/
#include "jit_tvm_query.h"
#include "jit_plan_expr.h"
#include "logger.h"
namespace JitExec {

View File

@ -25,42 +25,12 @@
#ifndef JIT_TVM_QUERY_H
#define JIT_TVM_QUERY_H
// Be sure to include global.h before postgres.h to avoid conflict between libintl.h (included in global.h)
// and c.h (included in postgres.h).
#include "global.h"
// be careful to include gscodegen.h before anything else to avoid clash with PM definition in datetime.h
#include "codegen/gscodegen.h"
#include "postgres.h"
#include "catalog/pg_operator.h"
#include "utils/fmgroids.h"
#include "nodes/parsenodes.h"
#include "storage/ipc.h"
#include "nodes/pg_list.h"
#include "utils/elog.h"
#include "utils/numeric.h"
#include "utils/numeric_gs.h"
#include "catalog/pg_aggregate.h"
#include "mot_internal.h"
#include "storage/mot/jit_exec.h"
/*
* ATTENTION: Be sure to include libintl.h before anything else to avoid problem with gettext.
*/
#include "libintl.h"
#include "jit_common.h"
#include "jit_tvm.h"
#include "jit_tvm_util.h"
#include "jit_util.h"
#include "jit_plan.h"
#include "mot_engine.h"
#include "utilities.h"
#include "mot_internal.h"
#include "catalog_column_types.h"
#include "mot_error.h"
#include "utilities.h"
#include "mm_session_api.h"
#include <list>
#include <string>
#include <cassert>
namespace JitExec {
/** @struct Holds instructions that evaluate in runtime to begin and end iterators of a cursor. */

View File

@ -22,12 +22,17 @@
* -------------------------------------------------------------------------
*/
// Be sure to include jit_tvm_query.h before anything else because of global.h.
// See jit_tvm_query.h for more details.
/*
* ATTENTION: Be sure to include jit_tvm_query.h before anything else because of libintl.h
* See jit_tvm_query.h for more details.
*/
#include "jit_tvm_query.h"
#include "jit_tvm_query_codegen.h"
#include "jit_tvm_funcs.h"
#include "jit_tvm_blocks.h"
#include "storage/mot/jit_exec.h"
#include "jit_tvm_util.h"
#include "jit_util.h"
using namespace tvm;

View File

@ -53,7 +53,7 @@
#include "access/redo_statistic_msg.h"
#include "portability/instr_time.h"
#include "replication/rto_statistic.h"
#include "storage/mot/jit_def.h"
const int NUM_PERCENTILE_COUNT = 2;
const int INIT_NUMA_ALLOC_COUNT = 32;
@ -544,6 +544,10 @@ typedef struct knl_g_bgworker_context {
volatile bool have_crashed_worker;
} knl_g_bgworker_context;
typedef struct knl_g_mot_context {
JitExec::JitExecMode jitExecMode;
} knl_g_mot_context;
typedef struct knl_instance_context {
knl_virtual_role role;
volatile int status;
@ -616,6 +620,7 @@ typedef struct knl_instance_context {
knl_g_rto_context rto_cxt;
knl_g_xlog_context xlog_cxt;
knl_g_numa_context numa_cxt;
knl_g_mot_context mot_cxt;
knl_g_bgworker_context bgworker_cxt;
} knl_instance_context;

View File

@ -2731,7 +2731,6 @@ typedef struct knl_t_mot_context {
// misc
uint8_t log_level;
bool init_codegen_once;
uint16_t currentThreadId;
int currentNumaNodeId;

View File

@ -159,6 +159,8 @@ public:
bool m_isCompleted;
long m_position;
private:
static FusionType GetMotFusionType(PlannedStmt* plannedStmt);
};
class SelectFusion : public OpFusion {

View File

@ -48,6 +48,18 @@ namespace JitExec {
// To use advanced WHERE clause operators, #define MOT_JIT_ADVANCED_WHERE_OP
// To enable features required for JIT testing, #define MOT_JIT_TEST
/** @enum JIT execution mode constants. */
enum JitExecMode : uint32_t {
/** @var Invalid execution mode. */
JIT_EXEC_MODE_INVALID,
/** @var LLVM execution mode. */
JIT_EXEC_MODE_LLVM,
/** @var TVM execution mode. */
JIT_EXEC_MODE_TVM
};
/** @enum JitCommandType Command types supported by jitted queries. */
enum JitCommandType : uint8_t {
/** @var Invalid command type. */

View File

@ -57,9 +57,6 @@ extern bool IsMotCodegenPrintEnabled();
/** @brief Queries for the per-session limit of JIT queries. */
extern uint32_t GetMotCodegenLimit();
/** @brief Turn off MOT JIT compilation and execution. */
extern void DisableMotCodegen();
/**
* @brief Queries whether a SQL query to be executed by MM Engine is jittable.
* @param query The parsed SQL query to examine.