mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +03:00
Remove catalog function currtid()
currtid() and currtid2() are an undocumented set of functions whose sole known user is the Postgres ODBC driver, able to retrieve the latest TID version for a tuple given by the caller of those functions. As used by Postgres ODBC, currtid() is a shortcut able to retrieve the last TID loaded into a backend by passing an OID of 0 (magic value) after a tuple insertion. This is removed in this commit, as it became obsolete after the driver began using "RETURNING ctid" with inserts, a clause supported since Postgres 8.2 (using RETURNING is better for performance anyway as it reduces the number of round-trips to the backend). currtid2() is still used by the driver, so this remains around for now. Note that this function is kept in its original shape for backward compatibility reasons. Per discussion with many people, including Andres Freund, Peter Eisentraut, Álvaro Herrera, Hiroshi Inoue, Tom Lane and myself. Bump catalog version. Discussion: https://postgr.es/m/20200603021448.GB89559@paquier.xyz
This commit is contained in:
@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user