From 558d01d2e9697494e62702f23e3e1bccc1ea0702 Mon Sep 17 00:00:00 2001 From: Vinoth Veeraraghavan Date: Mon, 7 Dec 2020 12:12:56 +0800 Subject: [PATCH 1/4] MOT fixes and code cleanup --- src/common/backend/catalog/index.cpp | 8 +- src/gausskernel/runtime/executor/opfusion.cpp | 31 +- .../storage/mot/core/src/Makefile.local | 9 +- .../src/infra/config/config_file_loader.cpp | 6 +- .../src/infra/stats/global_statistics.cpp | 5 +- .../core/src/infra/stats/global_statistics.h | 5 +- .../src/infra/stats/thread_statistics.cpp | 6 +- .../core/src/infra/stats/thread_statistics.h | 5 +- .../mot/core/src/memory/object_pool.cpp | 147 +---- .../storage/mot/core/src/memory/object_pool.h | 515 +---------------- .../mot/core/src/memory/object_pool_compact.h | 2 +- .../mot/core/src/memory/object_pool_impl.cpp | 165 ++++++ .../mot/core/src/memory/object_pool_impl.h | 541 ++++++++++++++++++ .../core/src/storage/index/index_iterator.h | 5 +- .../storage/mot/core/src/storage/key.h | 18 +- .../storage/mot/core/src/storage/table.cpp | 7 +- .../system/checkpoint/checkpoint_worker.cpp | 7 +- .../src/system/checkpoint/checkpoint_worker.h | 8 +- .../mot/core/src/system/mot_engine.cpp | 5 +- .../storage/mot/core/src/system/mot_engine.h | 3 +- .../system/recovery/checkpoint_recovery.cpp | 14 +- .../src/system/recovery/recovery_manager.cpp | 5 +- .../system/statistics/system_statistics.cpp | 29 +- .../src/system/statistics/system_statistics.h | 3 + .../mot/core/src/system/transaction/txn.cpp | 2 +- .../src/system/transaction/txn_access.cpp | 11 + .../transaction_logger/redo_log_buffer.h | 2 +- .../storage/mot/fdw_adapter/src/Makefile | 4 +- .../mot/fdw_adapter/src/mot_internal.cpp | 261 +++++---- .../mot/fdw_adapter/src/mot_internal.h | 9 + .../storage/mot/jit_exec/src/Makefile | 6 +- .../storage/mot/jit_exec/src/jit_common.cpp | 51 +- .../storage/mot/jit_exec/src/jit_context.cpp | 9 +- .../mot/jit_exec/src/jit_context_pool.cpp | 4 +- .../storage/mot/jit_exec/src/jit_exec.cpp | 50 +- .../storage/mot/jit_exec/src/jit_helpers.cpp | 8 +- .../storage/mot/jit_exec/src/jit_llvm.cpp | 110 +--- .../storage/mot/jit_exec/src/jit_llvm.h | 17 - .../mot/jit_exec/src/jit_llvm_blocks.cpp | 7 +- .../mot/jit_exec/src/jit_llvm_blocks.h | 8 +- .../storage/mot/jit_exec/src/jit_llvm_funcs.h | 11 +- .../storage/mot/jit_exec/src/jit_llvm_query.h | 37 +- .../jit_exec/src/jit_llvm_query_codegen.cpp | 44 +- .../mot/jit_exec/src/jit_llvm_util.cpp | 9 +- .../storage/mot/jit_exec/src/jit_llvm_util.h | 6 + .../storage/mot/jit_exec/src/jit_pgproc.h | 3 - .../storage/mot/jit_exec/src/jit_plan.cpp | 1 + .../storage/mot/jit_exec/src/jit_plan_expr.h | 1 + .../storage/mot/jit_exec/src/jit_tvm.cpp | 4 + .../storage/mot/jit_exec/src/jit_tvm_query.h | 11 +- src/include/opfusion/opfusion.h | 2 + 51 files changed, 1129 insertions(+), 1108 deletions(-) create mode 100644 src/gausskernel/storage/mot/core/src/memory/object_pool_impl.cpp create mode 100644 src/gausskernel/storage/mot/core/src/memory/object_pool_impl.h diff --git a/src/common/backend/catalog/index.cpp b/src/common/backend/catalog/index.cpp index 56b924938..126355e45 100755 --- a/src/common/backend/catalog/index.cpp +++ b/src/common/backend/catalog/index.cpp @@ -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); diff --git a/src/gausskernel/runtime/executor/opfusion.cpp b/src/gausskernel/runtime/executor/opfusion.cpp index 7184a3ec3..b96ac7769 100644 --- a/src/gausskernel/runtime/executor/opfusion.cpp +++ b/src/gausskernel/runtime/executor/opfusion.cpp @@ -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; diff --git a/src/gausskernel/storage/mot/core/src/Makefile.local b/src/gausskernel/storage/mot/core/src/Makefile.local index b74cb5b53..403e96f3f 100644 --- a/src/gausskernel/storage/mot/core/src/Makefile.local +++ b/src/gausskernel/storage/mot/core/src/Makefile.local @@ -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 := diff --git a/src/gausskernel/storage/mot/core/src/infra/config/config_file_loader.cpp b/src/gausskernel/storage/mot/core/src/infra/config/config_file_loader.cpp index 46b32d424..0858c4ae9 100644 --- a/src/gausskernel/storage/mot/core/src/infra/config/config_file_loader.cpp +++ b/src/gausskernel/storage/mot/core/src/infra/config/config_file_loader.cpp @@ -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"); } } diff --git a/src/gausskernel/storage/mot/core/src/infra/stats/global_statistics.cpp b/src/gausskernel/storage/mot/core/src/infra/stats/global_statistics.cpp index 629b6ac10..1c71c7dc1 100755 --- a/src/gausskernel/storage/mot/core/src/infra/stats/global_statistics.cpp +++ b/src/gausskernel/storage/mot/core/src/infra/stats/global_statistics.cpp @@ -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 diff --git a/src/gausskernel/storage/mot/core/src/infra/stats/global_statistics.h b/src/gausskernel/storage/mot/core/src/infra/stats/global_statistics.h index 866d90021..429dd8a67 100755 --- a/src/gausskernel/storage/mot/core/src/infra/stats/global_statistics.h +++ b/src/gausskernel/storage/mot/core/src/infra/stats/global_statistics.h @@ -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. */ diff --git a/src/gausskernel/storage/mot/core/src/infra/stats/thread_statistics.cpp b/src/gausskernel/storage/mot/core/src/infra/stats/thread_statistics.cpp index e268b55f2..e51665fe7 100644 --- a/src/gausskernel/storage/mot/core/src/infra/stats/thread_statistics.cpp +++ b/src/gausskernel/storage/mot/core/src/infra/stats/thread_statistics.cpp @@ -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 diff --git a/src/gausskernel/storage/mot/core/src/infra/stats/thread_statistics.h b/src/gausskernel/storage/mot/core/src/infra/stats/thread_statistics.h index 6459b9368..d40ae56fb 100644 --- a/src/gausskernel/storage/mot/core/src/infra/stats/thread_statistics.h +++ b/src/gausskernel/storage/mot/core/src/infra/stats/thread_statistics.h @@ -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. */ diff --git a/src/gausskernel/storage/mot/core/src/memory/object_pool.cpp b/src/gausskernel/storage/mot/core/src/memory/object_pool.cpp index ce46c3c33..430ad4d55 100644 --- a/src/gausskernel/storage/mot/core/src/memory/object_pool.cpp +++ b/src/gausskernel/storage/mot/core/src/memory/object_pool.cpp @@ -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) { diff --git a/src/gausskernel/storage/mot/core/src/memory/object_pool.h b/src/gausskernel/storage/mot/core/src/memory/object_pool.h index e89755ac9..ed2e39e1a 100644 --- a/src/gausskernel/storage/mot/core/src/memory/object_pool.h +++ b/src/gausskernel/storage/mot/core/src/memory/object_pool.h @@ -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 -#include -#include -#include -#include -#include - -#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 - inline T* Alloc(Args&&... args) - { - void* buf = Alloc(); - if (unlikely(buf == nullptr)) - return nullptr; - return new (buf) T(std::forward(args)...); - } - - virtual void Release(void* ptr) = 0; - template - 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 */ diff --git a/src/gausskernel/storage/mot/core/src/memory/object_pool_compact.h b/src/gausskernel/storage/mot/core/src/memory/object_pool_compact.h index 434050aa5..a09ebeb00 100644 --- a/src/gausskernel/storage/mot/core/src/memory/object_pool_compact.h +++ b/src/gausskernel/storage/mot/core/src/memory/object_pool_compact.h @@ -26,7 +26,7 @@ #define OBJECT_POOL_COMPACT_H #include -#include "object_pool.h" +#include "object_pool_impl.h" namespace MOT { #define PTR_MASK (((uint64_t)-1) << 10) diff --git a/src/gausskernel/storage/mot/core/src/memory/object_pool_impl.cpp b/src/gausskernel/storage/mot/core/src/memory/object_pool_impl.cpp new file mode 100644 index 000000000..19bc228be --- /dev/null +++ b/src/gausskernel/storage/mot/core/src/memory/object_pool_impl.cpp @@ -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 diff --git a/src/gausskernel/storage/mot/core/src/memory/object_pool_impl.h b/src/gausskernel/storage/mot/core/src/memory/object_pool_impl.h new file mode 100644 index 000000000..d34891251 --- /dev/null +++ b/src/gausskernel/storage/mot/core/src/memory/object_pool_impl.h @@ -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 +#include +#include +#include +#include +#include + +#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 + inline T* Alloc(Args&&... args) + { + void* buf = Alloc(); + if (unlikely(buf == nullptr)) + return nullptr; + return new (buf) T(std::forward(args)...); + } + + virtual void Release(void* ptr) = 0; + template + 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 */ diff --git a/src/gausskernel/storage/mot/core/src/storage/index/index_iterator.h b/src/gausskernel/storage/mot/core/src/storage/index/index_iterator.h index b537cad15..f31be3a9b 100644 --- a/src/gausskernel/storage/mot/core/src/storage/index/index_iterator.h +++ b/src/gausskernel/storage/mot/core/src/storage/index/index_iterator.h @@ -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: /** diff --git a/src/gausskernel/storage/mot/core/src/storage/key.h b/src/gausskernel/storage/mot/core/src/storage/key.h index 42f55d7d3..0f31b1de0 100644 --- a/src/gausskernel/storage/mot/core/src/storage/key.h +++ b/src/gausskernel/storage/mot/core/src/storage/key.h @@ -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(m_keyBuf), m_keyLen, buf, len); - securec_check(erc, "\0", "\0"); - } + MOT_ASSERT(len <= m_keyLen); + errno_t erc = memcpy_s(const_cast(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 diff --git a/src/gausskernel/storage/mot/core/src/storage/table.cpp b/src/gausskernel/storage/mot/core/src/storage/table.cpp index d1469d767..01114fb24 100644 --- a/src/gausskernel/storage/mot/core/src/storage/table.cpp +++ b/src/gausskernel/storage/mot/core/src/storage/table.cpp @@ -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()) { diff --git a/src/gausskernel/storage/mot/core/src/system/checkpoint/checkpoint_worker.cpp b/src/gausskernel/storage/mot/core/src/system/checkpoint/checkpoint_worker.cpp index c0572d059..12355b0fa 100644 --- a/src/gausskernel/storage/mot/core/src/system/checkpoint/checkpoint_worker.cpp +++ b/src/gausskernel/storage/mot/core/src/system/checkpoint/checkpoint_worker.cpp @@ -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, diff --git a/src/gausskernel/storage/mot/core/src/system/checkpoint/checkpoint_worker.h b/src/gausskernel/storage/mot/core/src/system/checkpoint/checkpoint_worker.h index f7672553e..6c6fcc0c5 100644 --- a/src/gausskernel/storage/mot/core/src/system/checkpoint/checkpoint_worker.h +++ b/src/gausskernel/storage/mot/core/src/system/checkpoint/checkpoint_worker.h @@ -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); diff --git a/src/gausskernel/storage/mot/core/src/system/mot_engine.cpp b/src/gausskernel/storage/mot/core/src/system/mot_engine.cpp index 8bfb66ad5..4e78aa2cb 100644 --- a/src/gausskernel/storage/mot/core/src/system/mot_engine.cpp +++ b/src/gausskernel/storage/mot/core/src/system/mot_engine.cpp @@ -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 diff --git a/src/gausskernel/storage/mot/core/src/system/mot_engine.h b/src/gausskernel/storage/mot/core/src/system/mot_engine.h index d3bdfb50f..12d79a811 100644 --- a/src/gausskernel/storage/mot/core/src/system/mot_engine.h +++ b/src/gausskernel/storage/mot/core/src/system/mot_engine.h @@ -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(); diff --git a/src/gausskernel/storage/mot/core/src/system/recovery/checkpoint_recovery.cpp b/src/gausskernel/storage/mot/core/src/system/recovery/checkpoint_recovery.cpp index 93c9d339d..22bc9885a 100644 --- a/src/gausskernel/storage/mot/core/src/system/recovery/checkpoint_recovery.cpp +++ b/src/gausskernel/storage/mot/core/src/system/recovery/checkpoint_recovery.cpp @@ -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", diff --git a/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp b/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp index a225bb8bc..10eeb990b 100644 --- a/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp +++ b/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp @@ -302,7 +302,7 @@ bool RecoveryManager::LogStats::FindIdx(uint64_t tableId, uint64_t& id) { id = m_numEntries; std::map::iterator it; - m_slock.lock(); + std::lock_guard lock(m_slock); it = m_idToIdx.find(tableId); if (it == m_idToIdx.end()) { Entry* newEntry = new (std::nothrow) Entry(tableId); @@ -315,7 +315,6 @@ bool RecoveryManager::LogStats::FindIdx(uint64_t tableId, uint64_t& id) } else { id = it->second; } - m_slock.unlock(); return true; } @@ -481,7 +480,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 " diff --git a/src/gausskernel/storage/mot/core/src/system/statistics/system_statistics.cpp b/src/gausskernel/storage/mot/core/src/system/statistics/system_statistics.cpp index 4d52452ff..0793f7528 100644 --- a/src/gausskernel/storage/mot/core/src/system/statistics/system_statistics.cpp +++ b/src/gausskernel/storage/mot/core/src/system/statistics/system_statistics.cpp @@ -40,10 +40,12 @@ TypedStatisticsGenerator 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) { diff --git a/src/gausskernel/storage/mot/core/src/system/statistics/system_statistics.h b/src/gausskernel/storage/mot/core/src/system/statistics/system_statistics.h index 6cc6b33f2..d03713095 100644 --- a/src/gausskernel/storage/mot/core/src/system/statistics/system_statistics.h +++ b/src/gausskernel/storage/mot/core/src/system/statistics/system_statistics.h @@ -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. diff --git a/src/gausskernel/storage/mot/core/src/system/transaction/txn.cpp b/src/gausskernel/storage/mot/core/src/system/transaction/txn.cpp index 0b72f65d2..bfd489d15 100644 --- a/src/gausskernel/storage/mot/core/src/system/transaction/txn.cpp +++ b/src/gausskernel/storage/mot/core/src/system/transaction/txn.cpp @@ -26,7 +26,7 @@ #include #include -#include "../storage/table.h" // explicit path in order to solve collision with B header file with the same name +#include "../storage/table.h" // explicit path in order to solve collision with B db header file with the same name #include "mot_engine.h" #include "redo_log_writer.h" #include "sentinel.h" diff --git a/src/gausskernel/storage/mot/core/src/system/transaction/txn_access.cpp b/src/gausskernel/storage/mot/core/src/system/transaction/txn_access.cpp index b2ffb67e6..09ce223cf 100644 --- a/src/gausskernel/storage/mot/core/src/system/transaction/txn_access.cpp +++ b/src/gausskernel/storage/mot/core/src/system/transaction/txn_access.cpp @@ -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; diff --git a/src/gausskernel/storage/mot/core/src/system/transaction_logger/redo_log_buffer.h b/src/gausskernel/storage/mot/core/src/system/transaction_logger/redo_log_buffer.h index 10f56dbf6..f639b4098 100644 --- a/src/gausskernel/storage/mot/core/src/system/transaction_logger/redo_log_buffer.h +++ b/src/gausskernel/storage/mot/core/src/system/transaction_logger/redo_log_buffer.h @@ -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; diff --git a/src/gausskernel/storage/mot/fdw_adapter/src/Makefile b/src/gausskernel/storage/mot/fdw_adapter/src/Makefile index ad26ba1d0..bb78bf0b9 100644 --- a/src/gausskernel/storage/mot/fdw_adapter/src/Makefile +++ b/src/gausskernel/storage/mot/fdw_adapter/src/Makefile @@ -49,9 +49,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 -endif +override CXXFLAGS += -faligned-new $(OBJS): | buildrepo diff --git a/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.cpp b/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.cpp index 0fdbecd2a..337b0a58c 100644 --- a/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.cpp +++ b/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.cpp @@ -2168,6 +2168,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,130 +2308,24 @@ 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; diff --git a/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.h b/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.h index d07ffcce4..ed9e15d32 100644 --- a/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.h +++ b/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.h @@ -311,6 +311,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) diff --git a/src/gausskernel/storage/mot/jit_exec/src/Makefile b/src/gausskernel/storage/mot/jit_exec/src/Makefile index d19ef182c..71503cb21 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/Makefile +++ b/src/gausskernel/storage/mot/jit_exec/src/Makefile @@ -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) diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_common.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_common.cpp index fac853a39..ef0eb4a72 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_common.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_common.cpp @@ -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; diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_context.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_context.cpp index 4e7176de0..62a2ff124 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_context.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_context.cpp @@ -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" diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_context_pool.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_context_pool.cpp index d68271164..cccdf4ca9 100755 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_context_pool.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_context_pool.cpp @@ -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); diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_exec.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_exec.cpp index ce1dc3664..f5d236866 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_exec.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_exec.cpp @@ -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" @@ -494,35 +498,24 @@ 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"); } else { PrintNativeLlvmStartupInfo(); } } 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"); + MOT::GetGlobalConfiguration().m_forcePseudoCodegen = true; + } } - 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 +558,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 +571,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 +592,4 @@ extern uint32_t GetMotCodegenLimit() { return MOT::GetGlobalConfiguration().m_codegenLimit; } - -extern void DisableMotCodegen() -{ - MOT_ATOMIC_STORE(MOT::GetGlobalConfiguration().m_enableCodegen, false); -} } // namespace JitExec diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_helpers.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_helpers.cpp index 6c663175d..4abbb0179 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_helpers.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_helpers.cpp @@ -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" diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.cpp index 21fe83609..f00317b05 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.cpp @@ -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() { + // 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("SSE4.2 is not supported, native LLVM will not be used."); } } return canInit; @@ -146,16 +82,6 @@ GsCodeGen* SetupCodegenEnv() } } - // 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 - // create GsCodeGen object for LLVM code generation GsCodeGen* code_gen = New(g_instance.instance_context) GsCodeGen(); if (code_gen != nullptr) { diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.h b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.h index 54acf0888..4ae274f00 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.h +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.h @@ -62,23 +62,6 @@ 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(); diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.cpp index f14a9bcec..b2e553ce1 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.cpp @@ -24,6 +24,11 @@ #include "jit_llvm_funcs.h" #include "jit_llvm_blocks.h" +#include "jit_util.h" +#include "mot_error.h" +#include "utilities.h" + +#include "catalog/pg_aggregate.h" using namespace dorado; @@ -568,7 +573,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; } diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.h b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.h index 510658a8e..f692e0fa9 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.h +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.h @@ -25,9 +25,13 @@ #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. */ diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_funcs.h b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_funcs.h index 62d5056dd..0a5c7b70f 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_funcs.h +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_funcs.h @@ -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 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); } } diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_query.h b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_query.h index 8cf7717ca..c56f926cd 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_query.h +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_query.h @@ -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 -#include - -// 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. */ diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_query_codegen.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_query_codegen.cpp index 593edb796..71c15a370 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_query_codegen.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_query_codegen.cpp @@ -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; diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_util.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_util.cpp index e8804b683..8172d6d39 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_util.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_util.cpp @@ -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( diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_util.h b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_util.h index 16af1edd9..2b746b83c 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_util.h +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_util.h @@ -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" diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_pgproc.h b/src/gausskernel/storage/mot/jit_exec/src/jit_pgproc.h index 1f22cabad..ef4741a3b 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_pgproc.h +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_pgproc.h @@ -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" diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_plan.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_plan.cpp index 91da662a8..3b23ed92c 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_plan.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_plan.cpp @@ -1571,6 +1571,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; } diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_plan_expr.h b/src/gausskernel/storage/mot/jit_exec/src/jit_plan_expr.h index 9f4312219..791ed7cff 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_plan_expr.h +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_plan_expr.h @@ -31,6 +31,7 @@ #include "storage/mot/jit_def.h" #include "jit_common.h" #include "utilities.h" +#include namespace JitExec { /** @enum Index scan direction constants. */ diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm.cpp index c9f9a7fe0..cb20b6451 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm.cpp @@ -28,6 +28,7 @@ #include "mot_engine.h" #include "utilities.h" #include "mot_error.h" +#include DECLARE_LOGGER(TVM, JitExec) @@ -996,6 +997,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; diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_query.h b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_query.h index a72a45978..4d43c70f0 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_query.h +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_query.h @@ -25,11 +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 +/* + * 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" diff --git a/src/include/opfusion/opfusion.h b/src/include/opfusion/opfusion.h index 7aee34c8a..255d6e93e 100644 --- a/src/include/opfusion/opfusion.h +++ b/src/include/opfusion/opfusion.h @@ -159,6 +159,8 @@ public: bool m_isCompleted; long m_position; +private: + static FusionType GetMotFusionType(PlannedStmt* plannedStmt); }; class SelectFusion : public OpFusion { From 74de6dfc320dc4c284e6ebaff979b6a3c53810dc Mon Sep 17 00:00:00 2001 From: Vinoth Veeraraghavan Date: Mon, 7 Dec 2020 18:07:47 +0800 Subject: [PATCH 2/4] Fix to protect deserialize of fdwstate by adding type --- .../storage/mot/fdw_adapter/src/mot_fdw.cpp | 102 ++++++++++-------- .../mot/fdw_adapter/src/mot_internal.h | 1 + 2 files changed, 61 insertions(+), 42 deletions(-) diff --git a/src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw.cpp b/src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw.cpp index c0c96edab..2b63546d5 100644 --- a/src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw.cpp +++ b/src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw.cpp @@ -191,14 +191,22 @@ static int MOTGetFdwType() 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); + 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); + } + } } } static 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)); @@ -1989,51 +1997,59 @@ MOTFdwStateSt* InitializeFdwState(void* fdwState, List** fdwExpr, uint64_t exTab { 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); + 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); + 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)); - } + if (cell != NULL) { + state->m_bestIx = &state->m_bestIxBuf; + state->m_bestIx->Deserialize(cell, exTableID); } - *fdwExpr = list_truncate(*fdwExpr, state->m_numExpr); + 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; } @@ -2042,6 +2058,8 @@ 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)); diff --git a/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.h b/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.h index ed9e15d32..031ea52b9 100644 --- a/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.h +++ b/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.h @@ -104,6 +104,7 @@ void report_pg_error(MOT::RC rc, MOT::TxnManager* txn, void* arg1 = nullptr, voi #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; From 282e48c46884c263e01ac2e3d571e46d6c40915a Mon Sep 17 00:00:00 2001 From: Vinoth Veeraraghavan Date: Tue, 8 Dec 2020 11:11:56 +0800 Subject: [PATCH 3/4] MOT code refactoring --- .../storage/mot/core/src/system/global.h | 2 + .../src/system/recovery/recovery_manager.cpp | 1 + .../mot/core/src/system/transaction/txn.cpp | 2 +- .../src/system/transaction/txn_access.cpp | 2 +- .../storage/mot/fdw_adapter/src/Makefile | 4 +- .../fdw_adapter/src/gaussdb_config_loader.h | 2 +- .../storage/mot/fdw_adapter/src/mot_fdw.cpp | 177 +-------- .../mot/fdw_adapter/src/mot_fdw_error.cpp | 253 +++++++++++++ .../mot/fdw_adapter/src/mot_fdw_error.h | 39 ++ .../mot/fdw_adapter/src/mot_internal.cpp | 350 ++++++------------ .../mot/fdw_adapter/src/mot_internal.h | 73 +++- .../storage/mot/jit_exec/src/jit_exec.cpp | 10 +- .../mot/jit_exec/src/jit_llvm_blocks.cpp | 91 +++-- .../mot/jit_exec/src/jit_llvm_blocks.h | 106 ------ .../storage/mot/jit_exec/src/jit_plan.cpp | 10 +- .../mot/jit_exec/src/jit_plan_expr.cpp | 6 +- .../storage/mot/jit_exec/src/jit_plan_expr.h | 1 + .../storage/mot/jit_exec/src/jit_tvm.cpp | 1 + .../mot/jit_exec/src/jit_tvm_blocks.cpp | 120 +++--- .../storage/mot/jit_exec/src/jit_tvm_blocks.h | 121 +----- .../storage/mot/jit_exec/src/jit_tvm_funcs.h | 7 +- .../storage/mot/jit_exec/src/jit_tvm_query.h | 33 +- .../jit_exec/src/jit_tvm_query_codegen.cpp | 9 +- 23 files changed, 642 insertions(+), 778 deletions(-) create mode 100644 src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw_error.cpp create mode 100644 src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw_error.h diff --git a/src/gausskernel/storage/mot/core/src/system/global.h b/src/gausskernel/storage/mot/core/src/system/global.h index 85c09ce11..d48e44001 100644 --- a/src/gausskernel/storage/mot/core/src/system/global.h +++ b/src/gausskernel/storage/mot/core/src/system/global.h @@ -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 diff --git a/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp b/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp index 10eeb990b..7b688fee5 100644 --- a/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp +++ b/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp @@ -71,6 +71,7 @@ bool RecoveryManager::RecoverDbStart() MOT_LOG_INFO("Starting MOT recovery"); if (m_recoverFromCkptDone) { + SetLsn(m_lastReplayLsn); return true; } diff --git a/src/gausskernel/storage/mot/core/src/system/transaction/txn.cpp b/src/gausskernel/storage/mot/core/src/system/transaction/txn.cpp index bfd489d15..97f66081a 100644 --- a/src/gausskernel/storage/mot/core/src/system/transaction/txn.cpp +++ b/src/gausskernel/storage/mot/core/src/system/transaction/txn.cpp @@ -26,7 +26,7 @@ #include #include -#include "../storage/table.h" // explicit path in order to solve collision with B db header file with the same name +#include "table.h" #include "mot_engine.h" #include "redo_log_writer.h" #include "sentinel.h" diff --git a/src/gausskernel/storage/mot/core/src/system/transaction/txn_access.cpp b/src/gausskernel/storage/mot/core/src/system/transaction/txn_access.cpp index 09ce223cf..34d71ab82 100644 --- a/src/gausskernel/storage/mot/core/src/system/transaction/txn_access.cpp +++ b/src/gausskernel/storage/mot/core/src/system/transaction/txn_access.cpp @@ -24,7 +24,7 @@ #include -#include "../storage/table.h" +#include "table.h" #include "row.h" #include "txn.h" #include "txn_access.h" diff --git a/src/gausskernel/storage/mot/fdw_adapter/src/Makefile b/src/gausskernel/storage/mot/fdw_adapter/src/Makefile index bb78bf0b9..4d4922291 100644 --- a/src/gausskernel/storage/mot/fdw_adapter/src/Makefile +++ b/src/gausskernel/storage/mot/fdw_adapter/src/Makefile @@ -38,11 +38,11 @@ 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 diff --git a/src/gausskernel/storage/mot/fdw_adapter/src/gaussdb_config_loader.h b/src/gausskernel/storage/mot/fdw_adapter/src/gaussdb_config_loader.h index 333097ec1..afbc2d9bf 100644 --- a/src/gausskernel/storage/mot/fdw_adapter/src/gaussdb_config_loader.h +++ b/src/gausskernel/storage/mot/fdw_adapter/src/gaussdb_config_loader.h @@ -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()); } diff --git a/src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw.cpp b/src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw.cpp index 2b63546d5..205250d5e 100644 --- a/src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw.cpp +++ b/src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw.cpp @@ -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,30 +188,6 @@ static int MOTGetFdwType() return MOT_ORC; } -static 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); - } - } - } -} - -static 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; -} - void MOTRecover() { if (!MOTAdaptor::m_initialized) { @@ -1043,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); @@ -1091,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); @@ -1418,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); @@ -1445,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); @@ -1478,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; } @@ -1504,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); @@ -1532,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; } @@ -1543,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; } @@ -1561,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); @@ -1700,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 { @@ -1911,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); } } @@ -1993,139 +1963,6 @@ static void InitMOTHandler() } } -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 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(); diff --git a/src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw_error.cpp b/src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw_error.cpp new file mode 100644 index 000000000..871022a24 --- /dev/null +++ b/src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw_error.cpp @@ -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; + } +} diff --git a/src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw_error.h b/src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw_error.h new file mode 100644 index 000000000..f3e5082f6 --- /dev/null +++ b/src/gausskernel/storage/mot/fdw_adapter/src/mot_fdw_error.h @@ -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 */ diff --git a/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.cpp b/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.cpp index 337b0a58c..08950b5ee 100644 --- a/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.cpp +++ b/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.cpp @@ -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); @@ -2331,3 +2110,112 @@ void MOTAdaptor::DatumToMOTKey( 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); +} diff --git a/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.h b/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.h index 031ea52b9..0ca74955a 100644 --- a/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.h +++ b/src/gausskernel/storage/mot/fdw_adapter/src/mot_internal.h @@ -22,18 +22,20 @@ * ------------------------------------------------------------------------- */ -#ifndef MOT_INT_H -#define MOT_INT_H +#ifndef MOT_INTERNAL_H +#define MOT_INTERNAL_H #include #include #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,17 +94,6 @@ 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; @@ -332,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; @@ -340,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 diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_exec.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_exec.cpp index f5d236866..626763bbd 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_exec.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_exec.cpp @@ -55,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 @@ -195,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); } } @@ -369,7 +367,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 @@ -384,7 +382,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 @@ -395,7 +393,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,...) } } diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.cpp index b2e553ce1..16caef7cd 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.cpp @@ -22,8 +22,13 @@ * ------------------------------------------------------------------------- */ -#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" @@ -35,6 +40,15 @@ 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) @@ -50,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"); @@ -90,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) { @@ -104,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; @@ -176,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; @@ -294,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); @@ -370,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"); @@ -388,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"); @@ -426,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; @@ -451,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; @@ -475,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; @@ -491,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; @@ -516,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); @@ -524,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); @@ -532,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); @@ -562,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; @@ -610,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; @@ -683,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; @@ -721,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); @@ -752,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); @@ -762,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)) { @@ -771,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) { @@ -809,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; @@ -835,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; @@ -868,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; @@ -914,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; @@ -1069,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 @@ -1704,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 @@ -1751,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; @@ -1807,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; @@ -1850,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; @@ -1918,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; @@ -1982,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; @@ -2005,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; @@ -2038,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; diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.h b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.h index f692e0fa9..b07033601 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.h +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm_blocks.h @@ -37,24 +37,9 @@ 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); @@ -71,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); @@ -82,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); @@ -164,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); @@ -201,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); diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_plan.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_plan.cpp index 3b23ed92c..88aec441e 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_plan.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_plan.cpp @@ -22,10 +22,10 @@ * ------------------------------------------------------------------------- */ -#include - -// 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 + namespace JitExec { DECLARE_LOGGER(JitPlan, JitExec) diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_plan_expr.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_plan_expr.cpp index 018aaf7bd..fb5cc93d1 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_plan_expr.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_plan_expr.cpp @@ -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" diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_plan_expr.h b/src/gausskernel/storage/mot/jit_exec/src/jit_plan_expr.h index 791ed7cff..de93cf0d1 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_plan_expr.h +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_plan_expr.h @@ -31,6 +31,7 @@ #include "storage/mot/jit_def.h" #include "jit_common.h" #include "utilities.h" + #include namespace JitExec { diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm.cpp index cb20b6451..2e2dfc229 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm.cpp @@ -28,6 +28,7 @@ #include "mot_engine.h" #include "utilities.h" #include "mot_error.h" + #include DECLARE_LOGGER(TVM, JitExec) diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_blocks.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_blocks.cpp index d17726b37..255e428c1 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_blocks.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_blocks.cpp @@ -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; diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_blocks.h b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_blocks.h index d517e4601..45c455528 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_blocks.h +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_blocks.h @@ -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); diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_funcs.h b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_funcs.h index 2374df5de..c1fb55f49 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_funcs.h +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_funcs.h @@ -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 { diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_query.h b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_query.h index 4d43c70f0..b07d550cc 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_query.h +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_query.h @@ -26,42 +26,11 @@ #define JIT_TVM_QUERY_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. + * ATTENTION: Be sure to include libintl.h before anything else to avoid problem with gettext. */ #include "libintl.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" #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 -#include -#include namespace JitExec { /** @struct Holds instructions that evaluate in runtime to begin and end iterators of a cursor. */ diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_query_codegen.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_query_codegen.cpp index a765b6154..d90ffad40 100755 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_query_codegen.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_tvm_query_codegen.cpp @@ -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; From 26237dd1c59a0bf1285d29b391b8d934713c8b38 Mon Sep 17 00:00:00 2001 From: Vinoth Veeraraghavan Date: Thu, 10 Dec 2020 19:51:15 +0800 Subject: [PATCH 4/4] MOT fixes and cleanup --- src/bin/pg_dump/pg_dump.cpp | 26 +++++++++++---- .../process/threadpool/knl_instance.cpp | 6 ++++ .../process/threadpool/knl_thread.cpp | 1 - .../occ_transaction_manager.cpp | 32 +++++++++++++------ .../infra/config/cmdline_config_loader.cpp | 16 ++++++---- .../src/infra/config/config_file_parser.cpp | 11 +++---- .../src/infra/config/config_file_parser.h | 7 ++-- .../infra/config/props_config_file_loader.cpp | 16 ++++++---- .../mot/core/src/memory/mm_raw_chunk_pool.cpp | 1 + .../src/system/recovery/recovery_manager.cpp | 14 ++++++-- .../src/system/recovery/recovery_manager.h | 5 --- .../src/system/transaction/txn_access.cpp | 6 +--- .../storage/mot/jit_exec/src/jit_exec.cpp | 7 ++-- .../storage/mot/jit_exec/src/jit_llvm.cpp | 12 ++----- .../storage/mot/jit_exec/src/jit_llvm.h | 2 +- src/include/knl/knl_instance.h | 7 +++- src/include/knl/knl_thread.h | 1 - src/include/storage/mot/jit_def.h | 12 +++++++ src/include/storage/mot/jit_exec.h | 3 -- 19 files changed, 115 insertions(+), 70 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.cpp b/src/bin/pg_dump/pg_dump.cpp index fc126576b..946818ee0 100644 --- a/src/bin/pg_dump/pg_dump.cpp +++ b/src/bin/pg_dump/pg_dump.cpp @@ -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; diff --git a/src/gausskernel/process/threadpool/knl_instance.cpp b/src/gausskernel/process/threadpool/knl_instance.cpp index bc076d7dd..01283f2ec 100755 --- a/src/gausskernel/process/threadpool/knl_instance.cpp +++ b/src/gausskernel/process/threadpool/knl_instance.cpp @@ -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); diff --git a/src/gausskernel/process/threadpool/knl_thread.cpp b/src/gausskernel/process/threadpool/knl_thread.cpp index b9f92c310..74628e9dc 100755 --- a/src/gausskernel/process/threadpool/knl_thread.cpp +++ b/src/gausskernel/process/threadpool/knl_thread.cpp @@ -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); diff --git a/src/gausskernel/storage/mot/core/src/concurrency_control/occ_transaction_manager.cpp b/src/gausskernel/storage/mot/core/src/concurrency_control/occ_transaction_manager.cpp index 485632e7a..465a9d90b 100644 --- a/src/gausskernel/storage/mot/core/src/concurrency_control/occ_transaction_manager.cpp +++ b/src/gausskernel/storage/mot/core/src/concurrency_control/occ_transaction_manager.cpp @@ -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; diff --git a/src/gausskernel/storage/mot/core/src/infra/config/cmdline_config_loader.cpp b/src/gausskernel/storage/mot/core/src/infra/config/cmdline_config_loader.cpp index 6ba1b4187..57fcf8027 100644 --- a/src/gausskernel/storage/mot/core/src/infra/config/cmdline_config_loader.cpp +++ b/src/gausskernel/storage/mot/core/src/infra/config/cmdline_config_loader.cpp @@ -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()); } diff --git a/src/gausskernel/storage/mot/core/src/infra/config/config_file_parser.cpp b/src/gausskernel/storage/mot/core/src/infra/config/config_file_parser.cpp index d0ccfbf38..e2628ffa2 100644 --- a/src/gausskernel/storage/mot/core/src/infra/config/config_file_parser.cpp +++ b/src/gausskernel/storage/mot/core/src/infra/config/config_file_parser.cpp @@ -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 { diff --git a/src/gausskernel/storage/mot/core/src/infra/config/config_file_parser.h b/src/gausskernel/storage/mot/core/src/infra/config/config_file_parser.h index 27c4521ea..e6739c096 100644 --- a/src/gausskernel/storage/mot/core/src/infra/config/config_file_parser.h +++ b/src/gausskernel/storage/mot/core/src/infra/config/config_file_parser.h @@ -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. diff --git a/src/gausskernel/storage/mot/core/src/infra/config/props_config_file_loader.cpp b/src/gausskernel/storage/mot/core/src/infra/config/props_config_file_loader.cpp index 6a3511799..c19d9c780 100644 --- a/src/gausskernel/storage/mot/core/src/infra/config/props_config_file_loader.cpp +++ b/src/gausskernel/storage/mot/core/src/infra/config/props_config_file_loader.cpp @@ -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()); } diff --git a/src/gausskernel/storage/mot/core/src/memory/mm_raw_chunk_pool.cpp b/src/gausskernel/storage/mot/core/src/memory/mm_raw_chunk_pool.cpp index 4632b4622..b7664f9ad 100644 --- a/src/gausskernel/storage/mot/core/src/memory/mm_raw_chunk_pool.cpp +++ b/src/gausskernel/storage/mot/core/src/memory/mm_raw_chunk_pool.cpp @@ -940,6 +940,7 @@ static inline uint32_t PushSuperChunk(MemRawChunkPool* chunkPool, MemRawChunkHea chunkPool->m_poolName, chunksPushed, count); + FreeChunk(chunkPool, chunk); break; } } diff --git a/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp b/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp index 7b688fee5..77499a89d 100644 --- a/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp +++ b/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.cpp @@ -71,14 +71,24 @@ bool RecoveryManager::RecoverDbStart() MOT_LOG_INFO("Starting MOT recovery"); if (m_recoverFromCkptDone) { - SetLsn(m_lastReplayLsn); + /* + * 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; } diff --git a/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.h b/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.h index 35fd4aaec..d49b6a554 100644 --- a/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.h +++ b/src/gausskernel/storage/mot/core/src/system/recovery/recovery_manager.h @@ -341,11 +341,6 @@ private: */ void ApplySurrogate(); - void SetLsn(uint64_t lsn) - { - m_lsn = lsn; - } - bool m_initialized; bool m_recoverFromCkptDone; diff --git a/src/gausskernel/storage/mot/core/src/system/transaction/txn_access.cpp b/src/gausskernel/storage/mot/core/src/system/transaction/txn_access.cpp index 34d71ab82..d63ac8fdd 100644 --- a/src/gausskernel/storage/mot/core/src/system/transaction/txn_access.cpp +++ b/src/gausskernel/storage/mot/core/src/system/transaction/txn_access.cpp @@ -536,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; diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_exec.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_exec.cpp index 626763bbd..77b9f5c9c 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_exec.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_exec.cpp @@ -203,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); } @@ -497,16 +498,18 @@ extern bool JitInitialize() if (JitCanInitThreadCodeGen()) { if (IsMotPseudoCodegenForced()) { 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 { 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"); - MOT::GetGlobalConfiguration().m_forcePseudoCodegen = true; } + g_instance.mot_cxt.jitExecMode = JIT_EXEC_MODE_TVM; } enum InitState { JIT_INIT, JIT_CTX_POOL_INIT, JIT_SRC_POOL_INIT, JIT_INIT_DONE } initState = JIT_INIT; diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.cpp b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.cpp index f00317b05..46ae56209 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.cpp +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.cpp @@ -44,7 +44,7 @@ DECLARE_LOGGER(JitLlvm, JitExec); using namespace dorado; /** @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(); @@ -64,7 +64,7 @@ extern bool JitCanInitThreadCodeGen() if (IS_PGXC_DATANODE && IsMotCodegenEnabled()) { canInit = GlobalCodeGenEnvironmentSuccess; if (!canInit) { - MOT_LOG_WARN("SSE4.2 is not supported, native LLVM will not be used."); + MOT_LOG_WARN("LLVM environment is not initialized, native LLVM will not be used."); } } return canInit; @@ -74,13 +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; - } - } + 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(); diff --git a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.h b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.h index 4ae274f00..eba93738c 100644 --- a/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.h +++ b/src/gausskernel/storage/mot/jit_exec/src/jit_llvm.h @@ -66,7 +66,7 @@ typedef int (*JitFunc)(MOT::Table* table, MOT::Index* index, MOT::Key* key, MOT: void PrintNativeLlvmStartupInfo(); /** @brief Checks whether the current platforms natively supports LLVM. */ -extern bool JitCanInitThreadCodeGen(); +bool JitCanInitThreadCodeGen(); /** @brief Allocates a GsCodeGen object. */ dorado::GsCodeGen* SetupCodegenEnv(); diff --git a/src/include/knl/knl_instance.h b/src/include/knl/knl_instance.h index e5760e537..8729fccf4 100644 --- a/src/include/knl/knl_instance.h +++ b/src/include/knl/knl_instance.h @@ -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; @@ -541,6 +541,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; @@ -613,6 +617,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; diff --git a/src/include/knl/knl_thread.h b/src/include/knl/knl_thread.h index 8851b11c8..4373bf17c 100644 --- a/src/include/knl/knl_thread.h +++ b/src/include/knl/knl_thread.h @@ -2731,7 +2731,6 @@ typedef struct knl_t_mot_context { // misc uint8_t log_level; - bool init_codegen_once; uint16_t currentThreadId; int currentNumaNodeId; diff --git a/src/include/storage/mot/jit_def.h b/src/include/storage/mot/jit_def.h index 8da35f02a..603e27321 100644 --- a/src/include/storage/mot/jit_def.h +++ b/src/include/storage/mot/jit_def.h @@ -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. */ diff --git a/src/include/storage/mot/jit_exec.h b/src/include/storage/mot/jit_exec.h index 7820f352d..2f354bcf2 100644 --- a/src/include/storage/mot/jit_exec.h +++ b/src/include/storage/mot/jit_exec.h @@ -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.