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.14 2002/04/27 03:45:00 tgl Exp $
18 *-------------------------------------------------------------------------
22 #include "access/heapam.h"
23 #include "access/xact.h"
24 #include "catalog/catalog.h"
25 #include "catalog/catname.h"
26 #include "catalog/heap.h"
27 #include "catalog/namespace.h"
28 #include "catalog/pg_inherits.h"
29 #include "catalog/pg_namespace.h"
30 #include "catalog/pg_opclass.h"
31 #include "catalog/pg_operator.h"
32 #include "catalog/pg_proc.h"
33 #include "catalog/pg_shadow.h"
34 #include "lib/stringinfo.h"
35 #include "miscadmin.h"
36 #include "nodes/makefuncs.h"
37 #include "storage/backendid.h"
38 #include "utils/acl.h"
39 #include "utils/builtins.h"
40 #include "utils/fmgroids.h"
41 #include "utils/guc.h"
42 #include "utils/catcache.h"
43 #include "utils/lsyscache.h"
44 #include "utils/syscache.h"
48 * The namespace search path is a possibly-empty list of namespace OIDs.
49 * In addition to the explicit list, the TEMP table namespace is always
50 * implicitly searched first (if it's been initialized). Also, the system
51 * catalog namespace is always searched. If the system namespace is
52 * explicitly present in the path then it will be searched in the specified
53 * order; otherwise it will be searched after TEMP tables and *before* the
54 * explicit list. (It might seem that the system namespace should be
55 * implicitly last, but this behavior appears to be required by SQL99.
56 * Also, this provides a way to search the system namespace first without
57 * thereby making it the default creation target namespace.)
59 * The default creation target namespace is kept equal to the first element
60 * of the (explicit) list. If the list is empty, there is no default target.
62 * In bootstrap mode, the search path is set equal to 'pg_catalog', so that
63 * the system namespace is the only one searched or inserted into.
64 * The initdb script is also careful to set search_path to 'pg_catalog' for
65 * its post-bootstrap standalone backend runs. Otherwise the default search
66 * path is determined by GUC. The factory default path contains the PUBLIC
67 * namespace (if it exists), preceded by the user's personal namespace
71 static List *namespaceSearchPath = NIL;
73 /* this flag must be updated correctly when namespaceSearchPath is changed */
74 static bool pathContainsSystemNamespace = false;
76 /* default place to create stuff; if InvalidOid, no default */
77 static Oid defaultCreationNamespace = InvalidOid;
80 * myTempNamespace is InvalidOid until and unless a TEMP namespace is set up
81 * in a particular backend session (this happens when a CREATE TEMP TABLE
82 * command is first executed). Thereafter it's the OID of the temp namespace.
84 static Oid myTempNamespace = InvalidOid;
87 * This is the text equivalent of the search path --- it's the value
88 * of the GUC variable 'search_path'.
90 char *namespace_search_path = NULL;
94 * Deletion ordering constraint item.
96 typedef struct DelConstraint
98 Oid referencer; /* table to delete first */
99 Oid referencee; /* table to delete second */
100 int pred; /* workspace for TopoSortRels */
101 struct DelConstraint *link; /* workspace for TopoSortRels */
105 /* Local functions */
106 static Oid GetTempTableNamespace(void);
107 static void RemoveTempRelations(Oid tempNamespaceId);
108 static List *FindTempRelations(Oid tempNamespaceId);
109 static List *FindDeletionConstraints(List *relOids);
110 static List *TopoSortRels(List *relOids, List *constraintList);
111 static void RemoveTempRelationsCallback(void);
116 * Given a RangeVar describing an existing relation,
117 * select the proper namespace and look up the relation OID.
119 * If the relation is not found, return InvalidOid if failOK = true,
120 * otherwise raise an error.
123 RangeVarGetRelid(const RangeVar *relation, bool failOK)
129 * We check the catalog name and then ignore it.
131 if (relation->catalogname)
133 if (strcmp(relation->catalogname, DatabaseName) != 0)
134 elog(ERROR, "Cross-database references are not implemented");
137 if (relation->schemaname)
139 /* use exact schema given */
140 namespaceId = GetSysCacheOid(NAMESPACENAME,
141 CStringGetDatum(relation->schemaname),
143 if (!OidIsValid(namespaceId))
144 elog(ERROR, "Namespace \"%s\" does not exist",
145 relation->schemaname);
146 relId = get_relname_relid(relation->relname, namespaceId);
150 /* search the namespace path */
151 relId = RelnameGetRelid(relation->relname);
154 if (!OidIsValid(relId) && !failOK)
156 if (relation->schemaname)
157 elog(ERROR, "Relation \"%s\".\"%s\" does not exist",
158 relation->schemaname, relation->relname);
160 elog(ERROR, "Relation \"%s\" does not exist",
167 * RangeVarGetCreationNamespace
168 * Given a RangeVar describing a to-be-created relation,
169 * choose which namespace to create it in.
171 * Note: calling this may result in a CommandCounterIncrement operation.
172 * That will happen on the first request for a temp table in any particular
173 * backend run; we will need to either create or clean out the temp schema.
176 RangeVarGetCreationNamespace(const RangeVar *newRelation)
181 * We check the catalog name and then ignore it.
183 if (newRelation->catalogname)
185 if (strcmp(newRelation->catalogname, DatabaseName) != 0)
186 elog(ERROR, "Cross-database references are not implemented");
189 if (newRelation->istemp)
191 /* TEMP tables are created in our backend-local temp namespace */
192 if (newRelation->schemaname)
193 elog(ERROR, "TEMP tables may not specify a namespace");
194 /* Initialize temp namespace if first time through */
195 if (!OidIsValid(myTempNamespace))
196 myTempNamespace = GetTempTableNamespace();
197 return myTempNamespace;
200 if (newRelation->schemaname)
202 /* use exact schema given */
203 namespaceId = GetSysCacheOid(NAMESPACENAME,
204 CStringGetDatum(newRelation->schemaname),
206 if (!OidIsValid(namespaceId))
207 elog(ERROR, "Namespace \"%s\" does not exist",
208 newRelation->schemaname);
212 /* use the default creation namespace */
213 namespaceId = defaultCreationNamespace;
214 if (!OidIsValid(namespaceId))
215 elog(ERROR, "No namespace has been selected to create in");
223 * Try to resolve an unqualified relation name.
224 * Returns OID if relation found in search path, else InvalidOid.
227 RelnameGetRelid(const char *relname)
233 * If a TEMP-table namespace has been set up, it is implicitly first
234 * in the search path.
236 if (OidIsValid(myTempNamespace))
238 relid = get_relname_relid(relname, myTempNamespace);
239 if (OidIsValid(relid))
244 * If system namespace is not in path, implicitly search it before path
246 if (!pathContainsSystemNamespace)
248 relid = get_relname_relid(relname, PG_CATALOG_NAMESPACE);
249 if (OidIsValid(relid))
254 * Else search the path
256 foreach(lptr, namespaceSearchPath)
258 Oid namespaceId = (Oid) lfirsti(lptr);
260 relid = get_relname_relid(relname, namespaceId);
261 if (OidIsValid(relid))
265 /* Not found in path */
271 * Try to resolve an unqualified datatype name.
272 * Returns OID if type found in search path, else InvalidOid.
274 * This is essentially the same as RelnameGetRelid, but we never search
275 * the TEMP table namespace --- there is no reason to refer to the types
276 * of temp tables, AFAICS.
279 TypenameGetTypid(const char *typname)
285 * If system namespace is not in path, implicitly search it before path
287 if (!pathContainsSystemNamespace)
289 typid = GetSysCacheOid(TYPENAMENSP,
290 PointerGetDatum(typname),
291 ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
293 if (OidIsValid(typid))
298 * Else search the path
300 foreach(lptr, namespaceSearchPath)
302 Oid namespaceId = (Oid) lfirsti(lptr);
304 typid = GetSysCacheOid(TYPENAMENSP,
305 PointerGetDatum(typname),
306 ObjectIdGetDatum(namespaceId),
308 if (OidIsValid(typid))
312 /* Not found in path */
317 * OpclassnameGetOpcid
318 * Try to resolve an unqualified index opclass name.
319 * Returns OID if opclass found in search path, else InvalidOid.
321 * This is essentially the same as TypenameGetTypid, but we have to have
322 * an extra argument for the index AM OID.
325 OpclassnameGetOpcid(Oid amid, const char *opcname)
331 * If system namespace is not in path, implicitly search it before path
333 if (!pathContainsSystemNamespace)
335 opcid = GetSysCacheOid(CLAAMNAMENSP,
336 ObjectIdGetDatum(amid),
337 PointerGetDatum(opcname),
338 ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
340 if (OidIsValid(opcid))
345 * Else search the path
347 foreach(lptr, namespaceSearchPath)
349 Oid namespaceId = (Oid) lfirsti(lptr);
351 opcid = GetSysCacheOid(CLAAMNAMENSP,
352 ObjectIdGetDatum(amid),
353 PointerGetDatum(opcname),
354 ObjectIdGetDatum(namespaceId),
356 if (OidIsValid(opcid))
360 /* Not found in path */
365 * FuncnameGetCandidates
366 * Given a possibly-qualified function name and argument count,
367 * retrieve a list of the possible matches.
369 * If nargs is -1, we return all functions matching the given name,
370 * regardless of argument count.
372 * We search a single namespace if the function name is qualified, else
373 * all namespaces in the search path. The return list will never contain
374 * multiple entries with identical argument lists --- in the multiple-
375 * namespace case, we arrange for entries in earlier namespaces to mask
376 * identical entries in later namespaces.
379 FuncnameGetCandidates(List *names, int nargs)
381 FuncCandidateList resultList = NULL;
383 char *schemaname = NULL;
384 char *funcname = NULL;
389 /* deconstruct the name list */
390 switch (length(names))
393 funcname = strVal(lfirst(names));
396 schemaname = strVal(lfirst(names));
397 funcname = strVal(lsecond(names));
400 catalogname = strVal(lfirst(names));
401 schemaname = strVal(lsecond(names));
402 funcname = strVal(lfirst(lnext(lnext(names))));
404 * We check the catalog name and then ignore it.
406 if (strcmp(catalogname, DatabaseName) != 0)
407 elog(ERROR, "Cross-database references are not implemented");
410 elog(ERROR, "Improper qualified name (too many dotted names)");
416 /* use exact schema given */
417 namespaceId = GetSysCacheOid(NAMESPACENAME,
418 CStringGetDatum(schemaname),
420 if (!OidIsValid(namespaceId))
421 elog(ERROR, "Namespace \"%s\" does not exist",
426 /* flag to indicate we need namespace search */
427 namespaceId = InvalidOid;
430 /* Search syscache by name and (optionally) nargs only */
432 catlist = SearchSysCacheList(PROCNAMENSP, 2,
433 CStringGetDatum(funcname),
434 Int16GetDatum(nargs),
437 catlist = SearchSysCacheList(PROCNAMENSP, 1,
438 CStringGetDatum(funcname),
441 for (i = 0; i < catlist->n_members; i++)
443 HeapTuple proctup = &catlist->members[i]->tuple;
444 Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
446 FuncCandidateList newResult;
448 nargs = procform->pronargs;
450 if (OidIsValid(namespaceId))
452 /* Consider only procs in specified namespace */
453 if (procform->pronamespace != namespaceId)
455 /* No need to check args, they must all be different */
459 /* Consider only procs that are in the search path */
460 if (pathContainsSystemNamespace ||
461 !IsSystemNamespace(procform->pronamespace))
465 foreach(nsp, namespaceSearchPath)
468 if (procform->pronamespace == (Oid) lfirsti(nsp))
472 continue; /* proc is not in search path */
476 * Okay, it's in the search path, but does it have the same
477 * arguments as something we already accepted? If so, keep
478 * only the one that appears earlier in the search path.
480 * If we have an ordered list from SearchSysCacheList (the
481 * normal case), then any conflicting proc must immediately
482 * adjoin this one in the list, so we only need to look at
483 * the newest result item. If we have an unordered list,
484 * we have to scan the whole result list.
488 FuncCandidateList prevResult;
490 if (catlist->ordered)
492 if (nargs == resultList->nargs &&
493 memcmp(procform->proargtypes, resultList->args,
494 nargs * sizeof(Oid)) == 0)
495 prevResult = resultList;
501 for (prevResult = resultList;
503 prevResult = prevResult->next)
505 if (nargs == prevResult->nargs &&
506 memcmp(procform->proargtypes, prevResult->args,
507 nargs * sizeof(Oid)) == 0)
513 /* We have a match with a previous result */
514 Assert(pathpos != prevResult->pathpos);
515 if (pathpos > prevResult->pathpos)
516 continue; /* keep previous result */
517 /* replace previous result */
518 prevResult->pathpos = pathpos;
519 prevResult->oid = proctup->t_data->t_oid;
520 continue; /* args are same, of course */
526 * Okay to add it to result list
528 newResult = (FuncCandidateList)
529 palloc(sizeof(struct _FuncCandidateList) - sizeof(Oid)
530 + nargs * sizeof(Oid));
531 newResult->pathpos = pathpos;
532 newResult->oid = proctup->t_data->t_oid;
533 newResult->nargs = nargs;
534 memcpy(newResult->args, procform->proargtypes, nargs * sizeof(Oid));
536 newResult->next = resultList;
537 resultList = newResult;
540 ReleaseSysCacheList(catlist);
546 * OpernameGetCandidates
547 * Given a possibly-qualified operator name and operator kind,
548 * retrieve a list of the possible matches.
550 * If oprkind is '\0', we return all operators matching the given name,
551 * regardless of arguments.
553 * We search a single namespace if the operator name is qualified, else
554 * all namespaces in the search path. The return list will never contain
555 * multiple entries with identical argument lists --- in the multiple-
556 * namespace case, we arrange for entries in earlier namespaces to mask
557 * identical entries in later namespaces.
559 * The returned items always have two args[] entries --- one or the other
560 * will be InvalidOid for a prefix or postfix oprkind. nargs is 2, too.
563 OpernameGetCandidates(List *names, char oprkind)
565 FuncCandidateList resultList = NULL;
567 char *schemaname = NULL;
568 char *opername = NULL;
573 /* deconstruct the name list */
574 switch (length(names))
577 opername = strVal(lfirst(names));
580 schemaname = strVal(lfirst(names));
581 opername = strVal(lsecond(names));
584 catalogname = strVal(lfirst(names));
585 schemaname = strVal(lsecond(names));
586 opername = strVal(lfirst(lnext(lnext(names))));
588 * We check the catalog name and then ignore it.
590 if (strcmp(catalogname, DatabaseName) != 0)
591 elog(ERROR, "Cross-database references are not implemented");
594 elog(ERROR, "Improper qualified name (too many dotted names)");
600 /* use exact schema given */
601 namespaceId = GetSysCacheOid(NAMESPACENAME,
602 CStringGetDatum(schemaname),
604 if (!OidIsValid(namespaceId))
605 elog(ERROR, "Namespace \"%s\" does not exist",
610 /* flag to indicate we need namespace search */
611 namespaceId = InvalidOid;
614 /* Search syscache by name only */
615 catlist = SearchSysCacheList(OPERNAMENSP, 1,
616 CStringGetDatum(opername),
619 for (i = 0; i < catlist->n_members; i++)
621 HeapTuple opertup = &catlist->members[i]->tuple;
622 Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
624 FuncCandidateList newResult;
626 /* Ignore operators of wrong kind, if specific kind requested */
627 if (oprkind && operform->oprkind != oprkind)
630 if (OidIsValid(namespaceId))
632 /* Consider only opers in specified namespace */
633 if (operform->oprnamespace != namespaceId)
635 /* No need to check args, they must all be different */
639 /* Consider only opers that are in the search path */
640 if (pathContainsSystemNamespace ||
641 !IsSystemNamespace(operform->oprnamespace))
645 foreach(nsp, namespaceSearchPath)
648 if (operform->oprnamespace == (Oid) lfirsti(nsp))
652 continue; /* oper is not in search path */
656 * Okay, it's in the search path, but does it have the same
657 * arguments as something we already accepted? If so, keep
658 * only the one that appears earlier in the search path.
660 * If we have an ordered list from SearchSysCacheList (the
661 * normal case), then any conflicting oper must immediately
662 * adjoin this one in the list, so we only need to look at
663 * the newest result item. If we have an unordered list,
664 * we have to scan the whole result list.
668 FuncCandidateList prevResult;
670 if (catlist->ordered)
672 if (operform->oprleft == resultList->args[0] &&
673 operform->oprright == resultList->args[1])
674 prevResult = resultList;
680 for (prevResult = resultList;
682 prevResult = prevResult->next)
684 if (operform->oprleft == prevResult->args[0] &&
685 operform->oprright == prevResult->args[1])
691 /* We have a match with a previous result */
692 Assert(pathpos != prevResult->pathpos);
693 if (pathpos > prevResult->pathpos)
694 continue; /* keep previous result */
695 /* replace previous result */
696 prevResult->pathpos = pathpos;
697 prevResult->oid = opertup->t_data->t_oid;
698 continue; /* args are same, of course */
704 * Okay to add it to result list
706 newResult = (FuncCandidateList)
707 palloc(sizeof(struct _FuncCandidateList) + sizeof(Oid));
708 newResult->pathpos = pathpos;
709 newResult->oid = opertup->t_data->t_oid;
710 newResult->nargs = 2;
711 newResult->args[0] = operform->oprleft;
712 newResult->args[1] = operform->oprright;
713 newResult->next = resultList;
714 resultList = newResult;
717 ReleaseSysCacheList(catlist);
723 * OpclassGetCandidates
724 * Given an index access method OID, retrieve a list of all the
725 * opclasses for that AM that are visible in the search path.
727 * NOTE: the opcname_tmp field in the returned structs should not be used
728 * by callers, because it points at syscache entries that we release at
729 * the end of this routine. If any callers needed the name information,
730 * we could pstrdup() the names ... but at present it'd be wasteful.
733 OpclassGetCandidates(Oid amid)
735 OpclassCandidateList resultList = NULL;
739 /* Search syscache by AM OID only */
740 catlist = SearchSysCacheList(CLAAMNAMENSP, 1,
741 ObjectIdGetDatum(amid),
744 for (i = 0; i < catlist->n_members; i++)
746 HeapTuple opctup = &catlist->members[i]->tuple;
747 Form_pg_opclass opcform = (Form_pg_opclass) GETSTRUCT(opctup);
749 OpclassCandidateList newResult;
751 /* Consider only opclasses that are in the search path */
752 if (pathContainsSystemNamespace ||
753 !IsSystemNamespace(opcform->opcnamespace))
757 foreach(nsp, namespaceSearchPath)
760 if (opcform->opcnamespace == (Oid) lfirsti(nsp))
764 continue; /* opclass is not in search path */
768 * Okay, it's in the search path, but does it have the same name
769 * as something we already accepted? If so, keep
770 * only the one that appears earlier in the search path.
772 * If we have an ordered list from SearchSysCacheList (the
773 * normal case), then any conflicting opclass must immediately
774 * adjoin this one in the list, so we only need to look at
775 * the newest result item. If we have an unordered list,
776 * we have to scan the whole result list.
780 OpclassCandidateList prevResult;
782 if (catlist->ordered)
784 if (strcmp(NameStr(opcform->opcname),
785 resultList->opcname_tmp) == 0)
786 prevResult = resultList;
792 for (prevResult = resultList;
794 prevResult = prevResult->next)
796 if (strcmp(NameStr(opcform->opcname),
797 prevResult->opcname_tmp) == 0)
803 /* We have a match with a previous result */
804 Assert(pathpos != prevResult->pathpos);
805 if (pathpos > prevResult->pathpos)
806 continue; /* keep previous result */
807 /* replace previous result */
808 prevResult->opcname_tmp = NameStr(opcform->opcname);
809 prevResult->pathpos = pathpos;
810 prevResult->oid = opctup->t_data->t_oid;
811 prevResult->opcintype = opcform->opcintype;
812 prevResult->opcdefault = opcform->opcdefault;
813 prevResult->opckeytype = opcform->opckeytype;
819 * Okay to add it to result list
821 newResult = (OpclassCandidateList)
822 palloc(sizeof(struct _OpclassCandidateList));
823 newResult->opcname_tmp = NameStr(opcform->opcname);
824 newResult->pathpos = pathpos;
825 newResult->oid = opctup->t_data->t_oid;
826 newResult->opcintype = opcform->opcintype;
827 newResult->opcdefault = opcform->opcdefault;
828 newResult->opckeytype = opcform->opckeytype;
829 newResult->next = resultList;
830 resultList = newResult;
833 ReleaseSysCacheList(catlist);
840 * QualifiedNameGetCreationNamespace
841 * Given a possibly-qualified name for an object (in List-of-Values
842 * format), determine what namespace the object should be created in.
843 * Also extract and return the object name (last component of list).
845 * This is *not* used for tables. Hence, the TEMP table namespace is
846 * never selected as the creation target.
849 QualifiedNameGetCreationNamespace(List *names, char **objname_p)
852 char *schemaname = NULL;
853 char *objname = NULL;
856 /* deconstruct the name list */
857 switch (length(names))
860 objname = strVal(lfirst(names));
863 schemaname = strVal(lfirst(names));
864 objname = strVal(lsecond(names));
867 catalogname = strVal(lfirst(names));
868 schemaname = strVal(lsecond(names));
869 objname = strVal(lfirst(lnext(lnext(names))));
871 * We check the catalog name and then ignore it.
873 if (strcmp(catalogname, DatabaseName) != 0)
874 elog(ERROR, "Cross-database references are not implemented");
877 elog(ERROR, "Improper qualified name (too many dotted names)");
883 /* use exact schema given */
884 namespaceId = GetSysCacheOid(NAMESPACENAME,
885 CStringGetDatum(schemaname),
887 if (!OidIsValid(namespaceId))
888 elog(ERROR, "Namespace \"%s\" does not exist",
893 /* use the default creation namespace */
894 namespaceId = defaultCreationNamespace;
895 if (!OidIsValid(namespaceId))
896 elog(ERROR, "No namespace has been selected to create in");
899 *objname_p = objname;
904 * makeRangeVarFromNameList
905 * Utility routine to convert a qualified-name list into RangeVar form.
908 makeRangeVarFromNameList(List *names)
910 RangeVar *rel = makeRangeVar(NULL, NULL);
912 switch (length(names))
915 rel->relname = strVal(lfirst(names));
918 rel->schemaname = strVal(lfirst(names));
919 rel->relname = strVal(lsecond(names));
922 rel->catalogname = strVal(lfirst(names));
923 rel->schemaname = strVal(lsecond(names));
924 rel->relname = strVal(lfirst(lnext(lnext(names))));
927 elog(ERROR, "Improper relation name (too many dotted names)");
936 * Utility routine to convert a qualified-name list into a string.
937 * Used primarily to form error messages.
940 NameListToString(List *names)
942 StringInfoData string;
945 initStringInfo(&string);
950 appendStringInfoChar(&string, '.');
951 appendStringInfo(&string, "%s", strVal(lfirst(l)));
958 * isTempNamespace - is the given namespace my temporary-table namespace?
961 isTempNamespace(Oid namespaceId)
963 if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
969 * GetTempTableNamespace
970 * Initialize temp table namespace on first use in a particular backend
973 GetTempTableNamespace(void)
975 char namespaceName[NAMEDATALEN];
979 * First, do permission check to see if we are authorized to make
980 * temp tables. We use a nonstandard error message here since
981 * "databasename: permission denied" might be a tad cryptic.
983 if (pg_database_aclcheck(MyDatabaseId, GetUserId(),
984 ACL_CREATE_TEMP) != ACLCHECK_OK)
985 elog(ERROR, "%s: not authorized to create temp tables",
988 snprintf(namespaceName, NAMEDATALEN, "pg_temp_%d", MyBackendId);
990 namespaceId = GetSysCacheOid(NAMESPACENAME,
991 CStringGetDatum(namespaceName),
993 if (!OidIsValid(namespaceId))
996 * First use of this temp namespace in this database; create it.
997 * The temp namespaces are always owned by the superuser.
999 namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_USESYSID);
1000 /* Advance command counter to make namespace visible */
1001 CommandCounterIncrement();
1006 * If the namespace already exists, clean it out (in case the
1007 * former owner crashed without doing so).
1009 RemoveTempRelations(namespaceId);
1013 * Register exit callback to clean out temp tables at backend shutdown.
1015 on_shmem_exit(RemoveTempRelationsCallback, 0);
1021 * Remove all relations in the specified temp namespace.
1023 * This is called at backend shutdown (if we made any temp relations).
1024 * It is also called when we begin using a pre-existing temp namespace,
1025 * in order to clean out any relations that might have been created by
1026 * a crashed backend.
1029 RemoveTempRelations(Oid tempNamespaceId)
1032 List *constraintList;
1035 /* Get a list of relations to delete */
1036 tempRelList = FindTempRelations(tempNamespaceId);
1038 if (tempRelList == NIL)
1039 return; /* nothing to do */
1041 /* If more than one, sort them to respect any deletion-order constraints */
1042 if (length(tempRelList) > 1)
1044 constraintList = FindDeletionConstraints(tempRelList);
1045 if (constraintList != NIL)
1046 tempRelList = TopoSortRels(tempRelList, constraintList);
1049 /* Scan the list and delete all entries */
1050 foreach(lptr, tempRelList)
1052 Oid reloid = (Oid) lfirsti(lptr);
1054 heap_drop_with_catalog(reloid, true);
1056 * Advance cmd counter to make catalog changes visible, in case
1057 * a later entry depends on this one.
1059 CommandCounterIncrement();
1064 * Find all relations in the specified temp namespace.
1066 * Returns a list of relation OIDs.
1069 FindTempRelations(Oid tempNamespaceId)
1071 List *tempRelList = NIL;
1078 * Scan pg_class to find all the relations in the target namespace.
1079 * Ignore indexes, though, on the assumption that they'll go away
1080 * when their tables are deleted.
1082 ScanKeyEntryInitialize(&key, 0x0,
1083 Anum_pg_class_relnamespace,
1085 ObjectIdGetDatum(tempNamespaceId));
1087 pgclass = heap_openr(RelationRelationName, AccessShareLock);
1088 scan = heap_beginscan(pgclass, false, SnapshotNow, 1, &key);
1090 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
1092 switch (((Form_pg_class) GETSTRUCT(tuple))->relkind)
1094 case RELKIND_RELATION:
1095 case RELKIND_SEQUENCE:
1097 tempRelList = lconsi(tuple->t_data->t_oid, tempRelList);
1105 heap_close(pgclass, AccessShareLock);
1111 * Find deletion-order constraints involving the given relation OIDs.
1113 * Returns a list of DelConstraint objects.
1116 FindDeletionConstraints(List *relOids)
1118 List *constraintList = NIL;
1119 Relation inheritsrel;
1124 * Scan pg_inherits to find parents and children that are in the list.
1126 inheritsrel = heap_openr(InheritsRelationName, AccessShareLock);
1127 scan = heap_beginscan(inheritsrel, 0, SnapshotNow, 0, NULL);
1129 while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
1131 Oid inhrelid = ((Form_pg_inherits) GETSTRUCT(tuple))->inhrelid;
1132 Oid inhparent = ((Form_pg_inherits) GETSTRUCT(tuple))->inhparent;
1134 if (intMember(inhrelid, relOids) && intMember(inhparent, relOids))
1136 DelConstraint *item;
1138 item = (DelConstraint *) palloc(sizeof(DelConstraint));
1139 item->referencer = inhrelid;
1140 item->referencee = inhparent;
1141 constraintList = lcons(item, constraintList);
1146 heap_close(inheritsrel, AccessShareLock);
1148 return constraintList;
1152 * TopoSortRels -- topological sort of a list of rels to delete
1154 * This is a lot simpler and slower than, for example, the topological sort
1155 * algorithm shown in Knuth's Volume 1. However, we are not likely to be
1156 * working with more than a few constraints, so the apparent slowness of the
1157 * algorithm won't really matter.
1160 TopoSortRels(List *relOids, List *constraintList)
1162 int queue_size = length(relOids);
1164 int *beforeConstraints;
1165 DelConstraint **afterConstraints;
1166 List *resultList = NIL;
1173 /* Allocate workspace */
1174 rels = (Oid *) palloc(queue_size * sizeof(Oid));
1175 beforeConstraints = (int *) palloc(queue_size * sizeof(int));
1176 afterConstraints = (DelConstraint **)
1177 palloc(queue_size * sizeof(DelConstraint*));
1179 /* Build an array of the target relation OIDs */
1181 foreach(lptr, relOids)
1183 rels[i++] = (Oid) lfirsti(lptr);
1187 * Scan the constraints, and for each rel in the array, generate a
1188 * count of the number of constraints that say it must be before
1189 * something else, plus a list of the constraints that say it must be
1190 * after something else. The count for the j'th rel is stored in
1191 * beforeConstraints[j], and the head of its list in
1192 * afterConstraints[j]. Each constraint stores its list link in
1193 * its link field (note any constraint will be in just one list).
1194 * The array index for the before-rel of each constraint is
1195 * remembered in the constraint's pred field.
1197 MemSet(beforeConstraints, 0, queue_size * sizeof(int));
1198 MemSet(afterConstraints, 0, queue_size * sizeof(DelConstraint*));
1199 foreach(lptr, constraintList)
1201 DelConstraint *constraint = (DelConstraint *) lfirst(lptr);
1204 /* Find the referencer rel in the array */
1205 rel = constraint->referencer;
1206 for (j = queue_size; --j >= 0;)
1211 Assert(j >= 0); /* should have found a match */
1212 /* Find the referencee rel in the array */
1213 rel = constraint->referencee;
1214 for (k = queue_size; --k >= 0;)
1219 Assert(k >= 0); /* should have found a match */
1220 beforeConstraints[j]++; /* referencer must come before */
1221 /* add this constraint to list of after-constraints for referencee */
1222 constraint->pred = j;
1223 constraint->link = afterConstraints[k];
1224 afterConstraints[k] = constraint;
1226 /*--------------------
1227 * Now scan the rels array backwards. At each step, output the
1228 * last rel that has no remaining before-constraints, and decrease
1229 * the beforeConstraints count of each of the rels it was constrained
1230 * against. (This is the right order since we are building the result
1231 * list back-to-front.)
1232 * i = counter for number of rels left to output
1233 * j = search index for rels[]
1234 * dc = temp for scanning constraint list for rel j
1235 * last = last valid index in rels (avoid redundant searches)
1236 *--------------------
1238 last = queue_size - 1;
1239 for (i = queue_size; --i >= 0;)
1243 /* Find next candidate to output */
1244 while (rels[last] == InvalidOid)
1246 for (j = last; j >= 0; j--)
1248 if (rels[j] != InvalidOid && beforeConstraints[j] == 0)
1251 /* If no available candidate, topological sort fails */
1253 elog(ERROR, "TopoSortRels: failed to find a workable deletion ordering");
1254 /* Output candidate, and mark it done by zeroing rels[] entry */
1255 resultList = lconsi(rels[j], resultList);
1256 rels[j] = InvalidOid;
1257 /* Update beforeConstraints counts of its predecessors */
1258 for (dc = afterConstraints[j]; dc; dc = dc->link)
1259 beforeConstraints[dc->pred]--;
1267 * Callback to remove temp relations at backend exit.
1270 RemoveTempRelationsCallback(void)
1272 if (OidIsValid(myTempNamespace)) /* should always be true */
1274 /* Need to ensure we have a usable transaction. */
1275 AbortOutOfAnyTransaction();
1276 StartTransactionCommand();
1278 RemoveTempRelations(myTempNamespace);
1280 CommitTransactionCommand();
1285 * Routines for handling the GUC variable 'search_path'.
1288 /* parse_hook: is proposed value valid? */
1290 check_search_path(const char *proposed)
1296 /* Need a modifiable copy of string */
1297 rawname = pstrdup(proposed);
1299 /* Parse string into list of identifiers */
1300 if (!SplitIdentifierString(rawname, ',', &namelist))
1302 /* syntax error in name list */
1309 * If we aren't inside a transaction, we cannot do database access so
1310 * cannot verify the individual names. Must accept the list on faith.
1311 * (This case can happen, for example, when the postmaster reads a
1312 * search_path setting from postgresql.conf.)
1314 if (!IsTransactionState())
1322 * Verify that all the names are either valid namespace names or "$user".
1323 * (We do not require $user to correspond to a valid namespace; should we?)
1325 foreach(l, namelist)
1327 char *curname = (char *) lfirst(l);
1329 if (strcmp(curname, "$user") == 0)
1331 if (!SearchSysCacheExists(NAMESPACENAME,
1332 CStringGetDatum(curname),
1347 /* assign_hook: do extra actions needed when assigning to search_path */
1349 assign_search_path(const char *newval)
1356 MemoryContext oldcxt;
1359 * If we aren't inside a transaction, we cannot do database access so
1360 * cannot look up the names. In this case, do nothing; the internal
1361 * search path will be fixed later by InitializeSearchPath. (We assume
1362 * this situation can only happen in the postmaster or early in backend
1365 if (!IsTransactionState())
1368 /* Need a modifiable copy of string */
1369 rawname = pstrdup(newval);
1371 /* Parse string into list of identifiers */
1372 if (!SplitIdentifierString(rawname, ',', &namelist))
1374 /* syntax error in name list */
1375 /* this should not happen if GUC checked check_search_path */
1376 elog(ERROR, "assign_search_path: invalid list syntax");
1380 * Convert the list of names to a list of OIDs. If any names are not
1381 * recognizable, just leave them out of the list. (This is our only
1382 * reasonable recourse when the already-accepted default is bogus.)
1385 foreach(l, namelist)
1387 char *curname = (char *) lfirst(l);
1390 if (strcmp(curname, "$user") == 0)
1392 /* $user --- substitute namespace matching user name, if any */
1395 tuple = SearchSysCache(SHADOWSYSID,
1396 ObjectIdGetDatum(GetSessionUserId()),
1398 if (HeapTupleIsValid(tuple))
1402 uname = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename);
1403 namespaceId = GetSysCacheOid(NAMESPACENAME,
1404 CStringGetDatum(uname),
1406 if (OidIsValid(namespaceId))
1407 oidlist = lappendi(oidlist, namespaceId);
1408 ReleaseSysCache(tuple);
1413 /* normal namespace reference */
1414 namespaceId = GetSysCacheOid(NAMESPACENAME,
1415 CStringGetDatum(curname),
1417 if (OidIsValid(namespaceId))
1418 oidlist = lappendi(oidlist, namespaceId);
1423 * Now that we've successfully built the new list of namespace OIDs,
1424 * save it in permanent storage.
1426 oldcxt = MemoryContextSwitchTo(TopMemoryContext);
1427 newpath = listCopy(oidlist);
1428 MemoryContextSwitchTo(oldcxt);
1430 /* Now safe to assign to state variable. */
1431 freeList(namespaceSearchPath);
1432 namespaceSearchPath = newpath;
1435 * Update info derived from search path.
1437 pathContainsSystemNamespace = intMember(PG_CATALOG_NAMESPACE,
1438 namespaceSearchPath);
1440 if (namespaceSearchPath == NIL)
1441 defaultCreationNamespace = InvalidOid;
1443 defaultCreationNamespace = (Oid) lfirsti(namespaceSearchPath);
1452 * InitializeSearchPath: initialize module during InitPostgres.
1454 * This is called after we are up enough to be able to do catalog lookups.
1457 InitializeSearchPath(void)
1459 if (IsBootstrapProcessingMode())
1462 * In bootstrap mode, the search path must be 'pg_catalog' so that
1463 * tables are created in the proper namespace; ignore the GUC setting.
1465 MemoryContext oldcxt;
1467 oldcxt = MemoryContextSwitchTo(TopMemoryContext);
1468 namespaceSearchPath = makeListi1(PG_CATALOG_NAMESPACE);
1469 MemoryContextSwitchTo(oldcxt);
1470 pathContainsSystemNamespace = true;
1471 defaultCreationNamespace = PG_CATALOG_NAMESPACE;
1476 * If a search path setting was provided before we were able to
1477 * execute lookups, establish the internal search path now.
1479 if (namespace_search_path && *namespace_search_path &&
1480 namespaceSearchPath == NIL)
1481 assign_search_path(namespace_search_path);
1486 * Fetch the active search path, expressed as a List of OIDs.
1488 * NB: caller must treat the list as read-only!
1491 fetch_search_path(void)
1493 return namespaceSearchPath;