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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy