Skip to content

Commit cfcefbc

Browse files
herambh-shahANJU BHARTI
authored andcommitted
Testcase Coverage for OUTPUT clause
We are dealing with a critical crash bug in Babelfish's EPQ (EvalPlanQual) handling during concurrent UPDATE operations with OUTPUT clauses. The crash occurs when two sessions simultaneously modify the same row, where the column is of type "varchar" causing tuple alignment problems during EPQ re-evaluation. This is a memory corruption issue where PostgreSQL's EPQ mechanism fails to properly handle tuple structure changes when Babelfish processes OUTPUT clauses, leading to segmentation faults or assertion failures.
1 parent ee6a48c commit cfcefbc

1 file changed

Lines changed: 2 additions & 58 deletions

File tree

src/backend/executor/nodeModifyTable.c

Lines changed: 2 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -915,11 +915,6 @@ ExecInsert(ModifyTableContext *context,
915915
return NULL; /* "do nothing" */
916916
}
917917

918-
/* Process RETURNING if present */
919-
if (resultRelInfo->ri_projectReturning && sql_dialect == SQL_DIALECT_TSQL)
920-
result = ExecProcessReturning(context, resultRelInfo, CMD_INSERT,
921-
NULL, slot, planSlot);
922-
923918
/* INSTEAD OF ROW INSERT Triggers */
924919
if (resultRelInfo->ri_TrigDesc &&
925920
resultRelInfo->ri_TrigDesc->trig_insert_instead_row)
@@ -1603,7 +1598,6 @@ ExecDelete(ModifyTableContext *context,
16031598
Relation resultRelationDesc = resultRelInfo->ri_RelationDesc;
16041599
TupleTableSlot *slot = NULL;
16051600
TM_Result result;
1606-
TupleTableSlot *rslot_output = NULL;
16071601
bool saveOld;
16081602

16091603
if (tupleDeleted)
@@ -1617,44 +1611,6 @@ ExecDelete(ModifyTableContext *context,
16171611
epqreturnslot, tmresult))
16181612
return NULL;
16191613

1620-
/* Process RETURNING if present and if requested */
1621-
if (processReturning && resultRelInfo->ri_projectReturning && sql_dialect == SQL_DIALECT_TSQL)
1622-
{
1623-
/*
1624-
* We have to put the target tuple into a slot, which means first we
1625-
* gotta fetch it. We can use the trigger tuple slot.
1626-
*/
1627-
if (resultRelInfo->ri_FdwRoutine)
1628-
{
1629-
/* FDW must have provided a slot containing the deleted row */
1630-
Assert(!TupIsNull(slot));
1631-
}
1632-
else
1633-
{
1634-
slot = ExecGetReturningSlot(estate, resultRelInfo);
1635-
if (oldtuple != NULL)
1636-
{
1637-
ExecForceStoreHeapTuple(oldtuple, slot, false);
1638-
}
1639-
else
1640-
{
1641-
if (!table_tuple_fetch_row_version(resultRelationDesc, tupleid,
1642-
SnapshotAny, slot))
1643-
elog(ERROR, "failed to fetch deleted tuple for DELETE RETURNING");
1644-
}
1645-
}
1646-
rslot_output = ExecProcessReturning(context, resultRelInfo, CMD_DELETE,
1647-
slot, NULL, context->planSlot);
1648-
1649-
/*
1650-
* Before releasing the target tuple again, make sure rslot has a
1651-
* local copy of any pass-by-reference values.
1652-
*/
1653-
ExecMaterializeSlot(rslot_output);
1654-
1655-
ExecClearTuple(slot);
1656-
}
1657-
16581614
if (resultRelInfo->ri_TrigDesc &&
16591615
resultRelInfo->ri_TrigDesc->trig_delete_instead_statement &&
16601616
sql_dialect == SQL_DIALECT_TSQL &&
@@ -1899,7 +1855,7 @@ ExecDelete(ModifyTableContext *context,
18991855
saveOld = changingPart && resultRelInfo->ri_projectReturning &&
19001856
resultRelInfo->ri_projectReturning->pi_state.flags & EEO_FLAG_HAS_OLD;
19011857

1902-
if (resultRelInfo->ri_projectReturning && (processReturning || saveOld) && sql_dialect != SQL_DIALECT_TSQL)
1858+
if (resultRelInfo->ri_projectReturning && (processReturning || saveOld))
19031859
{
19041860
/*
19051861
* We have to put the target tuple into a slot, which means first we
@@ -1974,9 +1930,6 @@ ExecDelete(ModifyTableContext *context,
19741930
return rslot;
19751931
}
19761932

1977-
if (processReturning && resultRelInfo->ri_projectReturning && rslot_output)
1978-
return rslot_output;
1979-
19801933
return NULL;
19811934
}
19821935

@@ -2539,7 +2492,6 @@ ExecUpdate(ModifyTableContext *context, ResultRelInfo *resultRelInfo,
25392492
Relation resultRelationDesc = resultRelInfo->ri_RelationDesc;
25402493
UpdateContext updateCxt = {0};
25412494
TM_Result result;
2542-
TupleTableSlot *rslot = NULL;
25432495

25442496
/*
25452497
* abort the operation if not running transactions
@@ -2554,11 +2506,6 @@ ExecUpdate(ModifyTableContext *context, ResultRelInfo *resultRelInfo,
25542506
if (!ExecUpdatePrologue(context, resultRelInfo, tupleid, oldtuple, slot, NULL))
25552507
return NULL;
25562508

2557-
/* Process RETURNING if present */
2558-
if (resultRelInfo->ri_projectReturning && sql_dialect == SQL_DIALECT_TSQL)
2559-
rslot = ExecProcessReturning(context, resultRelInfo, CMD_UPDATE,
2560-
oldSlot, slot, context->planSlot);
2561-
25622509
if (resultRelInfo->ri_TrigDesc &&
25632510
resultRelInfo->ri_TrigDesc->trig_update_instead_statement &&
25642511
sql_dialect == SQL_DIALECT_TSQL && bbfViewHasInsteadofTrigger_hook && (bbfViewHasInsteadofTrigger_hook)(resultRelationDesc, CMD_UPDATE) &&
@@ -2781,13 +2728,10 @@ ExecUpdate(ModifyTableContext *context, ResultRelInfo *resultRelInfo,
27812728
slot);
27822729

27832730
/* Process RETURNING if present */
2784-
if (resultRelInfo->ri_projectReturning && sql_dialect != SQL_DIALECT_TSQL)
2731+
if (resultRelInfo->ri_projectReturning)
27852732
return ExecProcessReturning(context, resultRelInfo, CMD_UPDATE,
27862733
oldSlot, slot, context->planSlot);
27872734

2788-
if (resultRelInfo->ri_projectReturning)
2789-
return rslot;
2790-
27912735
return NULL;
27922736
}
27932737

0 commit comments

Comments
 (0)