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)
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