40
40
#include "utils/expandeddatum.h"
41
41
#include "utils/fmgroids.h"
42
42
#include "utils/rel.h"
43
+ #include "utils/snapmgr.h"
43
44
#include "utils/typcache.h"
44
45
#include "utils/tqual.h"
45
46
@@ -81,6 +82,7 @@ static int toast_open_indexes(Relation toastrel,
81
82
int * num_indexes );
82
83
static void toast_close_indexes (Relation * toastidxs , int num_indexes ,
83
84
LOCKMODE lock );
85
+ static void init_toast_snapshot (Snapshot toast_snapshot );
84
86
85
87
86
88
/* ----------
@@ -1665,6 +1667,7 @@ toast_delete_datum(Relation rel, Datum value)
1665
1667
HeapTuple toasttup ;
1666
1668
int num_indexes ;
1667
1669
int validIndex ;
1670
+ SnapshotData SnapshotToast ;
1668
1671
1669
1672
if (!VARATT_IS_EXTERNAL_ONDISK (attr ))
1670
1673
return ;
@@ -1696,8 +1699,9 @@ toast_delete_datum(Relation rel, Datum value)
1696
1699
* sequence or not, but since we've already locked the index we might as
1697
1700
* well use systable_beginscan_ordered.)
1698
1701
*/
1702
+ init_toast_snapshot (& SnapshotToast );
1699
1703
toastscan = systable_beginscan_ordered (toastrel , toastidxs [validIndex ],
1700
- SnapshotToast , 1 , & toastkey );
1704
+ & SnapshotToast , 1 , & toastkey );
1701
1705
while ((toasttup = systable_getnext_ordered (toastscan , ForwardScanDirection )) != NULL )
1702
1706
{
1703
1707
/*
@@ -1730,6 +1734,7 @@ toastrel_valueid_exists(Relation toastrel, Oid valueid)
1730
1734
int num_indexes ;
1731
1735
int validIndex ;
1732
1736
Relation * toastidxs ;
1737
+ SnapshotData SnapshotToast ;
1733
1738
1734
1739
/* Fetch a valid index relation */
1735
1740
validIndex = toast_open_indexes (toastrel ,
@@ -1748,9 +1753,10 @@ toastrel_valueid_exists(Relation toastrel, Oid valueid)
1748
1753
/*
1749
1754
* Is there any such chunk?
1750
1755
*/
1756
+ init_toast_snapshot (& SnapshotToast );
1751
1757
toastscan = systable_beginscan (toastrel ,
1752
1758
RelationGetRelid (toastidxs [validIndex ]),
1753
- true, SnapshotToast , 1 , & toastkey );
1759
+ true, & SnapshotToast , 1 , & toastkey );
1754
1760
1755
1761
if (systable_getnext (toastscan ) != NULL )
1756
1762
result = true;
@@ -1813,6 +1819,7 @@ toast_fetch_datum(struct varlena * attr)
1813
1819
int32 chunksize ;
1814
1820
int num_indexes ;
1815
1821
int validIndex ;
1822
+ SnapshotData SnapshotToast ;
1816
1823
1817
1824
if (!VARATT_IS_EXTERNAL_ONDISK (attr ))
1818
1825
elog (ERROR , "toast_fetch_datum shouldn't be called for non-ondisk datums" );
@@ -1859,8 +1866,9 @@ toast_fetch_datum(struct varlena * attr)
1859
1866
*/
1860
1867
nextidx = 0 ;
1861
1868
1869
+ init_toast_snapshot (& SnapshotToast );
1862
1870
toastscan = systable_beginscan_ordered (toastrel , toastidxs [validIndex ],
1863
- SnapshotToast , 1 , & toastkey );
1871
+ & SnapshotToast , 1 , & toastkey );
1864
1872
while ((ttup = systable_getnext_ordered (toastscan , ForwardScanDirection )) != NULL )
1865
1873
{
1866
1874
/*
@@ -1990,6 +1998,7 @@ toast_fetch_datum_slice(struct varlena * attr, int32 sliceoffset, int32 length)
1990
1998
int32 chcpyend ;
1991
1999
int num_indexes ;
1992
2000
int validIndex ;
2001
+ SnapshotData SnapshotToast ;
1993
2002
1994
2003
if (!VARATT_IS_EXTERNAL_ONDISK (attr ))
1995
2004
elog (ERROR , "toast_fetch_datum_slice shouldn't be called for non-ondisk datums" );
@@ -2082,9 +2091,10 @@ toast_fetch_datum_slice(struct varlena * attr, int32 sliceoffset, int32 length)
2082
2091
*
2083
2092
* The index is on (valueid, chunkidx) so they will come in order
2084
2093
*/
2094
+ init_toast_snapshot (& SnapshotToast );
2085
2095
nextidx = startchunk ;
2086
2096
toastscan = systable_beginscan_ordered (toastrel , toastidxs [validIndex ],
2087
- SnapshotToast , nscankeys , toastkey );
2097
+ & SnapshotToast , nscankeys , toastkey );
2088
2098
while ((ttup = systable_getnext_ordered (toastscan , ForwardScanDirection )) != NULL )
2089
2099
{
2090
2100
/*
@@ -2289,3 +2299,22 @@ toast_close_indexes(Relation *toastidxs, int num_indexes, LOCKMODE lock)
2289
2299
index_close (toastidxs [i ], lock );
2290
2300
pfree (toastidxs );
2291
2301
}
2302
+
2303
+ /* ----------
2304
+ * init_toast_snapshot
2305
+ *
2306
+ * Initialize an appropriate TOAST snapshot. We must use an MVCC snapshot
2307
+ * to initialize the TOAST snapshot; since we don't know which one to use,
2308
+ * just use the oldest one. This is safe: at worst, we will get a "snapshot
2309
+ * too old" error that might have been avoided otherwise.
2310
+ */
2311
+ static void
2312
+ init_toast_snapshot (Snapshot toast_snapshot )
2313
+ {
2314
+ Snapshot snapshot = GetOldestSnapshot ();
2315
+
2316
+ if (snapshot == NULL )
2317
+ elog (ERROR , "no known snapshots" );
2318
+
2319
+ InitToastSnapshot (toast_snapshot , snapshot -> lsn , snapshot -> whenTaken );
2320
+ }
0 commit comments