aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execQual.c40
-rw-r--r--src/backend/executor/nodeTidscan.c19
2 files changed, 23 insertions, 36 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 */
}
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index 31a9828b6a1..8c217a442be 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeTidscan.c,v 1.55 2007/06/11 22:22:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeTidscan.c,v 1.56 2007/10/24 18:37:08 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -68,6 +68,7 @@ TidListCreate(TidScanState *tidstate)
tidList = (ItemPointerData *)
palloc(numAllocTids * sizeof(ItemPointerData));
numTids = 0;
+ tidstate->tss_isCurrentOf = false;
foreach(l, evalList)
{
@@ -165,6 +166,7 @@ TidListCreate(TidScanState *tidstate)
numAllocTids * sizeof(ItemPointerData));
}
tidList[numTids++] = cursor_tid;
+ tidstate->tss_isCurrentOf = true;
}
}
else
@@ -182,6 +184,9 @@ TidListCreate(TidScanState *tidstate)
int lastTid;
int i;
+ /* CurrentOfExpr could never appear OR'd with something else */
+ Assert(!tidstate->tss_isCurrentOf);
+
qsort((void *) tidList, numTids, sizeof(ItemPointerData),
itemptr_comparator);
lastTid = 0;
@@ -269,7 +274,8 @@ TidNext(TidScanState *node)
/*
* XXX shouldn't we check here to make sure tuple matches TID list? In
- * runtime-key case this is not certain, is it?
+ * runtime-key case this is not certain, is it? However, in the
+ * WHERE CURRENT OF case it might not match anyway ...
*/
ExecStoreTuple(estate->es_evTuple[scanrelid - 1],
@@ -319,6 +325,15 @@ TidNext(TidScanState *node)
while (node->tss_TidPtr >= 0 && node->tss_TidPtr < numTids)
{
tuple->t_self = tidList[node->tss_TidPtr];
+
+ /*
+ * For WHERE CURRENT OF, the tuple retrieved from the cursor might
+ * since have been updated; if so, we should fetch the version that
+ * is current according to our snapshot.
+ */
+ if (node->tss_isCurrentOf)
+ heap_get_latest_tid(heapRelation, snapshot, &tuple->t_self);
+
if (heap_fetch(heapRelation, snapshot, tuple, &buffer, false, NULL))
{
/*