1 /*-------------------------------------------------------------------------
4 * code to support accessing and searching namespaces
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.
12 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
13 * Portions Copyright (c) 1994, Regents of the University of California
16 * $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.3 2002/03/30 01:02:41 tgl Exp $
18 *-------------------------------------------------------------------------
22 #include "catalog/namespace.h"
23 #include "catalog/pg_namespace.h"
24 #include "miscadmin.h"
25 #include "nodes/makefuncs.h"
26 #include "utils/lsyscache.h"
27 #include "utils/syscache.h"
32 * Given a RangeVar describing an existing relation,
33 * select the proper namespace and look up the relation OID.
35 * If the relation is not found, return InvalidOid if failOK = true,
36 * otherwise raise an error.
39 RangeVarGetRelid(const RangeVar *relation, bool failOK)
45 * We check the catalog name and then ignore it.
47 if (relation->catalogname)
49 if (strcmp(relation->catalogname, DatabaseName) != 0)
50 elog(ERROR, "Cross-database references are not implemented");
53 if (relation->schemaname)
55 namespaceId = GetSysCacheOid(NAMESPACENAME,
56 CStringGetDatum(relation->schemaname),
58 if (!OidIsValid(namespaceId))
59 elog(ERROR, "Namespace \"%s\" does not exist",
60 relation->schemaname);
61 relId = get_relname_relid(relation->relname, namespaceId);
65 relId = RelnameGetRelid(relation->relname);
68 if (!OidIsValid(relId) && !failOK)
70 if (relation->schemaname)
71 elog(ERROR, "Relation \"%s\".\"%s\" does not exist",
72 relation->schemaname, relation->relname);
74 elog(ERROR, "Relation \"%s\" does not exist",
81 * RangeVarGetCreationNamespace
82 * Given a RangeVar describing a to-be-created relation,
83 * choose which namespace to create it in.
85 * Note: calling this may result in a CommandCounterIncrement operation.
86 * That will happen on the first request for a temp table in any particular
87 * backend run; we will need to either create or clean out the temp schema.
90 RangeVarGetCreationNamespace(const RangeVar *newRelation)
95 * We check the catalog name and then ignore it.
97 if (newRelation->catalogname)
99 if (strcmp(newRelation->catalogname, DatabaseName) != 0)
100 elog(ERROR, "Cross-database references are not implemented");
103 if (newRelation->schemaname)
105 namespaceId = GetSysCacheOid(NAMESPACENAME,
106 CStringGetDatum(newRelation->schemaname),
108 if (!OidIsValid(namespaceId))
109 elog(ERROR, "Namespace \"%s\" does not exist",
110 newRelation->schemaname);
114 /* XXX Wrong! Need to get a default schema from somewhere */
115 namespaceId = PG_CATALOG_NAMESPACE;
123 * Try to resolve an unqualified relation name.
124 * Returns OID if relation found in search path, else InvalidOid.
127 RelnameGetRelid(const char *relname)
129 /* XXX Wrong! must search search path */
130 return get_relname_relid(relname, PG_CATALOG_NAMESPACE);
135 * Try to resolve an unqualified datatype name.
136 * Returns OID if type found in search path, else InvalidOid.
139 TypenameGetTypid(const char *typname)
141 /* XXX wrong, should use namespace search */
142 return GetSysCacheOid(TYPENAMENSP,
143 PointerGetDatum(typname),
144 ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
149 * QualifiedNameGetCreationNamespace
150 * Given a possibly-qualified name for an object (in List-of-Values
151 * format), determine what namespace the object should be created in.
152 * Also extract and return the object name (last component of list).
155 QualifiedNameGetCreationNamespace(List *names, char **objname_p)
158 char *schemaname = NULL;
159 char *objname = NULL;
162 /* deconstruct the name list */
163 switch (length(names))
166 objname = strVal(lfirst(names));
169 schemaname = strVal(lfirst(names));
170 objname = strVal(lsecond(names));
173 catalogname = strVal(lfirst(names));
174 schemaname = strVal(lsecond(names));
175 objname = strVal(lfirst(lnext(lnext(names))));
177 * We check the catalog name and then ignore it.
179 if (strcmp(catalogname, DatabaseName) != 0)
180 elog(ERROR, "Cross-database references are not implemented");
183 elog(ERROR, "Improper qualified name (too many dotted names)");
189 namespaceId = GetSysCacheOid(NAMESPACENAME,
190 CStringGetDatum(schemaname),
192 if (!OidIsValid(namespaceId))
193 elog(ERROR, "Namespace \"%s\" does not exist",
198 /* XXX Wrong! Need to get a default schema from somewhere */
199 namespaceId = PG_CATALOG_NAMESPACE;
202 *objname_p = objname;
207 * makeRangeVarFromNameList
208 * Utility routine to convert a qualified-name list into RangeVar form.
211 makeRangeVarFromNameList(List *names)
213 RangeVar *rel = makeRangeVar(NULL, NULL);
215 switch (length(names))
218 rel->relname = strVal(lfirst(names));
221 rel->schemaname = strVal(lfirst(names));
222 rel->relname = strVal(lsecond(names));
225 rel->catalogname = strVal(lfirst(names));
226 rel->schemaname = strVal(lsecond(names));
227 rel->relname = strVal(lfirst(lnext(lnext(names))));
230 elog(ERROR, "Improper relation name (too many dotted names)");