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

Commit 9261b19

Browse files
committed
Fix spccache.c to not suppose that a cache entry will live across database
access, per testing with CLOBBER_CACHE_ALWAYS. Minor other editorialization.
1 parent 64b9c85 commit 9261b19

File tree

1 file changed

+47
-28
lines changed

1 file changed

+47
-28
lines changed

src/backend/utils/cache/spccache.c

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
* Portions Copyright (c) 1994, Regents of the University of California
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/backend/utils/cache/spccache.c,v 1.2 2010/01/06 22:27:09 tgl Exp $
15+
* $PostgreSQL: pgsql/src/backend/utils/cache/spccache.c,v 1.3 2010/01/06 23:00:02 tgl Exp $
1616
*
1717
*-------------------------------------------------------------------------
1818
*/
19-
2019
#include "postgres.h"
20+
2121
#include "access/reloptions.h"
2222
#include "catalog/pg_tablespace.h"
2323
#include "commands/tablespace.h"
@@ -29,12 +29,16 @@
2929
#include "utils/spccache.h"
3030
#include "utils/syscache.h"
3131

32+
33+
/* Hash table for information about each tablespace */
3234
static HTAB *TableSpaceCacheHash = NULL;
3335

34-
typedef struct {
35-
Oid oid;
36-
TableSpaceOpts *opts;
37-
} TableSpace;
36+
typedef struct
37+
{
38+
Oid oid; /* lookup key - must be first */
39+
TableSpaceOpts *opts; /* options, or NULL if none */
40+
} TableSpaceCacheEntry;
41+
3842

3943
/*
4044
* InvalidateTableSpaceCacheCallback
@@ -49,10 +53,10 @@ static void
4953
InvalidateTableSpaceCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
5054
{
5155
HASH_SEQ_STATUS status;
52-
TableSpace *spc;
56+
TableSpaceCacheEntry *spc;
5357

5458
hash_seq_init(&status, TableSpaceCacheHash);
55-
while ((spc = (TableSpace *) hash_seq_search(&status)) != NULL)
59+
while ((spc = (TableSpaceCacheEntry *) hash_seq_search(&status)) != NULL)
5660
{
5761
if (spc->opts)
5862
pfree(spc->opts);
@@ -66,7 +70,7 @@ InvalidateTableSpaceCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
6670

6771
/*
6872
* InitializeTableSpaceCache
69-
* Initiate the tablespace cache.
73+
* Initialize the tablespace cache.
7074
*/
7175
static void
7276
InitializeTableSpaceCache(void)
@@ -76,8 +80,8 @@ InitializeTableSpaceCache(void)
7680
/* Initialize the hash table. */
7781
MemSet(&ctl, 0, sizeof(ctl));
7882
ctl.keysize = sizeof(Oid);
79-
ctl.entrysize = sizeof(TableSpace);
80-
ctl.hash = tag_hash;
83+
ctl.entrysize = sizeof(TableSpaceCacheEntry);
84+
ctl.hash = oid_hash;
8185
TableSpaceCacheHash =
8286
hash_create("TableSpace cache", 16, &ctl,
8387
HASH_ELEM | HASH_FUNCTION);
@@ -94,17 +98,17 @@ InitializeTableSpaceCache(void)
9498

9599
/*
96100
* get_tablespace
97-
* Fetch TableSpace structure for a specified table OID.
101+
* Fetch TableSpaceCacheEntry structure for a specified table OID.
98102
*
99103
* Pointers returned by this function should not be stored, since a cache
100104
* flush will invalidate them.
101105
*/
102-
static TableSpace *
106+
static TableSpaceCacheEntry *
103107
get_tablespace(Oid spcid)
104108
{
109+
TableSpaceCacheEntry *spc;
105110
HeapTuple tp;
106-
TableSpace *spc;
107-
bool found;
111+
TableSpaceOpts *opts;
108112

109113
/*
110114
* Since spcid is always from a pg_class tuple, InvalidOid implies the
@@ -113,12 +117,14 @@ get_tablespace(Oid spcid)
113117
if (spcid == InvalidOid)
114118
spcid = MyDatabaseTableSpace;
115119

116-
/* Find existing cache entry, or create a new one. */
120+
/* Find existing cache entry, if any. */
117121
if (!TableSpaceCacheHash)
118122
InitializeTableSpaceCache();
119-
spc = (TableSpace *) hash_search(TableSpaceCacheHash, (void *) &spcid,
120-
HASH_ENTER, &found);
121-
if (found)
123+
spc = (TableSpaceCacheEntry *) hash_search(TableSpaceCacheHash,
124+
(void *) &spcid,
125+
HASH_FIND,
126+
NULL);
127+
if (spc)
122128
return spc;
123129

124130
/*
@@ -127,9 +133,11 @@ get_tablespace(Oid spcid)
127133
* details for a non-existent tablespace. We'll just treat that case as if
128134
* no options were specified.
129135
*/
130-
tp = SearchSysCache(TABLESPACEOID, ObjectIdGetDatum(spcid), 0, 0, 0);
136+
tp = SearchSysCache(TABLESPACEOID,
137+
ObjectIdGetDatum(spcid),
138+
0, 0, 0);
131139
if (!HeapTupleIsValid(tp))
132-
spc->opts = NULL;
140+
opts = NULL;
133141
else
134142
{
135143
Datum datum;
@@ -141,29 +149,40 @@ get_tablespace(Oid spcid)
141149
Anum_pg_tablespace_spcoptions,
142150
&isNull);
143151
if (isNull)
144-
spc->opts = NULL;
152+
opts = NULL;
145153
else
146154
{
155+
/* XXX should NOT do the parsing work in CacheMemoryContext */
147156
octx = MemoryContextSwitchTo(CacheMemoryContext);
148-
spc->opts = (TableSpaceOpts *) tablespace_reloptions(datum, false);
157+
opts = (TableSpaceOpts *) tablespace_reloptions(datum, false);
149158
MemoryContextSwitchTo(octx);
150159
}
151160
ReleaseSysCache(tp);
152161
}
153162

154-
/* Update new TableSpace cache entry with results of option parsing. */
163+
/*
164+
* Now create the cache entry. It's important to do this only after
165+
* reading the pg_tablespace entry, since doing so could cause a cache
166+
* flush.
167+
*/
168+
spc = (TableSpaceCacheEntry *) hash_search(TableSpaceCacheHash,
169+
(void *) &spcid,
170+
HASH_ENTER,
171+
NULL);
172+
spc->opts = opts;
155173
return spc;
156174
}
157175

158176
/*
159177
* get_tablespace_page_costs
160-
* Return random and sequential page costs for a given tablespace.
178+
* Return random and/or sequential page costs for a given tablespace.
161179
*/
162180
void
163-
get_tablespace_page_costs(Oid spcid, double *spc_random_page_cost,
164-
double *spc_seq_page_cost)
181+
get_tablespace_page_costs(Oid spcid,
182+
double *spc_random_page_cost,
183+
double *spc_seq_page_cost)
165184
{
166-
TableSpace *spc = get_tablespace(spcid);
185+
TableSpaceCacheEntry *spc = get_tablespace(spcid);
167186

168187
Assert(spc != NULL);
169188

0 commit comments

Comments
 (0)