Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7b94e99

Browse files
committed
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
1 parent 660b899 commit 7b94e99

File tree

7 files changed

+56
-133
lines changed

7 files changed

+56
-133
lines changed

src/backend/executor/nodeModifyTable.c

-3
Original file line numberDiff line numberDiff line change
@@ -645,10 +645,7 @@ ExecInsert(ModifyTableState *mtstate,
645645
}
646646

647647
if (canSetTag)
648-
{
649648
(estate->es_processed)++;
650-
setLastTid(&slot->tts_tid);
651-
}
652649

653650
/*
654651
* If this insert is the result of a partition key update that moved the

src/backend/utils/adt/tid.c

+53-84
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
#define DELIM ','
4848
#define NTIDARGS 2
4949

50+
static ItemPointer currtid_for_view(Relation viewrel, ItemPointer tid);
51+
5052
/* ----------------------------------------------------------------
5153
* tidin
5254
* ----------------------------------------------------------------
@@ -275,20 +277,52 @@ hashtidextended(PG_FUNCTION_ARGS)
275277
* Maybe these implementations should be moved to another place
276278
*/
277279

278-
static ItemPointerData Current_last_tid = {{0, 0}, 0};
279-
280-
void
281-
setLastTid(const ItemPointer tid)
280+
/*
281+
* Utility wrapper for current CTID functions.
282+
* Returns the latest version of a tuple pointing at "tid" for
283+
* relation "rel".
284+
*/
285+
static ItemPointer
286+
currtid_internal(Relation rel, ItemPointer tid)
282287
{
283-
Current_last_tid = *tid;
288+
ItemPointer result;
289+
AclResult aclresult;
290+
Snapshot snapshot;
291+
TableScanDesc scan;
292+
293+
result = (ItemPointer) palloc(sizeof(ItemPointerData));
294+
295+
aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
296+
ACL_SELECT);
297+
if (aclresult != ACLCHECK_OK)
298+
aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind),
299+
RelationGetRelationName(rel));
300+
301+
if (rel->rd_rel->relkind == RELKIND_VIEW)
302+
return currtid_for_view(rel, tid);
303+
304+
if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
305+
elog(ERROR, "cannot look at latest visible tid for relation \"%s.%s\"",
306+
get_namespace_name(RelationGetNamespace(rel)),
307+
RelationGetRelationName(rel));
308+
309+
ItemPointerCopy(tid, result);
310+
311+
snapshot = RegisterSnapshot(GetLatestSnapshot());
312+
scan = table_beginscan_tid(rel, snapshot);
313+
table_tuple_get_latest_tid(scan, result);
314+
table_endscan(scan);
315+
UnregisterSnapshot(snapshot);
316+
317+
return result;
284318
}
285319

286320
/*
287321
* Handle CTIDs of views.
288322
* CTID should be defined in the view and it must
289323
* correspond to the CTID of a base relation.
290324
*/
291-
static Datum
325+
static ItemPointer
292326
currtid_for_view(Relation viewrel, ItemPointer tid)
293327
{
294328
TupleDesc att = RelationGetDescr(viewrel);
@@ -338,12 +372,12 @@ currtid_for_view(Relation viewrel, ItemPointer tid)
338372
rte = rt_fetch(var->varno, query->rtable);
339373
if (rte)
340374
{
341-
Datum result;
375+
ItemPointer result;
376+
Relation rel;
342377

343-
result = DirectFunctionCall2(currtid_byreloid,
344-
ObjectIdGetDatum(rte->relid),
345-
PointerGetDatum(tid));
346-
table_close(viewrel, AccessShareLock);
378+
rel = table_open(rte->relid, AccessShareLock);
379+
result = currtid_internal(rel, tid);
380+
table_close(rel, AccessShareLock);
347381
return result;
348382
}
349383
}
@@ -352,56 +386,14 @@ currtid_for_view(Relation viewrel, ItemPointer tid)
352386
}
353387
}
354388
elog(ERROR, "currtid cannot handle this view");
355-
return (Datum) 0;
356-
}
357-
358-
Datum
359-
currtid_byreloid(PG_FUNCTION_ARGS)
360-
{
361-
Oid reloid = PG_GETARG_OID(0);
362-
ItemPointer tid = PG_GETARG_ITEMPOINTER(1);
363-
ItemPointer result;
364-
Relation rel;
365-
AclResult aclresult;
366-
Snapshot snapshot;
367-
TableScanDesc scan;
368-
369-
result = (ItemPointer) palloc(sizeof(ItemPointerData));
370-
if (!reloid)
371-
{
372-
*result = Current_last_tid;
373-
PG_RETURN_ITEMPOINTER(result);
374-
}
375-
376-
rel = table_open(reloid, AccessShareLock);
377-
378-
aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
379-
ACL_SELECT);
380-
if (aclresult != ACLCHECK_OK)
381-
aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind),
382-
RelationGetRelationName(rel));
383-
384-
if (rel->rd_rel->relkind == RELKIND_VIEW)
385-
return currtid_for_view(rel, tid);
386-
387-
if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
388-
elog(ERROR, "cannot look at latest visible tid for relation \"%s.%s\"",
389-
get_namespace_name(RelationGetNamespace(rel)),
390-
RelationGetRelationName(rel));
391-
392-
ItemPointerCopy(tid, result);
393-
394-
snapshot = RegisterSnapshot(GetLatestSnapshot());
395-
scan = table_beginscan_tid(rel, snapshot);
396-
table_tuple_get_latest_tid(scan, result);
397-
table_endscan(scan);
398-
UnregisterSnapshot(snapshot);
399-
400-
table_close(rel, AccessShareLock);
401-
402-
PG_RETURN_ITEMPOINTER(result);
389+
return NULL;
403390
}
404391

392+
/*
393+
* currtid_byrelname
394+
* Get the latest tuple version of the tuple pointing at a CTID, for a
395+
* given relation name.
396+
*/
405397
Datum
406398
currtid_byrelname(PG_FUNCTION_ARGS)
407399
{
@@ -410,35 +402,12 @@ currtid_byrelname(PG_FUNCTION_ARGS)
410402
ItemPointer result;
411403
RangeVar *relrv;
412404
Relation rel;
413-
AclResult aclresult;
414-
Snapshot snapshot;
415-
TableScanDesc scan;
416405

417406
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
418407
rel = table_openrv(relrv, AccessShareLock);
419408

420-
aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
421-
ACL_SELECT);
422-
if (aclresult != ACLCHECK_OK)
423-
aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind),
424-
RelationGetRelationName(rel));
425-
426-
if (rel->rd_rel->relkind == RELKIND_VIEW)
427-
return currtid_for_view(rel, tid);
428-
429-
if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
430-
elog(ERROR, "cannot look at latest visible tid for relation \"%s.%s\"",
431-
get_namespace_name(RelationGetNamespace(rel)),
432-
RelationGetRelationName(rel));
433-
434-
result = (ItemPointer) palloc(sizeof(ItemPointerData));
435-
ItemPointerCopy(tid, result);
436-
437-
snapshot = RegisterSnapshot(GetLatestSnapshot());
438-
scan = table_beginscan_tid(rel, snapshot);
439-
table_tuple_get_latest_tid(scan, result);
440-
table_endscan(scan);
441-
UnregisterSnapshot(snapshot);
409+
/* grab the latest tuple version associated to this CTID */
410+
result = currtid_internal(rel, tid);
442411

443412
table_close(rel, AccessShareLock);
444413

src/include/access/heapam.h

-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ extern bool heap_hot_search_buffer(ItemPointer tid, Relation relation,
129129
bool *all_dead, bool first_call);
130130

131131
extern void heap_get_latest_tid(TableScanDesc scan, ItemPointer tid);
132-
extern void setLastTid(const ItemPointer tid);
133132

134133
extern BulkInsertState GetBulkInsertState(void);
135134
extern void FreeBulkInsertState(BulkInsertState);

src/include/catalog/catversion.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 202011241
56+
#define CATALOG_VERSION_NO 202011251
5757

5858
#endif

src/include/catalog/pg_proc.dat

