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

Commit 4676b30

Browse files
author
Thomas G. Lockhart
committed
Routines for database initial access info and support.
1 parent 8a7f79c commit 4676b30

File tree

1 file changed

+279
-0
lines changed

1 file changed

+279
-0
lines changed

src/backend/utils/misc/database.c

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* database.c--
4+
* miscellanious initialization support stuff
5+
*
6+
* Copyright (c) 1994, Regents of the University of California
7+
*
8+
*
9+
* IDENTIFICATION
10+
* $Header: /cvsroot/pgsql/src/backend/utils/misc/Attic/database.c,v 1.1 1997/11/07 07:05:46 thomas Exp $
11+
*
12+
*-------------------------------------------------------------------------
13+
*/
14+
#include <string.h>
15+
#include <stdlib.h>
16+
#include <stdio.h>
17+
#include <unistd.h>
18+
#include <fcntl.h>
19+
20+
#include "postgres.h"
21+
#include "miscadmin.h"
22+
23+
#include "utils/elog.h"
24+
#include "utils/builtins.h"
25+
#include "utils/syscache.h"
26+
27+
#include "access/heapam.h"
28+
#include "storage/bufmgr.h"
29+
#include "catalog/catname.h"
30+
#include "catalog/pg_proc.h"
31+
#include "catalog/pg_database.h"
32+
33+
#include "access/xact.h"
34+
#include "storage/bufpage.h"
35+
36+
/* GetDatabaseInfo()
37+
* Pull database information from pg_database.
38+
*/
39+
int
40+
GetDatabaseInfo(char *name, Oid *owner, char *path)
41+
{
42+
Oid dbowner,
43+
dbid;
44+
char dbpath[MAXPGPATH+1];
45+
text *dbtext;
46+
47+
Relation dbrel;
48+
HeapTuple dbtup;
49+
HeapTuple tup;
50+
Buffer buf;
51+
HeapScanDesc scan;
52+
ScanKeyData scanKey;
53+
54+
dbrel = heap_openr(DatabaseRelationName);
55+
if (!RelationIsValid(dbrel))
56+
elog(FATAL,"GetDatabaseInfo: cannot open relation \"%-.*s\"",
57+
DatabaseRelationName);
58+
59+
ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_database_datname,
60+
NameEqualRegProcedure, NameGetDatum(name));
61+
62+
scan = heap_beginscan(dbrel, 0, NowTimeQual, 1, &scanKey);
63+
if (!HeapScanIsValid(scan))
64+
elog(WARN, "GetDatabaseInfo: cannot begin scan of %s", DatabaseRelationName);
65+
66+
/*
67+
* Since we're going to close the relation, copy the tuple.
68+
*/
69+
tup = heap_getnext(scan, 0, &buf);
70+
71+
if (HeapTupleIsValid(tup))
72+
{
73+
dbtup = heap_copytuple(tup);
74+
ReleaseBuffer(buf);
75+
}
76+
else
77+
dbtup = tup;
78+
79+
heap_endscan(scan);
80+
81+
if (!HeapTupleIsValid(dbtup))
82+
{
83+
elog(NOTICE,"GetDatabaseInfo: %s entry not found %s",
84+
DatabaseRelationName,name);
85+
return TRUE;
86+
}
87+
88+
dbowner = (Oid) heap_getattr(dbtup, InvalidBuffer,
89+
Anum_pg_database_datdba,
90+
RelationGetTupleDescriptor(dbrel),
91+
(char *) NULL);
92+
dbid = dbtup->t_oid;
93+
94+
dbtext = (text *) heap_getattr(dbtup, InvalidBuffer,
95+
Anum_pg_database_datpath,
96+
RelationGetTupleDescriptor(dbrel),
97+
(char *) NULL);
98+
99+
memcpy(dbpath, VARDATA(dbtext), (VARSIZE(dbtext)-VARHDRSZ));
100+
*(dbpath+(VARSIZE(dbtext)-VARHDRSZ)) = '\0';
101+
102+
heap_close(dbrel);
103+
104+
owner = palloc(sizeof(Oid));
105+
*owner = dbowner;
106+
path = palloc(strlen(dbpath)+1);
107+
strcpy(path, dbpath);
108+
109+
return FALSE;
110+
} /* GetDatabaseInfo() */
111+
112+
char *
113+
ExpandDatabasePath(char *dbpath)
114+
{
115+
char *path;
116+
char *cp;
117+
char buf[MAXPGPATH+1];
118+
119+
/* leading path delimiter? then already absolute path */
120+
if (*dbpath == SEP_CHAR)
121+
{
122+
cp = strrchr(dbpath, SEP_CHAR);
123+
strncpy(buf,dbpath,(cp-dbpath));
124+
sprintf(&buf[cp-dbpath], "%cbase%c%s", SEP_CHAR, SEP_CHAR, (cp+1));
125+
}
126+
/* path delimiter somewhere? then has leading environment variable */
127+
else if (strchr(dbpath, SEP_CHAR) != NULL)
128+
{
129+
cp = strchr(dbpath, SEP_CHAR);
130+
strncpy(buf,dbpath,(cp-dbpath));
131+
buf[cp-dbpath] = '\0';
132+
path = getenv(buf);
133+
sprintf(buf, "%s%cbase%c%s", path, SEP_CHAR, SEP_CHAR, (cp+1));
134+
}
135+
/* no path delimiter? then add the default path prefixes */
136+
else
137+
{
138+
sprintf(buf, "%s%cbase%c%s", DataDir, SEP_CHAR, SEP_CHAR, dbpath);
139+
}
140+
141+
path = palloc(strlen(buf)+1);
142+
strcpy(path,buf);
143+
144+
return path;
145+
} /* ExpandDatabasePath() */
146+
147+
148+
/* --------------------------------
149+
* GetRawDatabaseInfo() -- Find the OID and path of the database.
150+
*
151+
* The database's oid forms half of the unique key for the system
152+
* caches and lock tables. We therefore want it initialized before
153+
* we open any relations, since opening relations puts things in the
154+
* cache. To get around this problem, this code opens and scans the
155+
* pg_database relation by hand.
156+
*
157+
* This algorithm relies on the fact that first attribute in the
158+
* pg_database relation schema is the database name. It also knows
159+
* about the internal format of tuples on disk and the length of
160+
* the datname attribute. It knows the location of the pg_database
161+
* file.
162+
* Actually, the code looks as though it is using the pg_database
163+
* tuple definition to locate the database name, so the above statement
164+
* seems to be no longer correct. - thomas 1997-11-01
165+
*
166+
* This code is called from InitPostgres(), before we chdir() to the
167+
* local database directory and before we open any relations.
168+
* Used to be called after the chdir(), but we now want to confirm
169+
* the location of the target database using pg_database info.
170+
* - thomas 1997-11-01
171+
* --------------------------------
172+
*/
173+
void
174+
GetRawDatabaseInfo(char *name, Oid *owner, Oid *db_id, char *path)
175+
{
176+
int dbfd;
177+
int fileflags;
178+
int nbytes;
179+
int max,
180+
i;
181+
HeapTuple tup;
182+
Page pg;
183+
PageHeader ph;
184+
char *dbfname;
185+
Form_pg_database tup_db;
186+
187+
dbfname = (char *) palloc(strlen(DataDir) + strlen("pg_database") + 2);
188+
sprintf(dbfname, "%s%cpg_database", DataDir, SEP_CHAR);
189+
fileflags = O_RDONLY;
190+
191+
if ((dbfd = open(dbfname, O_RDONLY, 0)) < 0)
192+
elog(FATAL, "Cannot open %s", dbfname);
193+
194+
pfree(dbfname);
195+
196+
/* ----------------
197+
* read and examine every page in pg_database
198+
*
199+
* Raw I/O! Read those tuples the hard way! Yow!
200+
*
201+
* Why don't we use the access methods or move this code
202+
* someplace else? This is really pg_database schema dependent
203+
* code. Perhaps it should go in lib/catalog/pg_database?
204+
* -cim 10/3/90
205+
*
206+
* mao replies 4 apr 91: yeah, maybe this should be moved to
207+
* lib/catalog. however, we CANNOT use the access methods since
208+
* those use the buffer cache, which uses the relation cache, which
209+
* requires that the dbid be set, which is what we're trying to do
210+
* here.
211+
* ----------------
212+
*/
213+
pg = (Page) palloc(BLCKSZ);
214+
ph = (PageHeader) pg;
215+
216+
while ((nbytes = read(dbfd, pg, BLCKSZ)) == BLCKSZ)
217+
{
218+
max = PageGetMaxOffsetNumber(pg);
219+
220+
/* look at each tuple on the page */
221+
for (i = 0; i <= max; i++)
222+
{
223+
int offset;
224+
225+
/* if it's a freed tuple, ignore it */
226+
if (!(ph->pd_linp[i].lp_flags & LP_USED))
227+
continue;
228+
229+
/* get a pointer to the tuple itself */
230+
offset = (int) ph->pd_linp[i].lp_off;
231+
tup = (HeapTuple) (((char *) pg) + offset);
232+
233+
/*
234+
* if the tuple has been deleted (the database was destroyed),
235+
* skip this tuple. XXX warning, will robinson: violation of
236+
* transaction semantics happens right here. we should check
237+
* to be sure that the xact that deleted this tuple actually
238+
* committed. only way to do this at init time is to paw over
239+
* the log relation by hand, too. let's be optimistic.
240+
*
241+
* XXX This is an evil type cast. tup->t_xmax is char[5] while
242+
* TransactionId is struct * { char data[5] }. It works but
243+
* if data is ever moved and no longer the first field this
244+
* will be broken!! -mer 11 Nov 1991.
245+
*/
246+
if (TransactionIdIsValid((TransactionId) tup->t_xmax))
247+
continue;
248+
249+
/*
250+
* Okay, see if this is the one we want. XXX 1 july 91: mao
251+
* and mer discover that tuples now squash t_bits. Why is
252+
* this?
253+
*
254+
* 24 july 92: mer realizes that the t_bits field is only used
255+
* in the event of null values. If no fields are null we
256+
* reduce the header size by doing the squash. t_hoff tells
257+
* you exactly how big the header actually is. use the PC
258+
* means of getting at sys cat attrs.
259+
*/
260+
tup_db = (Form_pg_database) GETSTRUCT(tup);
261+
262+
if (strncmp(name,
263+
&(tup_db->datname.data[0]),
264+
16) == 0)
265+
{
266+
*db_id = tup->t_oid;
267+
strncpy(path, VARDATA(&(tup_db->datpath)),
268+
(VARSIZE(&(tup_db->datpath))-VARHDRSZ));
269+
*(path+VARSIZE(&(tup_db->datpath))-VARHDRSZ) = '\0';
270+
271+
goto done;
272+
}
273+
}
274+
}
275+
276+
done:
277+
close(dbfd);
278+
pfree(pg);
279+
} /* GetRawDatabaseInfo() */

0 commit comments

Comments
 (0)