47
47
#define DELIM ','
48
48
#define NTIDARGS 2
49
49
50
+ static ItemPointer currtid_for_view (Relation viewrel , ItemPointer tid );
51
+
50
52
/* ----------------------------------------------------------------
51
53
* tidin
52
54
* ----------------------------------------------------------------
@@ -275,20 +277,52 @@ hashtidextended(PG_FUNCTION_ARGS)
275
277
* Maybe these implementations should be moved to another place
276
278
*/
277
279
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 )
282
287
{
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 ;
284
318
}
285
319
286
320
/*
287
321
* Handle CTIDs of views.
288
322
* CTID should be defined in the view and it must
289
323
* correspond to the CTID of a base relation.
290
324
*/
291
- static Datum
325
+ static ItemPointer
292
326
currtid_for_view (Relation viewrel , ItemPointer tid )
293
327
{
294
328
TupleDesc att = RelationGetDescr (viewrel );
@@ -338,12 +372,12 @@ currtid_for_view(Relation viewrel, ItemPointer tid)
338
372
rte = rt_fetch (var -> varno , query -> rtable );
339
373
if (rte )
340
374
{
341
- Datum result ;
375
+ ItemPointer result ;
376
+ Relation rel ;
342
377
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 );
347
381
return result ;
348
382
}
349
383
}
@@ -352,56 +386,14 @@ currtid_for_view(Relation viewrel, ItemPointer tid)
352
386
}
353
387
}
354
388
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 ;
403
390
}
404
391
392
+ /*
393
+ * currtid_byrelname
394
+ * Get the latest tuple version of the tuple pointing at a CTID, for a
395
+ * given relation name.
396
+ */
405
397
Datum
406
398
currtid_byrelname (PG_FUNCTION_ARGS )
407
399
{
@@ -410,35 +402,12 @@ currtid_byrelname(PG_FUNCTION_ARGS)
410
402
ItemPointer result ;
411
403
RangeVar * relrv ;
412
404
Relation rel ;
413
- AclResult aclresult ;
414
- Snapshot snapshot ;
415
- TableScanDesc scan ;
416
405
417
406
relrv = makeRangeVarFromNameList (textToQualifiedNameList (relname ));
418
407
rel = table_openrv (relrv , AccessShareLock );
419
408
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 );
442
411
443
412
table_close (rel , AccessShareLock );
444
413
0 commit comments