-3
Original file line numberDiff line numberDiff line change
@@ -2549,9 +2549,6 @@
25492549
{ oid => '1292',
25502550
proname => 'tideq', proleakproof => 't', prorettype => 'bool',
25512551
proargtypes => 'tid tid', prosrc => 'tideq' },
2552-
{ oid => '1293', descr => 'latest tid of a tuple',
2553-
proname => 'currtid', provolatile => 'v', proparallel => 'u',
2554-
prorettype => 'tid', proargtypes => 'oid tid', prosrc => 'currtid_byreloid' },
25552552
{ oid => '1294', descr => 'latest tid of a tuple',
25562553
proname => 'currtid2', provolatile => 'v', proparallel => 'u',
25572554
prorettype => 'tid', proargtypes => 'text tid',

src/test/regress/expected/tid.out

+1-31
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,13 @@ SELECT max(ctid) FROM tid_tab;
1515
(1 row)
1616

1717
TRUNCATE tid_tab;
18-
-- Tests for currtid() and currtid2() with various relation kinds
18+
-- Tests for currtid2() with various relation kinds
1919
-- Materialized view
2020
CREATE MATERIALIZED VIEW tid_matview AS SELECT a FROM tid_tab;
21-
SELECT currtid('tid_matview'::regclass::oid, '(0,1)'::tid); -- fails
22-
ERROR: tid (0, 1) is not valid for relation "tid_matview"
2321
SELECT currtid2('tid_matview'::text, '(0,1)'::tid); -- fails
2422
ERROR: tid (0, 1) is not valid for relation "tid_matview"
2523
INSERT INTO tid_tab VALUES (1);
2624
REFRESH MATERIALIZED VIEW tid_matview;
27-
SELECT currtid('tid_matview'::regclass::oid, '(0,1)'::tid); -- ok
28-
currtid
29-
---------
30-
(0,1)
31-
(1 row)
32-
3325
SELECT currtid2('tid_matview'::text, '(0,1)'::tid); -- ok
3426
currtid2
3527
----------
@@ -40,12 +32,6 @@ DROP MATERIALIZED VIEW tid_matview;
4032
TRUNCATE tid_tab;
4133
-- Sequence
4234
CREATE SEQUENCE tid_seq;
43-
SELECT currtid('tid_seq'::regclass::oid, '(0,1)'::tid); -- ok
44-
currtid
45-
---------
46-
(0,1)
47-
(1 row)
48-
4935
SELECT currtid2('tid_seq'::text, '(0,1)'::tid); -- ok
5036
currtid2
5137
----------
@@ -55,39 +41,25 @@ SELECT currtid2('tid_seq'::text, '(0,1)'::tid); -- ok
5541
DROP SEQUENCE tid_seq;
5642
-- Index, fails with incorrect relation type
5743
CREATE INDEX tid_ind ON tid_tab(a);
58-
SELECT currtid('tid_ind'::regclass::oid, '(0,1)'::tid); -- fails
59-
ERROR: "tid_ind" is an index
6044
SELECT currtid2('tid_ind'::text, '(0,1)'::tid); -- fails
6145
ERROR: "tid_ind" is an index
6246
DROP INDEX tid_ind;
6347
-- Partitioned table, no storage
6448
CREATE TABLE tid_part (a int) PARTITION BY RANGE (a);
65-
SELECT currtid('tid_part'::regclass::oid, '(0,1)'::tid); -- fails
66-
ERROR: cannot look at latest visible tid for relation "public.tid_part"
6749
SELECT currtid2('tid_part'::text, '(0,1)'::tid); -- fails
6850
ERROR: cannot look at latest visible tid for relation "public.tid_part"
6951
DROP TABLE tid_part;
7052
-- Views
7153
-- ctid not defined in the view
7254
CREATE VIEW tid_view_no_ctid AS SELECT a FROM tid_tab;
73-
SELECT currtid('tid_view_no_ctid'::regclass::oid, '(0,1)'::tid); -- fails
74-
ERROR: currtid cannot handle views with no CTID
7555
SELECT currtid2('tid_view_no_ctid'::text, '(0,1)'::tid); -- fails
7656
ERROR: currtid cannot handle views with no CTID
7757
DROP VIEW tid_view_no_ctid;
7858
-- ctid fetched directly from the source table.
7959
CREATE VIEW tid_view_with_ctid AS SELECT ctid, a FROM tid_tab;
80-
SELECT currtid('tid_view_with_ctid'::regclass::oid, '(0,1)'::tid); -- fails
81-
ERROR: tid (0, 1) is not valid for relation "tid_tab"
8260
SELECT currtid2('tid_view_with_ctid'::text, '(0,1)'::tid); -- fails
8361
ERROR: tid (0, 1) is not valid for relation "tid_tab"
8462
INSERT INTO tid_tab VALUES (1);
85-
SELECT currtid('tid_view_with_ctid'::regclass::oid, '(0,1)'::tid); -- ok
86-
currtid
87-
---------
88-
(0,1)
89-
(1 row)
90-
9163
SELECT currtid2('tid_view_with_ctid'::text, '(0,1)'::tid); -- ok
9264
currtid2
9365
----------
@@ -98,8 +70,6 @@ DROP VIEW tid_view_with_ctid;
9870
TRUNCATE tid_tab;
9971
-- ctid attribute with incorrect data type
10072
CREATE VIEW tid_view_fake_ctid AS SELECT 1 AS ctid, 2 AS a;
101-
SELECT currtid('tid_view_fake_ctid'::regclass::oid, '(0,1)'::tid); -- fails
102-
ERROR: ctid isn't of type TID
10373
SELECT currtid2('tid_view_fake_ctid'::text, '(0,1)'::tid); -- fails
10474
ERROR: ctid isn't of type TID
10575
DROP VIEW tid_view_fake_ctid;

src/test/regress/sql/tid.sql

+1-10
Original file line numberDiff line numberDiff line change
@@ -8,55 +8,46 @@ SELECT min(ctid) FROM tid_tab;
88
SELECT max(ctid) FROM tid_tab;
99
TRUNCATE tid_tab;
1010

11-
-- Tests for currtid() and currtid2() with various relation kinds
11+
-- Tests for currtid2() with various relation kinds
1212

1313
-- Materialized view
1414
CREATE MATERIALIZED VIEW tid_matview AS SELECT a FROM tid_tab;
15-
SELECT currtid('tid_matview'::regclass::oid, '(0,1)'::tid); -- fails
1615
SELECT currtid2('tid_matview'::text, '(0,1)'::tid); -- fails
1716
INSERT INTO tid_tab VALUES (1);
1817
REFRESH MATERIALIZED VIEW tid_matview;
19-
SELECT currtid('tid_matview'::regclass::oid, '(0,1)'::tid); -- ok
2018
SELECT currtid2('tid_matview'::text, '(0,1)'::tid); -- ok
2119
DROP MATERIALIZED VIEW tid_matview;
2220
TRUNCATE tid_tab;
2321

2422
-- Sequence
2523
CREATE SEQUENCE tid_seq;
26-
SELECT currtid('tid_seq'::regclass::oid, '(0,1)'::tid); -- ok
2724
SELECT currtid2('tid_seq'::text, '(0,1)'::tid); -- ok
2825
DROP SEQUENCE tid_seq;
2926

3027
-- Index, fails with incorrect relation type
3128
CREATE INDEX tid_ind ON tid_tab(a);
32-
SELECT currtid('tid_ind'::regclass::oid, '(0,1)'::tid); -- fails
3329
SELECT currtid2('tid_ind'::text, '(0,1)'::tid); -- fails
3430
DROP INDEX tid_ind;
3531

3632
-- Partitioned table, no storage
3733
CREATE TABLE tid_part (a int) PARTITION BY RANGE (a);
38-
SELECT currtid('tid_part'::regclass::oid, '(0,1)'::tid); -- fails
3934
SELECT currtid2('tid_part'::text, '(0,1)'::tid); -- fails
4035
DROP TABLE tid_part;
4136

4237
-- Views
4338
-- ctid not defined in the view
4439
CREATE VIEW tid_view_no_ctid AS SELECT a FROM tid_tab;
45-
SELECT currtid('tid_view_no_ctid'::regclass::oid, '(0,1)'::tid); -- fails
4640
SELECT currtid2('tid_view_no_ctid'::text, '(0,1)'::tid); -- fails
4741
DROP VIEW tid_view_no_ctid;
4842
-- ctid fetched directly from the source table.
4943
CREATE VIEW tid_view_with_ctid AS SELECT ctid, a FROM tid_tab;
50-
SELECT currtid('tid_view_with_ctid'::regclass::oid, '(0,1)'::tid); -- fails
5144
SELECT currtid2('tid_view_with_ctid'::text, '(0,1)'::tid); -- fails
5245
INSERT INTO tid_tab VALUES (1);
53-
SELECT currtid('tid_view_with_ctid'::regclass::oid, '(0,1)'::tid); -- ok
5446
SELECT currtid2('tid_view_with_ctid'::text, '(0,1)'::tid); -- ok
5547
DROP VIEW tid_view_with_ctid;
5648
TRUNCATE tid_tab;
5749
-- ctid attribute with incorrect data type
5850
CREATE VIEW tid_view_fake_ctid AS SELECT 1 AS ctid, 2 AS a;
59-
SELECT currtid('tid_view_fake_ctid'::regclass::oid, '(0,1)'::tid); -- fails
6051
SELECT currtid2('tid_view_fake_ctid'::text, '(0,1)'::tid); -- fails
6152
DROP VIEW tid_view_fake_ctid;
6253

0 commit comments

Comments
 (0)