aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execQual.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-10-24 18:37:09 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-10-24 18:37:09 +0000
commitc29a9c37bf6bdaaaa65ccbcd4c69c596691134e1 (patch)
treec7df7fd2c22d5007ff6901800714d93bc4ce8a4c /src/backend/executor/execQual.c
parent9226ba817b19999d51d39a0a2bde810160d0cf24 (diff)
downloadpostgresql-c29a9c37bf6bdaaaa65ccbcd4c69c596691134e1.tar.gz
postgresql-c29a9c37bf6bdaaaa65ccbcd4c69c596691134e1.zip
Fix UPDATE/DELETE WHERE CURRENT OF to support repeated update and update-
then-delete on the current cursor row. The basic fix is that nodeTidscan.c has to apply heap_get_latest_tid() to the current-scan-TID obtained from the cursor query; this ensures we get the latest row version to work with. However, since that only works if the query plan is a TID scan, we also have to hack the planner to make sure only that type of plan will be selected. (Formerly, the planner might decide to apply a seqscan if the table is very small. This change is probably a Good Thing anyway, since it's hard to see how a seqscan could really win.) That means the execQual.c code to support CurrentOfExpr as a regular expression type is dead code, so replace it with just an elog(). Also, add regression tests covering these cases. Note that the added tests expose the fact that re-fetching an updated row misbehaves if the cursor used FOR UPDATE. That's an independent bug that should be fixed later. Per report from Dharmendra Goyal.
Diffstat (limited to 'src/backend/executor/execQual.c')
-rw-r--r--src/backend/executor/execQual.c40
1 files changed, 6 insertions, 34 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index cc165006f5c..53ddc658197 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.222 2007/09/06 17:31:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.223 2007/10/24 18:37:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -3694,45 +3694,17 @@ ExecEvalArrayCoerceExpr(ArrayCoerceExprState *astate,
/* ----------------------------------------------------------------
* ExecEvalCurrentOfExpr
*
- * Normally, the planner will convert CURRENT OF into a TidScan qualification,
- * but we have plain execQual support in case it doesn't.
+ * The planner must convert CURRENT OF into a TidScan qualification.
+ * So, we have to be able to do ExecInitExpr on a CurrentOfExpr,
+ * but we shouldn't ever actually execute it.
* ----------------------------------------------------------------
*/
static Datum
ExecEvalCurrentOfExpr(ExprState *exprstate, ExprContext *econtext,
bool *isNull, ExprDoneCond *isDone)
{
- CurrentOfExpr *cexpr = (CurrentOfExpr *) exprstate->expr;
- bool result;
- bool lisnull;
- Oid tableoid;
- ItemPointer tuple_tid;
- ItemPointerData cursor_tid;
-
- if (isDone)
- *isDone = ExprSingleResult;
- *isNull = false;
-
- Assert(cexpr->cvarno != INNER);
- Assert(cexpr->cvarno != OUTER);
- Assert(!TupIsNull(econtext->ecxt_scantuple));
- /* Use slot_getattr to catch any possible mistakes */
- tableoid = DatumGetObjectId(slot_getattr(econtext->ecxt_scantuple,
- TableOidAttributeNumber,
- &lisnull));
- Assert(!lisnull);
- tuple_tid = (ItemPointer)
- DatumGetPointer(slot_getattr(econtext->ecxt_scantuple,
- SelfItemPointerAttributeNumber,
- &lisnull));
- Assert(!lisnull);
-
- if (execCurrentOf(cexpr, econtext, tableoid, &cursor_tid))
- result = ItemPointerEquals(&cursor_tid, tuple_tid);
- else
- result = false;
-
- return BoolGetDatum(result);
+ elog(ERROR, "CURRENT OF cannot be executed");
+ return 0; /* keep compiler quiet */
}