27
27
#include "catalog/toasting.h"
28
28
#include "miscadmin.h"
29
29
#include "nodes/makefuncs.h"
30
+ #include "storage/lock.h"
30
31
#include "utils/builtins.h"
31
32
#include "utils/rel.h"
32
33
#include "utils/syscache.h"
33
34
34
35
/* Potentially set by contrib/pg_upgrade_support functions */
35
36
Oid binary_upgrade_next_toast_pg_type_oid = InvalidOid ;
36
37
38
+ static void CheckAndCreateToastTable (Oid relOid , Datum reloptions ,
39
+ LOCKMODE lockmode , bool check );
37
40
static bool create_toast_table (Relation rel , Oid toastOid , Oid toastIndexOid ,
38
- Datum reloptions );
41
+ Datum reloptions , LOCKMODE lockmode , bool check );
39
42
static bool needs_toast_table (Relation rel );
40
43
41
44
42
45
/*
43
- * AlterTableCreateToastTable
46
+ * CreateToastTable variants
44
47
* If the table needs a toast table, and doesn't already have one,
45
48
* then create a toast table for it.
46
49
*
@@ -52,21 +55,32 @@ static bool needs_toast_table(Relation rel);
52
55
* to end with CommandCounterIncrement if it makes any changes.
53
56
*/
54
57
void
55
- AlterTableCreateToastTable (Oid relOid , Datum reloptions )
58
+ AlterTableCreateToastTable (Oid relOid , Datum reloptions , LOCKMODE lockmode )
59
+ {
60
+ CheckAndCreateToastTable (relOid , reloptions , lockmode , true);
61
+ }
62
+
63
+ void
64
+ NewHeapCreateToastTable (Oid relOid , Datum reloptions , LOCKMODE lockmode )
65
+ {
66
+ CheckAndCreateToastTable (relOid , reloptions , lockmode , false);
67
+ }
68
+
69
+ void
70
+ NewRelationCreateToastTable (Oid relOid , Datum reloptions )
71
+ {
72
+ CheckAndCreateToastTable (relOid , reloptions , AccessExclusiveLock , false);
73
+ }
74
+
75
+ static void
76
+ CheckAndCreateToastTable (Oid relOid , Datum reloptions , LOCKMODE lockmode , bool check )
56
77
{
57
78
Relation rel ;
58
79
59
- /*
60
- * Grab an exclusive lock on the target table, since we'll update its
61
- * pg_class tuple. This is redundant for all present uses, since caller
62
- * will have such a lock already. But the lock is needed to ensure that
63
- * concurrent readers of the pg_class tuple won't have visibility issues,
64
- * so let's be safe.
65
- */
66
- rel = heap_open (relOid , AccessExclusiveLock );
80
+ rel = heap_open (relOid , lockmode );
67
81
68
82
/* create_toast_table does all the work */
69
- (void ) create_toast_table (rel , InvalidOid , InvalidOid , reloptions );
83
+ (void ) create_toast_table (rel , InvalidOid , InvalidOid , reloptions , lockmode , check );
70
84
71
85
heap_close (rel , NoLock );
72
86
}
@@ -91,7 +105,8 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid)
91
105
relName )));
92
106
93
107
/* create_toast_table does all the work */
94
- if (!create_toast_table (rel , toastOid , toastIndexOid , (Datum ) 0 ))
108
+ if (!create_toast_table (rel , toastOid , toastIndexOid , (Datum ) 0 ,
109
+ AccessExclusiveLock , false))
95
110
elog (ERROR , "\"%s\" does not require a toast table" ,
96
111
relName );
97
112
@@ -107,7 +122,8 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid)
107
122
* bootstrap they can be nonzero to specify hand-assigned OIDs
108
123
*/
109
124
static bool
110
- create_toast_table (Relation rel , Oid toastOid , Oid toastIndexOid , Datum reloptions )
125
+ create_toast_table (Relation rel , Oid toastOid , Oid toastIndexOid ,
126
+ Datum reloptions , LOCKMODE lockmode , bool check )
111
127
{
112
128
Oid relOid = RelationGetRelid (rel );
113
129
HeapTuple reltup ;
@@ -160,6 +176,13 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio
160
176
!OidIsValid (binary_upgrade_next_toast_pg_class_oid )))
161
177
return false;
162
178
179
+ /*
180
+ * If requested check lockmode is sufficient. This is a cross check
181
+ * in case of errors or conflicting decisions in earlier code.
182
+ */
183
+ if (check && lockmode != AccessExclusiveLock )
184
+ elog (ERROR , "AccessExclusiveLock required to add toast table." );
185
+
163
186
/*
164
187
* Create the toast table and its index
165
188
*/
0 commit comments