]> granicus.if.org Git - postgresql/blob - src/backend/catalog/namespace.c
pg_class has a relnamespace column. You can create and access tables
[postgresql] / src / backend / catalog / namespace.c
1 /*-------------------------------------------------------------------------
2  *
3  * namespace.c
4  *        code to support accessing and searching namespaces
5  *
6  * This is separate from pg_namespace.c, which contains the routines that
7  * directly manipulate the pg_namespace system catalog.  This module
8  * provides routines associated with defining a "namespace search path"
9  * and implementing search-path-controlled searches.
10  *
11  *
12  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
13  * Portions Copyright (c) 1994, Regents of the University of California
14  *
15  * IDENTIFICATION
16  *        $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.1 2002/03/26 19:15:32 tgl Exp $
17  *
18  *-------------------------------------------------------------------------
19  */
20 #include "postgres.h"
21
22 #include "catalog/namespace.h"
23 #include "catalog/pg_namespace.h"
24 #include "miscadmin.h"
25 #include "utils/lsyscache.h"
26 #include "utils/syscache.h"
27
28
29 /*
30  * RangeVarGetRelid
31  *              Given a RangeVar describing an existing relation,
32  *              select the proper namespace and look up the relation OID.
33  *
34  * If the relation is not found, return InvalidOid if failOK = true,
35  * otherwise raise an error.
36  */
37 Oid
38 RangeVarGetRelid(const RangeVar *relation, bool failOK)
39 {
40         Oid                     namespaceId;
41         Oid                     relId;
42
43         /*
44          * We check the catalog name and then ignore it.
45          */
46         if (relation->catalogname)
47         {
48                 if (strcmp(relation->catalogname, DatabaseName) != 0)
49                         elog(ERROR, "Cross-database references are not implemented");
50         }
51
52         if (relation->schemaname)
53         {
54                 namespaceId = GetSysCacheOid(NAMESPACENAME,
55                                                                          CStringGetDatum(relation->schemaname),
56                                                                          0, 0, 0);
57                 if (!OidIsValid(namespaceId))
58                         elog(ERROR, "Namespace \"%s\" does not exist",
59                                  relation->schemaname);
60                 relId = get_relname_relid(relation->relname, namespaceId);
61         }
62         else
63         {
64                 relId = RelnameGetRelid(relation->relname);
65         }
66
67         if (!OidIsValid(relId) && !failOK)
68         {
69                 if (relation->schemaname)
70                         elog(ERROR, "Relation \"%s\".\"%s\" does not exist",
71                                  relation->schemaname, relation->relname);
72                 else
73                         elog(ERROR, "Relation \"%s\" does not exist",
74                                  relation->relname);
75         }
76         return relId;
77 }
78
79 /*
80  * RangeVarGetCreationNamespace
81  *              Given a RangeVar describing a to-be-created relation,
82  *              choose which namespace to create it in.
83  */
84 Oid
85 RangeVarGetCreationNamespace(const RangeVar *newRelation)
86 {
87         Oid                     namespaceId;
88
89         /*
90          * We check the catalog name and then ignore it.
91          */
92         if (newRelation->catalogname)
93         {
94                 if (strcmp(newRelation->catalogname, DatabaseName) != 0)
95                         elog(ERROR, "Cross-database references are not implemented");
96         }
97
98         if (newRelation->schemaname)
99         {
100                 namespaceId = GetSysCacheOid(NAMESPACENAME,
101                                                                          CStringGetDatum(newRelation->schemaname),
102                                                                          0, 0, 0);
103                 if (!OidIsValid(namespaceId))
104                         elog(ERROR, "Namespace \"%s\" does not exist",
105                                  newRelation->schemaname);
106         }
107         else
108         {
109                 /* XXX Wrong!  Need to get a default schema from somewhere */
110                 namespaceId = PG_CATALOG_NAMESPACE;
111         }
112
113         return namespaceId;
114 }
115
116 /*
117  * RelnameGetRelid
118  *              Try to resolve an unqualified relation name.
119  *              Returns OID if relation found in search path, else InvalidOid.
120  */
121 Oid
122 RelnameGetRelid(const char *relname)
123 {
124         /* XXX Wrong!  must search search path */
125         return get_relname_relid(relname, PG_CATALOG_NAMESPACE);
126 }