forked from huawei/openGauss-server
1. Added envelopeType in Column and CommonColumnMetadata (required for JIT)
2. Minor MOT JIT fixes
This commit is contained in:
parent
9a762552be
commit
8bb58f27da
|
|
@ -251,6 +251,9 @@ static int errdetail_recovery_conflict(void);
|
|||
static bool IsTransactionExitStmt(Node* parsetree);
|
||||
static bool IsTransactionExitStmtList(List* parseTrees);
|
||||
static bool IsTransactionStmtList(List* parseTrees);
|
||||
#ifdef ENABLE_MOT
|
||||
static bool IsTransactionPrepareStmt(const Node* parsetree);
|
||||
#endif
|
||||
static void drop_unnamed_stmt(void);
|
||||
static void SigHupHandler(SIGNAL_ARGS);
|
||||
static void ForceModifyInitialPwd(const char* query_string, List* parsetree_list);
|
||||
|
|
@ -2420,6 +2423,12 @@ static void exec_simple_query(const char* query_string, MessageType messageType,
|
|||
errmsg("SubTransaction is not supported for memory table")));
|
||||
}
|
||||
|
||||
if (IsTransactionPrepareStmt(parsetree) && (IsMOTEngineUsed() || IsMixedEngineUsed())) {
|
||||
/* Explicit prepare transaction is not supported for memory table */
|
||||
ereport(ERROR, (errcode(ERRCODE_FDW_OPERATION_NOT_SUPPORTED), errmodule(MOD_MOT),
|
||||
errmsg("Explicit prepare transaction is not supported for memory table")));
|
||||
}
|
||||
|
||||
/* check for MOT update of indexed field. Can check only the querytree head, no need for drill down */
|
||||
if (!IsTransactionExitStmt(parsetree) &&
|
||||
(querytree_list != NULL && CheckMotIndexedColumnUpdate((Query*)linitial(querytree_list)))) {
|
||||
|
|
@ -4100,14 +4109,22 @@ static void exec_bind_message(StringInfo input_message)
|
|||
#ifdef ENABLE_MOT
|
||||
/* set transaction storage engine and check for cross transaction violation */
|
||||
SetCurrentTransactionStorageEngine(psrc->storageEngineType);
|
||||
if (!IsTransactionExitStmt(psrc->raw_parse_tree) && IsMixedEngineUsed())
|
||||
if (!IsTransactionExitStmt(psrc->raw_parse_tree) && IsMixedEngineUsed()) {
|
||||
ereport(ERROR, (errcode(ERRCODE_FDW_CROSS_STORAGE_ENGINE_TRANSACTION_NOT_SUPPORTED), errmodule(MOD_MOT),
|
||||
errmsg("Cross storage engine transaction is not supported")));
|
||||
errmsg("Cross storage engine transaction is not supported")));
|
||||
}
|
||||
|
||||
/* block MOT engine queries in sub-transactions */
|
||||
if (!IsTransactionExitStmt(psrc->raw_parse_tree) && IsMOTEngineUsedInParentTransaction() && IsMOTEngineUsed())
|
||||
if (!IsTransactionExitStmt(psrc->raw_parse_tree) && IsMOTEngineUsedInParentTransaction() && IsMOTEngineUsed()) {
|
||||
ereport(ERROR, (errcode(ERRCODE_FDW_OPERATION_NOT_SUPPORTED), errmodule(MOD_MOT),
|
||||
errmsg("SubTransaction is not supported for memory table")));
|
||||
errmsg("SubTransaction is not supported for memory table")));
|
||||
}
|
||||
|
||||
if (IsTransactionPrepareStmt(psrc->raw_parse_tree) && (IsMOTEngineUsed() || IsMixedEngineUsed())) {
|
||||
/* Explicit prepare transaction is not supported for memory table */
|
||||
ereport(ERROR, (errcode(ERRCODE_FDW_OPERATION_NOT_SUPPORTED), errmodule(MOD_MOT),
|
||||
errmsg("Explicit prepare transaction is not supported for memory table")));
|
||||
}
|
||||
|
||||
/*
|
||||
* MOT JIT Execution:
|
||||
|
|
@ -5360,6 +5377,19 @@ static bool IsTransactionStmtList(List* parseTrees)
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MOT
|
||||
static bool IsTransactionPrepareStmt(const Node* parsetree)
|
||||
{
|
||||
if (parsetree && IsA(parsetree, TransactionStmt)) {
|
||||
TransactionStmt* stmt = (TransactionStmt*)parsetree;
|
||||
if (stmt->kind == TRANS_STMT_PREPARE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Release any existing unnamed prepared statement */
|
||||
static void drop_unnamed_stmt(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7807,7 +7807,7 @@ bool IsPGEngineUsed()
|
|||
}
|
||||
|
||||
/*
|
||||
* Check if we are using PG storage engine in parent transaction.
|
||||
* Check if we are using MOT storage engine in parent transaction.
|
||||
*/
|
||||
bool IsMOTEngineUsedInParentTransaction()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -384,7 +384,7 @@ bool ConfigManager::ReloadConfig(bool ignoreErrors /* = true */)
|
|||
|
||||
// print loaded configuration
|
||||
LogLevel logLevel = LogLevel::LL_TRACE;
|
||||
GetLayeredConfigTree()->GetUserConfigValue("Log/cfg_startup_log_level", logLevel, false);
|
||||
GetLayeredConfigTree()->GetUserConfigValue("Log.cfg_startup_log_level", logLevel, false);
|
||||
if (MOT_CHECK_LOG_LEVEL(logLevel)) {
|
||||
GetLayeredConfigTree()->Print(logLevel);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ Column::Column()
|
|||
securec_check(erc, "\0", "\0");
|
||||
erc = memset_s(&(this->m_type), sizeof(this->m_type), 0, sizeof(this->m_type));
|
||||
securec_check(erc, "\0", "\0");
|
||||
this->m_envelopeType = 0;
|
||||
}
|
||||
|
||||
Column::~Column()
|
||||
|
|
|
|||
|
|
@ -162,6 +162,9 @@ public:
|
|||
|
||||
/** @var Column does not allow null values. */
|
||||
bool m_isNotNull;
|
||||
|
||||
/** @var Envelope column type. */
|
||||
unsigned int m_envelopeType;
|
||||
};
|
||||
|
||||
// derived column classes
|
||||
|
|
|
|||
|
|
@ -652,7 +652,8 @@ bool Table::CreateMultipleRows(size_t numRows, Row* rows[])
|
|||
return res;
|
||||
}
|
||||
|
||||
RC Table::AddColumn(const char* colName, uint64_t size, MOT_CATALOG_FIELD_TYPES type, bool isNotNull)
|
||||
RC Table::AddColumn(
|
||||
const char* colName, uint64_t size, MOT_CATALOG_FIELD_TYPES type, bool isNotNull, unsigned int envelopeType)
|
||||
{
|
||||
// validate input parameters
|
||||
if (!colName || type >= MOT_CATALOG_FIELD_TYPES::MOT_TYPE_UNKNOWN)
|
||||
|
|
@ -695,6 +696,7 @@ RC Table::AddColumn(const char* colName, uint64_t size, MOT_CATALOG_FIELD_TYPES
|
|||
m_columns[m_fieldCnt]->m_id = m_fieldCnt;
|
||||
m_columns[m_fieldCnt]->m_offset = m_tupleSize;
|
||||
m_columns[m_fieldCnt]->m_isNotNull = isNotNull;
|
||||
m_columns[m_fieldCnt]->m_envelopeType = envelopeType;
|
||||
m_columns[m_fieldCnt]->SetKeySize();
|
||||
|
||||
m_tupleSize += size;
|
||||
|
|
@ -817,7 +819,8 @@ size_t Table::SerializeItemSize(Column* column)
|
|||
size_t ret = SerializableARR<char, Column::MAX_COLUMN_NAME_LEN>::SerializeSize(column->m_name) +
|
||||
SerializablePOD<uint64_t>::SerializeSize(column->m_size) +
|
||||
SerializablePOD<MOT_CATALOG_FIELD_TYPES>::SerializeSize(column->m_type) +
|
||||
SerializablePOD<bool>::SerializeSize(column->m_isNotNull);
|
||||
SerializablePOD<bool>::SerializeSize(column->m_isNotNull) +
|
||||
SerializablePOD<unsigned int>::SerializeSize(column->m_envelopeType); // required for MOT JIT
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -830,6 +833,7 @@ char* Table::SerializeItem(char* dataOut, Column* column)
|
|||
dataOut = SerializablePOD<uint64_t>::Serialize(dataOut, column->m_size);
|
||||
dataOut = SerializablePOD<MOT_CATALOG_FIELD_TYPES>::Serialize(dataOut, column->m_type);
|
||||
dataOut = SerializablePOD<bool>::Serialize(dataOut, column->m_isNotNull);
|
||||
dataOut = SerializablePOD<unsigned int>::Serialize(dataOut, column->m_envelopeType); // required for MOT JIT
|
||||
return dataOut;
|
||||
}
|
||||
|
||||
|
|
@ -839,6 +843,7 @@ char* Table::DeserializeMeta(char* dataIn, CommonColumnMeta& meta)
|
|||
dataIn = SerializablePOD<uint64_t>::Deserialize(dataIn, meta.m_size);
|
||||
dataIn = SerializablePOD<MOT_CATALOG_FIELD_TYPES>::Deserialize(dataIn, meta.m_type);
|
||||
dataIn = SerializablePOD<bool>::Deserialize(dataIn, meta.m_isNotNull);
|
||||
dataIn = SerializablePOD<unsigned int>::Deserialize(dataIn, meta.m_envelopeType); // required for MOT JIT
|
||||
return dataIn;
|
||||
}
|
||||
|
||||
|
|
@ -1110,7 +1115,7 @@ void Table::Deserialize(const char* in)
|
|||
CommonColumnMeta col;
|
||||
for (uint32_t i = 0; i < saveFieldCount; i++) {
|
||||
dataIn = DeserializeMeta(dataIn, col);
|
||||
if (AddColumn(col.m_name, col.m_size, col.m_type, col.m_isNotNull) != RC_OK) {
|
||||
if (AddColumn(col.m_name, col.m_size, col.m_type, col.m_isNotNull, col.m_envelopeType) != RC_OK) {
|
||||
MOT_LOG_ERROR("Table::deserialize - failed to add column %u", i);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -634,7 +634,8 @@ public:
|
|||
* @param type The type name of the column.
|
||||
* @return RC error code.
|
||||
*/
|
||||
RC AddColumn(const char* col_name, uint64_t size, MOT_CATALOG_FIELD_TYPES type, bool isNotNull = false);
|
||||
RC AddColumn(const char* col_name, uint64_t size, MOT_CATALOG_FIELD_TYPES type, bool isNotNull = false,
|
||||
unsigned int envelopeType = 0);
|
||||
|
||||
/**
|
||||
* @brief Modifies the size of a column. This may be required for supporting ALTER TABLE.
|
||||
|
|
@ -952,6 +953,8 @@ public:
|
|||
MOT_CATALOG_FIELD_TYPES m_type;
|
||||
|
||||
bool m_isNotNull;
|
||||
|
||||
unsigned int m_envelopeType; // required for MOT JIT
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -935,10 +935,10 @@ static void VarLenFieldType(
|
|||
}
|
||||
}
|
||||
|
||||
static MOT::RC TableFieldType(const ColumnDef* colDef, MOT::MOT_CATALOG_FIELD_TYPES& type, int16* typeLen, bool& isBlob)
|
||||
static MOT::RC TableFieldType(
|
||||
const ColumnDef* colDef, MOT::MOT_CATALOG_FIELD_TYPES& type, int16* typeLen, Oid& typoid, bool& isBlob)
|
||||
{
|
||||
MOT::RC res = MOT::RC_OK;
|
||||
Oid typoid;
|
||||
Type tup;
|
||||
Form_pg_type typeDesc;
|
||||
int32_t colLen;
|
||||
|
|
@ -1210,7 +1210,8 @@ void MOTAdaptor::AddTableColumns(MOT::Table* table, List *tableElts, bool& hasBl
|
|||
break;
|
||||
}
|
||||
|
||||
MOT::RC res = TableFieldType(colDef, colType, &typeLen, isBlob);
|
||||
Oid typoid = InvalidOid;
|
||||
MOT::RC res = TableFieldType(colDef, colType, &typeLen, typoid, isBlob);
|
||||
if (res != MOT::RC_OK) {
|
||||
delete table;
|
||||
table = nullptr;
|
||||
|
|
@ -1264,7 +1265,8 @@ void MOTAdaptor::AddTableColumns(MOT::Table* table, List *tableElts, bool& hasBl
|
|||
}
|
||||
}
|
||||
}
|
||||
res = table->AddColumn(colDef->colname, typeLen, colType, colDef->is_not_null);
|
||||
|
||||
res = table->AddColumn(colDef->colname, typeLen, colType, colDef->is_not_null, typoid);
|
||||
if (res != MOT::RC_OK) {
|
||||
delete table;
|
||||
table = nullptr;
|
||||
|
|
@ -1724,7 +1726,7 @@ void MOTAdaptor::CreateKeyBuffer(Relation rel, MOTFdwStateSt* festate, int start
|
|||
}
|
||||
|
||||
DatumToMOTKey(col,
|
||||
expr,
|
||||
expr->resultType,
|
||||
val,
|
||||
desc->attrs[orgCols[i] - 1]->atttypid,
|
||||
buf + offset,
|
||||
|
|
@ -1948,26 +1950,25 @@ 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)
|
||||
MOT::Column* col, Oid datumType, Datum datum, Oid colType, 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;
|
||||
}
|
||||
bool noValue = false;
|
||||
switch (datumType) {
|
||||
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);
|
||||
|
|
@ -1984,13 +1985,13 @@ inline void MOTAdaptor::VarcharToMOTKey(
|
|||
size -= 1;
|
||||
} else {
|
||||
// switch to equal
|
||||
if (type == BPCHAROID) {
|
||||
if (colType == BPCHAROID) {
|
||||
fill = 0x20; // space ' ' == 0x20
|
||||
} else {
|
||||
fill = 0x00;
|
||||
}
|
||||
}
|
||||
} else if (type == BPCHAROID) { // handle padding for blank-padded type
|
||||
} else if (colType == BPCHAROID) { // handle padding for blank-padded type
|
||||
fill = 0x20;
|
||||
}
|
||||
col->PackKey(data, (uintptr_t)src, size, fill);
|
||||
|
|
@ -2000,25 +2001,21 @@ inline void MOTAdaptor::VarcharToMOTKey(
|
|||
}
|
||||
}
|
||||
|
||||
inline void MOTAdaptor::FloatToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, uint8_t* data)
|
||||
inline void MOTAdaptor::FloatToMOTKey(MOT::Column* col, Oid datumType, 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);
|
||||
}
|
||||
if (datumType == 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);
|
||||
}
|
||||
}
|
||||
|
||||
inline void MOTAdaptor::NumericToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, uint8_t* data)
|
||||
inline void MOTAdaptor::NumericToMOTKey(MOT::Column* col, Oid datumType, Datum datum, uint8_t* data)
|
||||
{
|
||||
Numeric n = DatumGetNumeric(datum);
|
||||
char buf[DECIMAL_MAX_SIZE];
|
||||
|
|
@ -2027,83 +2024,71 @@ inline void MOTAdaptor::NumericToMOTKey(MOT::Column* col, ExprState* expr, Datum
|
|||
col->PackKey(data, (uintptr_t)d, DECIMAL_SIZE(d));
|
||||
}
|
||||
|
||||
inline void MOTAdaptor::TimestampToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, uint8_t* data)
|
||||
inline void MOTAdaptor::TimestampToMOTKey(MOT::Column* col, Oid datumType, 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);
|
||||
}
|
||||
if (datumType == TIMESTAMPTZOID) {
|
||||
Timestamp result = DatumGetTimestamp(DirectFunctionCall1(timestamptz_timestamp, datum));
|
||||
col->PackKey(data, result, col->m_size);
|
||||
} else if (datumType == DATEOID) {
|
||||
Timestamp result = DatumGetTimestamp(DirectFunctionCall1(date_timestamp, datum));
|
||||
col->PackKey(data, result, 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)
|
||||
inline void MOTAdaptor::TimestampTzToMOTKey(MOT::Column* col, Oid datumType, 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);
|
||||
}
|
||||
if (datumType == TIMESTAMPOID) {
|
||||
TimestampTz result = DatumGetTimestampTz(DirectFunctionCall1(timestamp_timestamptz, datum));
|
||||
col->PackKey(data, result, col->m_size);
|
||||
} else if (datumType == DATEOID) {
|
||||
TimestampTz result = DatumGetTimestampTz(DirectFunctionCall1(date_timestamptz, datum));
|
||||
col->PackKey(data, result, 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)
|
||||
inline void MOTAdaptor::DateToMOTKey(MOT::Column* col, Oid datumType, 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);
|
||||
}
|
||||
if (datumType == TIMESTAMPOID) {
|
||||
DateADT result = DatumGetDateADT(DirectFunctionCall1(timestamp_date, datum));
|
||||
col->PackKey(data, result, col->m_size);
|
||||
} else if (datumType == TIMESTAMPTZOID) {
|
||||
DateADT result = DatumGetDateADT(DirectFunctionCall1(timestamptz_date, datum));
|
||||
col->PackKey(data, result, 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)
|
||||
MOT::Column* col, Oid datumType, Datum datum, Oid colType, uint8_t* data, size_t len, KEY_OPER oper, uint8_t fill)
|
||||
{
|
||||
EnsureSafeThreadAccessInline();
|
||||
switch (type) {
|
||||
switch (colType) {
|
||||
case BYTEAOID:
|
||||
case TEXTOID:
|
||||
case VARCHAROID:
|
||||
case CLOBOID:
|
||||
case BPCHAROID:
|
||||
VarcharToMOTKey(col, expr, datum, type, data, len, oper, fill);
|
||||
VarcharToMOTKey(col, datumType, datum, colType, data, len, oper, fill);
|
||||
break;
|
||||
case FLOAT4OID:
|
||||
FloatToMOTKey(col, expr, datum, data);
|
||||
FloatToMOTKey(col, datumType, datum, data);
|
||||
break;
|
||||
case NUMERICOID:
|
||||
NumericToMOTKey(col, expr, datum, data);
|
||||
NumericToMOTKey(col, datumType, datum, data);
|
||||
break;
|
||||
case TIMESTAMPOID:
|
||||
TimestampToMOTKey(col, expr, datum, data);
|
||||
TimestampToMOTKey(col, datumType, datum, data);
|
||||
break;
|
||||
case TIMESTAMPTZOID:
|
||||
TimestampTzToMOTKey(col, expr, datum, data);
|
||||
TimestampTzToMOTKey(col, datumType, datum, data);
|
||||
break;
|
||||
case DATEOID:
|
||||
DateToMOTKey(col, expr, datum, data);
|
||||
DateToMOTKey(col, datumType, datum, data);
|
||||
break;
|
||||
default:
|
||||
col->PackKey(data, datum, col->m_size);
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ public:
|
|||
|
||||
// data conversion
|
||||
static void DatumToMOT(MOT::Column* col, Datum datum, Oid type, uint8_t* data);
|
||||
static void DatumToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, Oid type, uint8_t* data, size_t len,
|
||||
static void DatumToMOTKey(MOT::Column* col, Oid datumType, Datum datum, Oid colType, uint8_t* data, size_t len,
|
||||
KEY_OPER oper, uint8_t fill = 0x00);
|
||||
static void MOTToDatum(MOT::Table* table, const Form_pg_attribute attr, uint8_t* data, Datum* value, bool* is_null);
|
||||
|
||||
|
|
@ -315,13 +315,13 @@ private:
|
|||
|
||||
static void ValidateCreateIndex(IndexStmt* index, MOT::Table* table, MOT::TxnManager* txn);
|
||||
|
||||
static void VarcharToMOTKey(MOT::Column* col, ExprState* expr, Datum datum, Oid type, uint8_t* data, size_t len,
|
||||
static void VarcharToMOTKey(MOT::Column* col, Oid datumType, Datum datum, Oid colType, 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);
|
||||
static void FloatToMOTKey(MOT::Column* col, Oid datumType, Datum datum, uint8_t* data);
|
||||
static void NumericToMOTKey(MOT::Column* col, Oid datumType, Datum datum, uint8_t* data);
|
||||
static void TimestampToMOTKey(MOT::Column* col, Oid datumType, Datum datum, uint8_t* data);
|
||||
static void TimestampTzToMOTKey(MOT::Column* col, Oid datumType, Datum datum, uint8_t* data);
|
||||
static void DateToMOTKey(MOT::Column* col, Oid datumType, Datum datum, uint8_t* data);
|
||||
};
|
||||
|
||||
inline MOT::TxnManager* GetSafeTxn(const char* callerSrc, ::TransactionId txn_id = 0)
|
||||
|
|
|
|||
|
|
@ -612,6 +612,17 @@ static void CleanupJitContextPrimary(JitContext* jitContext)
|
|||
jitContext->m_index->DestroyKey(jitContext->m_endIteratorKey);
|
||||
jitContext->m_endIteratorKey = nullptr;
|
||||
}
|
||||
|
||||
if (jitContext->m_beginIterator != nullptr) {
|
||||
destroyIterator(jitContext->m_beginIterator);
|
||||
jitContext->m_beginIterator = nullptr;
|
||||
}
|
||||
|
||||
if (jitContext->m_endIterator != nullptr) {
|
||||
destroyIterator(jitContext->m_endIterator);
|
||||
jitContext->m_endIterator = nullptr;
|
||||
}
|
||||
|
||||
jitContext->m_index = nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -636,6 +647,17 @@ static void CleanupJitContextInner(JitContext* jitContext)
|
|||
jitContext->m_innerIndex->DestroyKey(jitContext->m_innerEndIteratorKey);
|
||||
jitContext->m_innerEndIteratorKey = nullptr;
|
||||
}
|
||||
|
||||
if (jitContext->m_innerBeginIterator != nullptr) {
|
||||
destroyIterator(jitContext->m_innerBeginIterator);
|
||||
jitContext->m_innerBeginIterator = nullptr;
|
||||
}
|
||||
|
||||
if (jitContext->m_innerEndIterator != nullptr) {
|
||||
destroyIterator(jitContext->m_innerEndIterator);
|
||||
jitContext->m_innerEndIterator = nullptr;
|
||||
}
|
||||
|
||||
jitContext->m_innerIndex = nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -449,9 +449,9 @@ void buildDatumKey(
|
|||
securec_check(erc, "\0", "\0");
|
||||
} else {
|
||||
MOTAdaptor::DatumToMOTKey(column,
|
||||
NULL,
|
||||
value,
|
||||
(Oid)value_type,
|
||||
value,
|
||||
column->m_envelopeType,
|
||||
key->GetKeyBuf() + offset,
|
||||
column->m_size,
|
||||
KEY_OPER::READ_KEY_EXACT,
|
||||
|
|
|
|||
|
|
@ -156,7 +156,8 @@ void RangeScanExpressionCollector::EvaluateScanType()
|
|||
|
||||
// first step: sort in-place all collected operators
|
||||
if (_index_op_count > 1) {
|
||||
std::sort(&_index_ops[0], &_index_ops[_index_op_count - 1], IndexOpCmp);
|
||||
MOT_LOG_TRACE("Sorting index ops")
|
||||
std::stable_sort(&_index_ops[0], &_index_ops[_index_op_count], IndexOpCmp);
|
||||
}
|
||||
|
||||
// now verify all but last two are equals operator
|
||||
|
|
@ -227,7 +228,9 @@ bool RangeScanExpressionCollector::DetermineScanType(JitIndexScanType& scanType,
|
|||
void RangeScanExpressionCollector::Cleanup()
|
||||
{
|
||||
for (int i = 0; i < _index_op_count; ++i) {
|
||||
freeExpr(_index_scan->_search_exprs._exprs[i]._expr);
|
||||
if (_index_scan->_search_exprs._exprs[i]._expr != nullptr) {
|
||||
freeExpr(_index_scan->_search_exprs._exprs[i]._expr);
|
||||
}
|
||||
}
|
||||
_index_scan->_search_exprs._count = 0;
|
||||
_index_op_count = 0;
|
||||
|
|
@ -255,23 +258,26 @@ int RangeScanExpressionCollector::RemoveSingleDuplicate()
|
|||
continue;
|
||||
}
|
||||
// now we need to decide which one to remove,
|
||||
// our consideration is to keep equals operators and then join expressions
|
||||
// our consideration is to keep first JOIN expressions and then EQUALS expressions
|
||||
int victim = -1;
|
||||
if ((_index_ops[i]._op_class == JIT_WOC_EQUALS) || (_index_ops[j]._op_class == JIT_WOC_EQUALS)) {
|
||||
if ((_index_ops[i]._op_class != JIT_WOC_EQUALS) || (_index_ops[j]._op_class != JIT_WOC_EQUALS)) {
|
||||
// we keep the equals operator for index scan, and leave the other as a filter
|
||||
MOT_LOG_TRACE("RangeScanExpressionCollector(): Rejecting query due to duplicate index column "
|
||||
"reference, one with EQUALS, one without");
|
||||
MOT_LOG_TRACE("RangeScanExpressionCollector(): Found duplicate index column reference, one with "
|
||||
"EQUALS, one without - non-equals column will be considered as a filter");
|
||||
if (_index_ops[i]._op_class != JIT_WOC_EQUALS) {
|
||||
victim = i;
|
||||
} else {
|
||||
victim = j;
|
||||
}
|
||||
MOT_LOG_TRACE("Selected non-EQUALS victim at index %d", victim);
|
||||
} else if (_index_scan->_search_exprs._exprs[i]._join_expr &&
|
||||
!_index_scan->_search_exprs._exprs[j]._join_expr) {
|
||||
victim = j;
|
||||
MOT_LOG_TRACE("Selected non-JOIN victim at index %d", victim);
|
||||
} else if (!_index_scan->_search_exprs._exprs[i]._join_expr &&
|
||||
_index_scan->_search_exprs._exprs[j]._join_expr) {
|
||||
victim = i;
|
||||
MOT_LOG_TRACE("Selected non-JOIN victim at index %d", victim);
|
||||
} else if (_index_scan->_search_exprs._exprs[i]._join_expr &&
|
||||
_index_scan->_search_exprs._exprs[j]._join_expr) {
|
||||
// both are join expressions, this is unacceptable, so we abort
|
||||
|
|
@ -284,12 +290,18 @@ int RangeScanExpressionCollector::RemoveSingleDuplicate()
|
|||
// both items are not join expressions, both refer to index columns, so we arbitrarily drop one
|
||||
// of them
|
||||
victim = j;
|
||||
MOT_LOG_TRACE("Selected arbitrary duplicate EQUALS victim at index %d", victim);
|
||||
}
|
||||
// switch victim with last item
|
||||
MOT_LOG_TRACE(
|
||||
"Removing victim index op at index %d and putting there index %d", victim, _index_op_count - 1);
|
||||
if (_index_scan->_search_exprs._exprs[victim]._expr != nullptr) {
|
||||
freeExpr(_index_scan->_search_exprs._exprs[victim]._expr);
|
||||
}
|
||||
MOT_LOG_TRACE("Removing victim index op at index %d", victim);
|
||||
_index_scan->_search_exprs._exprs[victim] = _index_scan->_search_exprs._exprs[_index_op_count - 1];
|
||||
_index_scan->_search_exprs._exprs[_index_op_count - 1]._expr = nullptr;
|
||||
_index_ops[victim] = _index_ops[_index_op_count - 1];
|
||||
--_index_op_count;
|
||||
--_index_scan->_search_exprs._count;
|
||||
return 1;
|
||||
|
|
@ -317,8 +329,15 @@ bool RangeScanExpressionCollector::IndexOpCmp(const IndexOpClass& lhs, const Ind
|
|||
int result = IntCmp(lhs._index_column_id, rhs._index_column_id);
|
||||
if (result == 0) {
|
||||
// make sure equals appears before other operators in case column id is equal
|
||||
result = IntCmp(lhs._op_class, rhs._op_class);
|
||||
if ((lhs._op_class == JIT_WOC_EQUALS) && (rhs._op_class != JIT_WOC_EQUALS)) {
|
||||
result = -1;
|
||||
} else if ((lhs._op_class != JIT_WOC_EQUALS) && (rhs._op_class == JIT_WOC_EQUALS)) {
|
||||
result = 1;
|
||||
}
|
||||
// otherwise we keep order intact to avoid misinterpreting open range scan as inverted
|
||||
}
|
||||
|
||||
// we return true when strict ascending order is preserved
|
||||
return result < 0;
|
||||
}
|
||||
|
||||
|
|
@ -336,6 +355,9 @@ bool RangeScanExpressionCollector::ScanHasHoles(JitIndexScanType scan_type) cons
|
|||
if (_index_ops[0]._index_column_id != 0) {
|
||||
MOT_LOG_TRACE(
|
||||
"RangeScanExpressionCollector(): Disqualifying query - Index scan does not begin with index column 0");
|
||||
for (int i = 0; i < _index_op_count; ++i) {
|
||||
MOT_LOG_TRACE("Index column id %d: %d", i, _index_ops[i]._index_column_id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue