1. Incorrect behavior in update/delete queries with repeating access to same records

2.     Change MOT key operator for expr with l-values
This commit is contained in:
Vinoth Veeraraghavan
2020-10-26 14:51:56 +08:00
parent 194536bf78
commit a2b914b960
4 changed files with 50 additions and 5 deletions

View File

@ -137,6 +137,7 @@ RC TxnManager::DeleteLastRow()
rc = m_accessMgr->UpdateRowState(AccessType::DEL, access);
if (rc != RC_OK)
return rc;
access->m_stmtCount = GetStmtCount();
return rc;
}
@ -145,6 +146,18 @@ RC TxnManager::UpdateLastRowState(AccessType state)
return m_accessMgr->UpdateRowState(state, m_accessMgr->GetLastAccess());
}
bool TxnManager::IsUpdatedInCurrStmt()
{
Access* access = m_accessMgr->GetLastAccess();
if (access == nullptr) {
return false;
}
if (m_internalStmtCount == m_accessMgr->GetLastAccess()->m_stmtCount) {
return true;
}
return false;
}
RC TxnManager::StartTransaction(uint64_t transactionId, int isolationLevel)
{
m_transactionId = transactionId;
@ -781,8 +794,10 @@ RC TxnManager::OverwriteRow(Row* updatedRow, BitmapSet& modifiedColumns)
return RC_ERROR;
Access* access = m_accessMgr->GetLastAccess();
if (access->m_type == AccessType::WR)
if (access->m_type == AccessType::WR) {
access->m_modifiedColumns |= modifiedColumns;
access->m_stmtCount = GetStmtCount();
}
return RC_OK;
}

View File

@ -471,6 +471,8 @@ public:
m_occManager.SetValidationNoWait(b);
}
bool IsUpdatedInCurrStmt();
private:
static constexpr uint32_t SESSION_ID_BITS = 32;

View File

@ -1508,6 +1508,10 @@ static TupleTableSlot* MOTExecForeignUpdate(
return nullptr;
}
// This case handle multiple updates of the same row in one query
if (fdwState->m_currTxn->IsUpdatedInCurrStmt()) {
return nullptr;
}
if ((rc = MOTAdaptor::UpdateRow(fdwState, planSlot, currRow)) == MOT::RC_OK) {
if (resultRelInfo->ri_projectReturning) {
return planSlot;
@ -1552,6 +1556,10 @@ static TupleTableSlot* MOTExecForeignDelete(
}
if (currRow == nullptr) {
// This case handle multiple updates of the same row in one query
if (fdwState->m_currTxn->IsUpdatedInCurrStmt()) {
return nullptr;
}
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);
@ -2233,6 +2241,20 @@ inline bool IsNotEqualOper(OpExpr* op)
}
}
inline void RevertKeyOperation(KEY_OPER& oper)
{
if (oper == KEY_OPER::READ_KEY_BEFORE) {
oper = KEY_OPER::READ_KEY_AFTER;
} else if (oper == KEY_OPER::READ_KEY_OR_PREV) {
oper = KEY_OPER::READ_KEY_OR_NEXT;
} else if (oper == KEY_OPER::READ_KEY_AFTER) {
oper = KEY_OPER::READ_KEY_BEFORE;
} else if (oper == KEY_OPER::READ_KEY_OR_NEXT) {
oper = KEY_OPER::READ_KEY_OR_PREV;
}
return;
}
inline bool GetKeyOperation(OpExpr* op, KEY_OPER& oper)
{
switch (op->opno) {
@ -2411,11 +2433,13 @@ bool IsMOTExpr(RelOptInfo* baserel, MOTFdwStateSt* state, MatchIndexArr* marr, E
} else {
v = (Var*)r;
e = l;
RevertKeyOperation(oper);
}
}
} else if (IsA(r, Var)) {
v = (Var*)r;
e = l;
RevertKeyOperation(oper);
} else {
isOperatorMOTReady = false;
break;

View File

@ -167,8 +167,10 @@ SELECT '' AS one, f.* FROM FLOAT8_TBL f WHERE f.f1 = '1004.3';
SELECT '' AS three, f.* FROM FLOAT8_TBL f WHERE '1004.3' > f.f1 ORDER BY f1;
three | f1
-------+----------------------
| 1.2345678901234e+200
(1 row)
| -34.84
| 0
| 1.2345678901234e-200
(3 rows)
SELECT '' AS three, f.* FROM FLOAT8_TBL f WHERE f.f1 < '1004.3' ORDER BY f1;
three | f1
@ -181,9 +183,11 @@ SELECT '' AS three, f.* FROM FLOAT8_TBL f WHERE f.f1 < '1004.3' ORDER BY f1;
SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE '1004.3' >= f.f1 ORDER BY f1;
four | f1
------+----------------------
| -34.84
| 0
| 1.2345678901234e-200
| 1004.3
| 1.2345678901234e+200
(2 rows)
(4 rows)
SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE f.f1 <= '1004.3' ORDER BY f1;
four | f1