diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/executor/nodeModifyTable.c | 3 | ||||
-rw-r--r-- | src/backend/utils/adt/tid.c | 137 |
2 files changed, 53 insertions, 87 deletions
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 29e07b72287..e0f24283b80 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -645,10 +645,7 @@ ExecInsert(ModifyTableState *mtstate, } if (canSetTag) - { (estate->es_processed)++; - setLastTid(&slot->tts_tid); - } /* * If this insert is the result of a partition key update that moved the diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c index 509a0fdffcd..52028603d23 100644 --- a/src/backend/utils/adt/tid.c +++ b/src/backend/utils/adt/tid.c @@ -47,6 +47,8 @@ #define DELIM ',' #define NTIDARGS 2 +static ItemPointer currtid_for_view(Relation viewrel, ItemPointer tid); + /* ---------------------------------------------------------------- * tidin * ---------------------------------------------------------------- @@ -275,12 +277,44 @@ hashtidextended(PG_FUNCTION_ARGS) * Maybe these implementations should be moved to another place */ -static ItemPointerData Current_last_tid = {{0, 0}, 0}; - -void -setLastTid(const ItemPointer tid) +/* + * Utility wrapper for current CTID functions. + * Returns the latest version of a tuple pointing at "tid" for + * relation "rel". + */ +static ItemPointer +currtid_internal(Relation rel, ItemPointer tid) { - Current_last_tid = *tid; + ItemPointer result; + AclResult aclresult; + Snapshot snapshot; + TableScanDesc scan; + + result = (ItemPointer) palloc(sizeof(ItemPointerData)); + + aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), + ACL_SELECT); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind), + RelationGetRelationName(rel)); + + if (rel->rd_rel->relkind == RELKIND_VIEW) + return currtid_for_view(rel, tid); + + if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind)) + elog(ERROR, "cannot look at latest visible tid for relation \"%s.%s\"", + get_namespace_name(RelationGetNamespace(rel)), + RelationGetRelationName(rel)); + + ItemPointerCopy(tid, result); + + snapshot = RegisterSnapshot(GetLatestSnapshot()); + scan = table_beginscan_tid(rel, snapshot); + table_tuple_get_latest_tid(scan, result); + table_endscan(scan); + UnregisterSnapshot(snapshot); + + return result; } /* @@ -288,7 +322,7 @@ setLastTid(const ItemPointer tid) * CTID should be defined in the view and it must * correspond to the CTID of a base relation. */ -static Datum +static ItemPointer currtid_for_view(Relation viewrel, ItemPointer tid) { TupleDesc att = RelationGetDescr(viewrel); @@ -338,12 +372,12 @@ currtid_for_view(Relation viewrel, ItemPointer tid) rte = rt_fetch(var->varno, query->rtable); if (rte) { - Datum result; + ItemPointer result; + Relation rel; - result = DirectFunctionCall2(currtid_byreloid, - ObjectIdGetDatum(rte->relid), - PointerGetDatum(tid)); - table_close(viewrel, AccessShareLock); + rel = table_open(rte->relid, AccessShareLock); + result = currtid_internal(rel, tid); + table_close(rel, AccessShareLock); return result; } } @@ -352,56 +386,14 @@ currtid_for_view(Relation viewrel, ItemPointer tid) } } elog(ERROR, "currtid cannot handle this view"); - return (Datum) 0; -} - -Datum -currtid_byreloid(PG_FUNCTION_ARGS) -{ - Oid reloid = PG_GETARG_OID(0); - ItemPointer tid = PG_GETARG_ITEMPOINTER(1); - ItemPointer result; - Relation rel; - AclResult aclresult; - Snapshot snapshot; - TableScanDesc scan; - - result = (ItemPointer) palloc(sizeof(ItemPointerData)); - if (!reloid) - { - *result = Current_last_tid; - PG_RETURN_ITEMPOINTER(result); - } - - rel = table_open(reloid, AccessShareLock); - - aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), - ACL_SELECT); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind), - RelationGetRelationName(rel)); - - if (rel->rd_rel->relkind == RELKIND_VIEW) - return currtid_for_view(rel, tid); - - if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind)) - elog(ERROR, "cannot look at latest visible tid for relation \"%s.%s\"", - get_namespace_name(RelationGetNamespace(rel)), - RelationGetRelationName(rel)); - - ItemPointerCopy(tid, result); - - snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = table_beginscan_tid(rel, snapshot); - table_tuple_get_latest_tid(scan, result); - table_endscan(scan); - UnregisterSnapshot(snapshot); - - table_close(rel, AccessShareLock); - - PG_RETURN_ITEMPOINTER(result); + return NULL; } +/* + * currtid_byrelname + * Get the latest tuple version of the tuple pointing at a CTID, for a + * given relation name. + */ Datum currtid_byrelname(PG_FUNCTION_ARGS) { @@ -410,35 +402,12 @@ currtid_byrelname(PG_FUNCTION_ARGS) ItemPointer result; RangeVar *relrv; Relation rel; - AclResult aclresult; - Snapshot snapshot; - TableScanDesc scan; relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); rel = table_openrv(relrv, AccessShareLock); - aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), - ACL_SELECT); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind), - RelationGetRelationName(rel)); - - if (rel->rd_rel->relkind == RELKIND_VIEW) - return currtid_for_view(rel, tid); - - if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind)) - elog(ERROR, "cannot look at latest visible tid for relation \"%s.%s\"", - get_namespace_name(RelationGetNamespace(rel)), - RelationGetRelationName(rel)); - - result = (ItemPointer) palloc(sizeof(ItemPointerData)); - ItemPointerCopy(tid, result); - - snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = table_beginscan_tid(rel, snapshot); - table_tuple_get_latest_tid(scan, result); - table_endscan(scan); - UnregisterSnapshot(snapshot); + /* grab the latest tuple version associated to this CTID */ + result = currtid_internal(rel, tid); table_close(rel, AccessShareLock); |