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-2006, PostgreSQL Global Development Group
13 * Portions Copyright (c) 1994, Regents of the University of California
16 * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.89 2006/12/23 00:43:09 tgl Exp $
18 *-------------------------------------------------------------------------
22 #include "access/xact.h"
23 #include "catalog/dependency.h"
24 #include "catalog/namespace.h"
25 #include "catalog/pg_authid.h"
26 #include "catalog/pg_conversion.h"
27 #include "catalog/pg_namespace.h"
28 #include "catalog/pg_opclass.h"
29 #include "catalog/pg_operator.h"
30 #include "catalog/pg_opfamily.h"
31 #include "catalog/pg_proc.h"
32 #include "catalog/pg_type.h"
33 #include "commands/dbcommands.h"
34 #include "miscadmin.h"
35 #include "nodes/makefuncs.h"
36 #include "storage/backendid.h"
37 #include "storage/ipc.h"
38 #include "utils/acl.h"
39 #include "utils/builtins.h"
40 #include "utils/guc.h"
41 #include "utils/inval.h"
42 #include "utils/lsyscache.h"
43 #include "utils/memutils.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, several implicitly-searched namespaces
52 * 1. If a "special" namespace has been set by PushSpecialNamespace, it is
53 * always searched first. (This is a hack for CREATE SCHEMA.)
55 * 2. If a TEMP table namespace has been initialized in this session, it
56 * is always searched just after any special namespace.
58 * 3. The system catalog namespace is always searched. If the system
59 * namespace is present in the explicit path then it will be searched in
60 * the specified order; otherwise it will be searched after TEMP tables and
61 * *before* the explicit list. (It might seem that the system namespace
62 * should be implicitly last, but this behavior appears to be required by
63 * SQL99. Also, this provides a way to search the system namespace first
64 * without thereby making it the default creation target namespace.)
66 * The default creation target namespace is normally equal to the first
67 * element of the explicit list, but is the "special" namespace when one
68 * has been set. If the explicit list is empty and there is no special
69 * namespace, there is no default target.
71 * In bootstrap mode, the search path is set equal to 'pg_catalog', so that
72 * the system namespace is the only one searched or inserted into.
73 * The initdb script is also careful to set search_path to 'pg_catalog' for
74 * its post-bootstrap standalone backend runs. Otherwise the default search
75 * path is determined by GUC. The factory default path contains the PUBLIC
76 * namespace (if it exists), preceded by the user's personal namespace
79 * If namespaceSearchPathValid is false, then namespaceSearchPath (and other
80 * derived variables) need to be recomputed from namespace_search_path.
81 * We mark it invalid upon an assignment to namespace_search_path or receipt
82 * of a syscache invalidation event for pg_namespace. The recomputation
83 * is done during the next lookup attempt.
85 * Any namespaces mentioned in namespace_search_path that are not readable
86 * by the current user ID are simply left out of namespaceSearchPath; so
87 * we have to be willing to recompute the path when current userid changes.
88 * namespaceUser is the userid the path has been computed for.
91 static List *namespaceSearchPath = NIL;
93 static Oid namespaceUser = InvalidOid;
95 /* default place to create stuff; if InvalidOid, no default */
96 static Oid defaultCreationNamespace = InvalidOid;
98 /* first explicit member of list; usually same as defaultCreationNamespace */
99 static Oid firstExplicitNamespace = InvalidOid;
101 /* The above four values are valid only if namespaceSearchPathValid */
102 static bool namespaceSearchPathValid = true;
105 * myTempNamespace is InvalidOid until and unless a TEMP namespace is set up
106 * in a particular backend session (this happens when a CREATE TEMP TABLE
107 * command is first executed). Thereafter it's the OID of the temp namespace.
109 * myTempNamespaceSubID shows whether we've created the TEMP namespace in the
110 * current subtransaction. The flag propagates up the subtransaction tree,
111 * so the main transaction will correctly recognize the flag if all
112 * intermediate subtransactions commit. When it is InvalidSubTransactionId,
113 * we either haven't made the TEMP namespace yet, or have successfully
114 * committed its creation, depending on whether myTempNamespace is valid.
116 static Oid myTempNamespace = InvalidOid;
118 static SubTransactionId myTempNamespaceSubID = InvalidSubTransactionId;
121 * "Special" namespace for CREATE SCHEMA. If set, it's the first search
122 * path element, and also the default creation namespace.
124 static Oid mySpecialNamespace = InvalidOid;
127 * This is the text equivalent of the search path --- it's the value
128 * of the GUC variable 'search_path'.
130 char *namespace_search_path = NULL;
133 /* Local functions */
134 static void recomputeNamespacePath(void);
135 static void InitTempTableNamespace(void);
136 static void RemoveTempRelations(Oid tempNamespaceId);
137 static void RemoveTempRelationsCallback(int code, Datum arg);
138 static void NamespaceCallback(Datum arg, Oid relid);
140 /* These don't really need to appear in any header file */
141 Datum pg_table_is_visible(PG_FUNCTION_ARGS);
142 Datum pg_type_is_visible(PG_FUNCTION_ARGS);
143 Datum pg_function_is_visible(PG_FUNCTION_ARGS);
144 Datum pg_operator_is_visible(PG_FUNCTION_ARGS);
145 Datum pg_opclass_is_visible(PG_FUNCTION_ARGS);
146 Datum pg_conversion_is_visible(PG_FUNCTION_ARGS);
147 Datum pg_my_temp_schema(PG_FUNCTION_ARGS);
148 Datum pg_is_other_temp_schema(PG_FUNCTION_ARGS);
153 * Given a RangeVar describing an existing relation,
154 * select the proper namespace and look up the relation OID.
156 * If the relation is not found, return InvalidOid if failOK = true,
157 * otherwise raise an error.
160 RangeVarGetRelid(const RangeVar *relation, bool failOK)
166 * We check the catalog name and then ignore it.
168 if (relation->catalogname)
170 if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
172 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
173 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
174 relation->catalogname, relation->schemaname,
175 relation->relname)));
178 if (relation->schemaname)
180 /* use exact schema given */
181 namespaceId = LookupExplicitNamespace(relation->schemaname);
182 relId = get_relname_relid(relation->relname, namespaceId);
186 /* search the namespace path */
187 relId = RelnameGetRelid(relation->relname);
190 if (!OidIsValid(relId) && !failOK)
192 if (relation->schemaname)
194 (errcode(ERRCODE_UNDEFINED_TABLE),
195 errmsg("relation \"%s.%s\" does not exist",
196 relation->schemaname, relation->relname)));
199 (errcode(ERRCODE_UNDEFINED_TABLE),
200 errmsg("relation \"%s\" does not exist",
201 relation->relname)));
207 * RangeVarGetCreationNamespace
208 * Given a RangeVar describing a to-be-created relation,
209 * choose which namespace to create it in.
211 * Note: calling this may result in a CommandCounterIncrement operation.
212 * That will happen on the first request for a temp table in any particular
213 * backend run; we will need to either create or clean out the temp schema.
216 RangeVarGetCreationNamespace(const RangeVar *newRelation)
221 * We check the catalog name and then ignore it.
223 if (newRelation->catalogname)
225 if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
227 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
228 errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
229 newRelation->catalogname, newRelation->schemaname,
230 newRelation->relname)));
233 if (newRelation->istemp)
235 /* TEMP tables are created in our backend-local temp namespace */
236 if (newRelation->schemaname)
238 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
239 errmsg("temporary tables may not specify a schema name")));
240 /* Initialize temp namespace if first time through */
241 if (!OidIsValid(myTempNamespace))
242 InitTempTableNamespace();
243 return myTempNamespace;
246 if (newRelation->schemaname)
248 /* use exact schema given */
249 namespaceId = GetSysCacheOid(NAMESPACENAME,
250 CStringGetDatum(newRelation->schemaname),
252 if (!OidIsValid(namespaceId))
254 (errcode(ERRCODE_UNDEFINED_SCHEMA),
255 errmsg("schema \"%s\" does not exist",
256 newRelation->schemaname)));
257 /* we do not check for USAGE rights here! */
261 /* use the default creation namespace */
262 recomputeNamespacePath();
263 namespaceId = defaultCreationNamespace;
264 if (!OidIsValid(namespaceId))
266 (errcode(ERRCODE_UNDEFINED_SCHEMA),
267 errmsg("no schema has been selected to create in")));
270 /* Note: callers will check for CREATE rights when appropriate */
277 * Try to resolve an unqualified relation name.
278 * Returns OID if relation found in search path, else InvalidOid.
281 RelnameGetRelid(const char *relname)
286 recomputeNamespacePath();
288 foreach(l, namespaceSearchPath)
290 Oid namespaceId = lfirst_oid(l);
292 relid = get_relname_relid(relname, namespaceId);
293 if (OidIsValid(relid))
297 /* Not found in path */
304 * Determine whether a relation (identified by OID) is visible in the
305 * current search path. Visible means "would be found by searching
306 * for the unqualified relation name".
309 RelationIsVisible(Oid relid)
312 Form_pg_class relform;
316 reltup = SearchSysCache(RELOID,
317 ObjectIdGetDatum(relid),
319 if (!HeapTupleIsValid(reltup))
320 elog(ERROR, "cache lookup failed for relation %u", relid);
321 relform = (Form_pg_class) GETSTRUCT(reltup);
323 recomputeNamespacePath();
326 * Quick check: if it ain't in the path at all, it ain't visible. Items in
327 * the system namespace are surely in the path and so we needn't even do
328 * list_member_oid() for them.
330 relnamespace = relform->relnamespace;
331 if (relnamespace != PG_CATALOG_NAMESPACE &&
332 !list_member_oid(namespaceSearchPath, relnamespace))
337 * If it is in the path, it might still not be visible; it could be
338 * hidden by another relation of the same name earlier in the path. So
339 * we must do a slow check for conflicting relations.
341 char *relname = NameStr(relform->relname);
345 foreach(l, namespaceSearchPath)
347 Oid namespaceId = lfirst_oid(l);
349 if (namespaceId == relnamespace)
351 /* Found it first in path */
355 if (OidIsValid(get_relname_relid(relname, namespaceId)))
357 /* Found something else first in path */
363 ReleaseSysCache(reltup);
371 * Try to resolve an unqualified datatype name.
372 * Returns OID if type found in search path, else InvalidOid.
374 * This is essentially the same as RelnameGetRelid.
377 TypenameGetTypid(const char *typname)
382 recomputeNamespacePath();
384 foreach(l, namespaceSearchPath)
386 Oid namespaceId = lfirst_oid(l);
388 typid = GetSysCacheOid(TYPENAMENSP,
389 PointerGetDatum(typname),
390 ObjectIdGetDatum(namespaceId),
392 if (OidIsValid(typid))
396 /* Not found in path */
402 * Determine whether a type (identified by OID) is visible in the
403 * current search path. Visible means "would be found by searching
404 * for the unqualified type name".
407 TypeIsVisible(Oid typid)
410 Form_pg_type typform;
414 typtup = SearchSysCache(TYPEOID,
415 ObjectIdGetDatum(typid),
417 if (!HeapTupleIsValid(typtup))
418 elog(ERROR, "cache lookup failed for type %u", typid);
419 typform = (Form_pg_type) GETSTRUCT(typtup);
421 recomputeNamespacePath();
424 * Quick check: if it ain't in the path at all, it ain't visible. Items in
425 * the system namespace are surely in the path and so we needn't even do
426 * list_member_oid() for them.
428 typnamespace = typform->typnamespace;
429 if (typnamespace != PG_CATALOG_NAMESPACE &&
430 !list_member_oid(namespaceSearchPath, typnamespace))
435 * If it is in the path, it might still not be visible; it could be
436 * hidden by another type of the same name earlier in the path. So we
437 * must do a slow check for conflicting types.
439 char *typname = NameStr(typform->typname);
443 foreach(l, namespaceSearchPath)
445 Oid namespaceId = lfirst_oid(l);
447 if (namespaceId == typnamespace)
449 /* Found it first in path */
453 if (SearchSysCacheExists(TYPENAMENSP,
454 PointerGetDatum(typname),
455 ObjectIdGetDatum(namespaceId),
458 /* Found something else first in path */
464 ReleaseSysCache(typtup);
471 * FuncnameGetCandidates
472 * Given a possibly-qualified function name and argument count,
473 * retrieve a list of the possible matches.
475 * If nargs is -1, we return all functions matching the given name,
476 * regardless of argument count.
478 * We search a single namespace if the function name is qualified, else
479 * all namespaces in the search path. The return list will never contain
480 * multiple entries with identical argument lists --- in the multiple-
481 * namespace case, we arrange for entries in earlier namespaces to mask
482 * identical entries in later namespaces.
485 FuncnameGetCandidates(List *names, int nargs)
487 FuncCandidateList resultList = NULL;
494 /* deconstruct the name list */
495 DeconstructQualifiedName(names, &schemaname, &funcname);
499 /* use exact schema given */
500 namespaceId = LookupExplicitNamespace(schemaname);
504 /* flag to indicate we need namespace search */
505 namespaceId = InvalidOid;
506 recomputeNamespacePath();
509 /* Search syscache by name only */
510 catlist = SearchSysCacheList(PROCNAMEARGSNSP, 1,
511 CStringGetDatum(funcname),
514 for (i = 0; i < catlist->n_members; i++)
516 HeapTuple proctup = &catlist->members[i]->tuple;
517 Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
518 int pronargs = procform->pronargs;
520 FuncCandidateList newResult;
522 /* Ignore if it doesn't match requested argument count */
523 if (nargs >= 0 && pronargs != nargs)
526 if (OidIsValid(namespaceId))
528 /* Consider only procs in specified namespace */
529 if (procform->pronamespace != namespaceId)
531 /* No need to check args, they must all be different */
535 /* Consider only procs that are in the search path */
538 foreach(nsp, namespaceSearchPath)
540 if (procform->pronamespace == lfirst_oid(nsp))
545 continue; /* proc is not in search path */
548 * Okay, it's in the search path, but does it have the same
549 * arguments as something we already accepted? If so, keep only
550 * the one that appears earlier in the search path.
552 * If we have an ordered list from SearchSysCacheList (the normal
553 * case), then any conflicting proc must immediately adjoin this
554 * one in the list, so we only need to look at the newest result
555 * item. If we have an unordered list, we have to scan the whole
560 FuncCandidateList prevResult;
562 if (catlist->ordered)
564 if (pronargs == resultList->nargs &&
565 memcmp(procform->proargtypes.values,
567 pronargs * sizeof(Oid)) == 0)
568 prevResult = resultList;
574 for (prevResult = resultList;
576 prevResult = prevResult->next)
578 if (pronargs == prevResult->nargs &&
579 memcmp(procform->proargtypes.values,
581 pronargs * sizeof(Oid)) == 0)
587 /* We have a match with a previous result */
588 Assert(pathpos != prevResult->pathpos);
589 if (pathpos > prevResult->pathpos)
590 continue; /* keep previous result */
591 /* replace previous result */
592 prevResult->pathpos = pathpos;
593 prevResult->oid = HeapTupleGetOid(proctup);
594 continue; /* args are same, of course */
600 * Okay to add it to result list
602 newResult = (FuncCandidateList)
603 palloc(sizeof(struct _FuncCandidateList) - sizeof(Oid)
604 + pronargs * sizeof(Oid));
605 newResult->pathpos = pathpos;
606 newResult->oid = HeapTupleGetOid(proctup);
607 newResult->nargs = pronargs;
608 memcpy(newResult->args, procform->proargtypes.values,
609 pronargs * sizeof(Oid));
611 newResult->next = resultList;
612 resultList = newResult;
615 ReleaseSysCacheList(catlist);
622 * Determine whether a function (identified by OID) is visible in the
623 * current search path. Visible means "would be found by searching
624 * for the unqualified function name with exact argument matches".
627 FunctionIsVisible(Oid funcid)
630 Form_pg_proc procform;
634 proctup = SearchSysCache(PROCOID,
635 ObjectIdGetDatum(funcid),
637 if (!HeapTupleIsValid(proctup))
638 elog(ERROR, "cache lookup failed for function %u", funcid);
639 procform = (Form_pg_proc) GETSTRUCT(proctup);
641 recomputeNamespacePath();
644 * Quick check: if it ain't in the path at all, it ain't visible. Items in
645 * the system namespace are surely in the path and so we needn't even do
646 * list_member_oid() for them.
648 pronamespace = procform->pronamespace;
649 if (pronamespace != PG_CATALOG_NAMESPACE &&
650 !list_member_oid(namespaceSearchPath, pronamespace))
655 * If it is in the path, it might still not be visible; it could be
656 * hidden by another proc of the same name and arguments earlier in
657 * the path. So we must do a slow check to see if this is the same
658 * proc that would be found by FuncnameGetCandidates.
660 char *proname = NameStr(procform->proname);
661 int nargs = procform->pronargs;
662 FuncCandidateList clist;
666 clist = FuncnameGetCandidates(list_make1(makeString(proname)), nargs);
668 for (; clist; clist = clist->next)
670 if (memcmp(clist->args, procform->proargtypes.values,
671 nargs * sizeof(Oid)) == 0)
673 /* Found the expected entry; is it the right proc? */
674 visible = (clist->oid == funcid);
680 ReleaseSysCache(proctup);
688 * Given a possibly-qualified operator name and exact input datatypes,
689 * look up the operator. Returns InvalidOid if not found.
691 * Pass oprleft = InvalidOid for a prefix op, oprright = InvalidOid for
694 * If the operator name is not schema-qualified, it is sought in the current
695 * namespace search path.
698 OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
705 /* deconstruct the name list */
706 DeconstructQualifiedName(names, &schemaname, &opername);
710 /* search only in exact schema given */
714 namespaceId = LookupExplicitNamespace(schemaname);
715 opertup = SearchSysCache(OPERNAMENSP,
716 CStringGetDatum(opername),
717 ObjectIdGetDatum(oprleft),
718 ObjectIdGetDatum(oprright),
719 ObjectIdGetDatum(namespaceId));
720 if (HeapTupleIsValid(opertup))
722 Oid result = HeapTupleGetOid(opertup);
724 ReleaseSysCache(opertup);
730 /* Search syscache by name and argument types */
731 catlist = SearchSysCacheList(OPERNAMENSP, 3,
732 CStringGetDatum(opername),
733 ObjectIdGetDatum(oprleft),
734 ObjectIdGetDatum(oprright),
737 if (catlist->n_members == 0)
739 /* no hope, fall out early */
740 ReleaseSysCacheList(catlist);
745 * We have to find the list member that is first in the search path, if
746 * there's more than one. This doubly-nested loop looks ugly, but in
747 * practice there should usually be few catlist members.
749 recomputeNamespacePath();
751 foreach(l, namespaceSearchPath)
753 Oid namespaceId = lfirst_oid(l);
756 for (i = 0; i < catlist->n_members; i++)
758 HeapTuple opertup = &catlist->members[i]->tuple;
759 Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
761 if (operform->oprnamespace == namespaceId)
763 Oid result = HeapTupleGetOid(opertup);
765 ReleaseSysCacheList(catlist);
771 ReleaseSysCacheList(catlist);
776 * OpernameGetCandidates
777 * Given a possibly-qualified operator name and operator kind,
778 * retrieve a list of the possible matches.
780 * If oprkind is '\0', we return all operators matching the given name,
781 * regardless of arguments.
783 * We search a single namespace if the operator name is qualified, else
784 * all namespaces in the search path. The return list will never contain
785 * multiple entries with identical argument lists --- in the multiple-
786 * namespace case, we arrange for entries in earlier namespaces to mask
787 * identical entries in later namespaces.
789 * The returned items always have two args[] entries --- one or the other
790 * will be InvalidOid for a prefix or postfix oprkind. nargs is 2, too.
793 OpernameGetCandidates(List *names, char oprkind)
795 FuncCandidateList resultList = NULL;
796 char *resultSpace = NULL;
804 /* deconstruct the name list */
805 DeconstructQualifiedName(names, &schemaname, &opername);
809 /* use exact schema given */
810 namespaceId = LookupExplicitNamespace(schemaname);
814 /* flag to indicate we need namespace search */
815 namespaceId = InvalidOid;
816 recomputeNamespacePath();
819 /* Search syscache by name only */
820 catlist = SearchSysCacheList(OPERNAMENSP, 1,
821 CStringGetDatum(opername),
825 * In typical scenarios, most if not all of the operators found by the
826 * catcache search will end up getting returned; and there can be quite a
827 * few, for common operator names such as '=' or '+'. To reduce the time
828 * spent in palloc, we allocate the result space as an array large enough
829 * to hold all the operators. The original coding of this routine did a
830 * separate palloc for each operator, but profiling revealed that the
831 * pallocs used an unreasonably large fraction of parsing time.
833 #define SPACE_PER_OP MAXALIGN(sizeof(struct _FuncCandidateList) + sizeof(Oid))
835 if (catlist->n_members > 0)
836 resultSpace = palloc(catlist->n_members * SPACE_PER_OP);
838 for (i = 0; i < catlist->n_members; i++)
840 HeapTuple opertup = &catlist->members[i]->tuple;
841 Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
843 FuncCandidateList newResult;
845 /* Ignore operators of wrong kind, if specific kind requested */
846 if (oprkind && operform->oprkind != oprkind)
849 if (OidIsValid(namespaceId))
851 /* Consider only opers in specified namespace */
852 if (operform->oprnamespace != namespaceId)
854 /* No need to check args, they must all be different */
858 /* Consider only opers that are in the search path */
861 foreach(nsp, namespaceSearchPath)
863 if (operform->oprnamespace == lfirst_oid(nsp))
868 continue; /* oper is not in search path */
871 * Okay, it's in the search path, but does it have the same
872 * arguments as something we already accepted? If so, keep only
873 * the one that appears earlier in the search path.
875 * If we have an ordered list from SearchSysCacheList (the normal
876 * case), then any conflicting oper must immediately adjoin this
877 * one in the list, so we only need to look at the newest result
878 * item. If we have an unordered list, we have to scan the whole
883 FuncCandidateList prevResult;
885 if (catlist->ordered)
887 if (operform->oprleft == resultList->args[0] &&
888 operform->oprright == resultList->args[1])
889 prevResult = resultList;
895 for (prevResult = resultList;
897 prevResult = prevResult->next)
899 if (operform->oprleft == prevResult->args[0] &&
900 operform->oprright == prevResult->args[1])
906 /* We have a match with a previous result */
907 Assert(pathpos != prevResult->pathpos);
908 if (pathpos > prevResult->pathpos)
909 continue; /* keep previous result */
910 /* replace previous result */
911 prevResult->pathpos = pathpos;
912 prevResult->oid = HeapTupleGetOid(opertup);
913 continue; /* args are same, of course */
919 * Okay to add it to result list
921 newResult = (FuncCandidateList) (resultSpace + nextResult);
922 nextResult += SPACE_PER_OP;
924 newResult->pathpos = pathpos;
925 newResult->oid = HeapTupleGetOid(opertup);
926 newResult->nargs = 2;
927 newResult->args[0] = operform->oprleft;
928 newResult->args[1] = operform->oprright;
929 newResult->next = resultList;
930 resultList = newResult;
933 ReleaseSysCacheList(catlist);
940 * Determine whether an operator (identified by OID) is visible in the
941 * current search path. Visible means "would be found by searching
942 * for the unqualified operator name with exact argument matches".
945 OperatorIsVisible(Oid oprid)
948 Form_pg_operator oprform;
952 oprtup = SearchSysCache(OPEROID,
953 ObjectIdGetDatum(oprid),
955 if (!HeapTupleIsValid(oprtup))
956 elog(ERROR, "cache lookup failed for operator %u", oprid);
957 oprform = (Form_pg_operator) GETSTRUCT(oprtup);
959 recomputeNamespacePath();
962 * Quick check: if it ain't in the path at all, it ain't visible. Items in
963 * the system namespace are surely in the path and so we needn't even do
964 * list_member_oid() for them.
966 oprnamespace = oprform->oprnamespace;
967 if (oprnamespace != PG_CATALOG_NAMESPACE &&
968 !list_member_oid(namespaceSearchPath, oprnamespace))
973 * If it is in the path, it might still not be visible; it could be
974 * hidden by another operator of the same name and arguments earlier
975 * in the path. So we must do a slow check to see if this is the same
976 * operator that would be found by OpernameGetOprId.
978 char *oprname = NameStr(oprform->oprname);
980 visible = (OpernameGetOprid(list_make1(makeString(oprname)),
981 oprform->oprleft, oprform->oprright)
985 ReleaseSysCache(oprtup);
992 * OpclassnameGetOpcid
993 * Try to resolve an unqualified index opclass name.
994 * Returns OID if opclass found in search path, else InvalidOid.
996 * This is essentially the same as TypenameGetTypid, but we have to have
997 * an extra argument for the index AM OID.
1000 OpclassnameGetOpcid(Oid amid, const char *opcname)
1005 recomputeNamespacePath();
1007 foreach(l, namespaceSearchPath)
1009 Oid namespaceId = lfirst_oid(l);
1011 opcid = GetSysCacheOid(CLAAMNAMENSP,
1012 ObjectIdGetDatum(amid),
1013 PointerGetDatum(opcname),
1014 ObjectIdGetDatum(namespaceId),
1016 if (OidIsValid(opcid))
1020 /* Not found in path */
1026 * Determine whether an opclass (identified by OID) is visible in the
1027 * current search path. Visible means "would be found by searching
1028 * for the unqualified opclass name".
1031 OpclassIsVisible(Oid opcid)
1034 Form_pg_opclass opcform;
1038 opctup = SearchSysCache(CLAOID,
1039 ObjectIdGetDatum(opcid),
1041 if (!HeapTupleIsValid(opctup))
1042 elog(ERROR, "cache lookup failed for opclass %u", opcid);
1043 opcform = (Form_pg_opclass) GETSTRUCT(opctup);
1045 recomputeNamespacePath();
1048 * Quick check: if it ain't in the path at all, it ain't visible. Items in
1049 * the system namespace are surely in the path and so we needn't even do
1050 * list_member_oid() for them.
1052 opcnamespace = opcform->opcnamespace;
1053 if (opcnamespace != PG_CATALOG_NAMESPACE &&
1054 !list_member_oid(namespaceSearchPath, opcnamespace))
1059 * If it is in the path, it might still not be visible; it could be
1060 * hidden by another opclass of the same name earlier in the path. So
1061 * we must do a slow check to see if this opclass would be found by
1062 * OpclassnameGetOpcid.
1064 char *opcname = NameStr(opcform->opcname);
1066 visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid);
1069 ReleaseSysCache(opctup);
1075 * OpfamilynameGetOpfid
1076 * Try to resolve an unqualified index opfamily name.
1077 * Returns OID if opfamily found in search path, else InvalidOid.
1079 * This is essentially the same as TypenameGetTypid, but we have to have
1080 * an extra argument for the index AM OID.
1083 OpfamilynameGetOpfid(Oid amid, const char *opfname)
1088 recomputeNamespacePath();
1090 foreach(l, namespaceSearchPath)
1092 Oid namespaceId = lfirst_oid(l);
1094 opfid = GetSysCacheOid(OPFAMILYAMNAMENSP,
1095 ObjectIdGetDatum(amid),
1096 PointerGetDatum(opfname),
1097 ObjectIdGetDatum(namespaceId),
1099 if (OidIsValid(opfid))
1103 /* Not found in path */
1109 * Determine whether an opfamily (identified by OID) is visible in the
1110 * current search path. Visible means "would be found by searching
1111 * for the unqualified opfamily name".
1114 OpfamilyIsVisible(Oid opfid)
1117 Form_pg_opfamily opfform;
1121 opftup = SearchSysCache(OPFAMILYOID,
1122 ObjectIdGetDatum(opfid),
1124 if (!HeapTupleIsValid(opftup))
1125 elog(ERROR, "cache lookup failed for opfamily %u", opfid);
1126 opfform = (Form_pg_opfamily) GETSTRUCT(opftup);
1128 recomputeNamespacePath();
1131 * Quick check: if it ain't in the path at all, it ain't visible. Items in
1132 * the system namespace are surely in the path and so we needn't even do
1133 * list_member_oid() for them.
1135 opfnamespace = opfform->opfnamespace;
1136 if (opfnamespace != PG_CATALOG_NAMESPACE &&
1137 !list_member_oid(namespaceSearchPath, opfnamespace))
1142 * If it is in the path, it might still not be visible; it could be
1143 * hidden by another opfamily of the same name earlier in the path. So
1144 * we must do a slow check to see if this opfamily would be found by
1145 * OpfamilynameGetOpfid.
1147 char *opfname = NameStr(opfform->opfname);
1149 visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid);
1152 ReleaseSysCache(opftup);
1158 * ConversionGetConid
1159 * Try to resolve an unqualified conversion name.
1160 * Returns OID if conversion found in search path, else InvalidOid.
1162 * This is essentially the same as RelnameGetRelid.
1165 ConversionGetConid(const char *conname)
1170 recomputeNamespacePath();
1172 foreach(l, namespaceSearchPath)
1174 Oid namespaceId = lfirst_oid(l);
1176 conid = GetSysCacheOid(CONNAMENSP,
1177 PointerGetDatum(conname),
1178 ObjectIdGetDatum(namespaceId),
1180 if (OidIsValid(conid))
1184 /* Not found in path */
1189 * ConversionIsVisible
1190 * Determine whether a conversion (identified by OID) is visible in the
1191 * current search path. Visible means "would be found by searching
1192 * for the unqualified conversion name".
1195 ConversionIsVisible(Oid conid)
1198 Form_pg_conversion conform;
1202 contup = SearchSysCache(CONOID,
1203 ObjectIdGetDatum(conid),
1205 if (!HeapTupleIsValid(contup))
1206 elog(ERROR, "cache lookup failed for conversion %u", conid);
1207 conform = (Form_pg_conversion) GETSTRUCT(contup);
1209 recomputeNamespacePath();
1212 * Quick check: if it ain't in the path at all, it ain't visible. Items in
1213 * the system namespace are surely in the path and so we needn't even do
1214 * list_member_oid() for them.
1216 connamespace = conform->connamespace;
1217 if (connamespace != PG_CATALOG_NAMESPACE &&
1218 !list_member_oid(namespaceSearchPath, connamespace))
1223 * If it is in the path, it might still not be visible; it could be
1224 * hidden by another conversion of the same name earlier in the path.
1225 * So we must do a slow check to see if this conversion would be found
1226 * by ConversionGetConid.
1228 char *conname = NameStr(conform->conname);
1230 visible = (ConversionGetConid(conname) == conid);
1233 ReleaseSysCache(contup);
1239 * DeconstructQualifiedName
1240 * Given a possibly-qualified name expressed as a list of String nodes,
1241 * extract the schema name and object name.
1243 * *nspname_p is set to NULL if there is no explicit schema name.
1246 DeconstructQualifiedName(List *names,
1251 char *schemaname = NULL;
1252 char *objname = NULL;
1254 switch (list_length(names))
1257 objname = strVal(linitial(names));
1260 schemaname = strVal(linitial(names));
1261 objname = strVal(lsecond(names));
1264 catalogname = strVal(linitial(names));
1265 schemaname = strVal(lsecond(names));
1266 objname = strVal(lthird(names));
1269 * We check the catalog name and then ignore it.
1271 if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
1273 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1274 errmsg("cross-database references are not implemented: %s",
1275 NameListToString(names))));
1279 (errcode(ERRCODE_SYNTAX_ERROR),
1280 errmsg("improper qualified name (too many dotted names): %s",
1281 NameListToString(names))));
1285 *nspname_p = schemaname;
1286 *objname_p = objname;
1290 * LookupExplicitNamespace
1291 * Process an explicitly-specified schema name: look up the schema
1292 * and verify we have USAGE (lookup) rights in it.
1294 * Returns the namespace OID. Raises ereport if any problem.
1297 LookupExplicitNamespace(const char *nspname)
1300 AclResult aclresult;
1302 namespaceId = GetSysCacheOid(NAMESPACENAME,
1303 CStringGetDatum(nspname),
1305 if (!OidIsValid(namespaceId))
1307 (errcode(ERRCODE_UNDEFINED_SCHEMA),
1308 errmsg("schema \"%s\" does not exist", nspname)));
1310 aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
1311 if (aclresult != ACLCHECK_OK)
1312 aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
1319 * LookupCreationNamespace
1320 * Look up the schema and verify we have CREATE rights on it.
1322 * This is just like LookupExplicitNamespace except for the permission check.
1325 LookupCreationNamespace(const char *nspname)
1328 AclResult aclresult;
1330 namespaceId = GetSysCacheOid(NAMESPACENAME,
1331 CStringGetDatum(nspname),
1333 if (!OidIsValid(namespaceId))
1335 (errcode(ERRCODE_UNDEFINED_SCHEMA),
1336 errmsg("schema \"%s\" does not exist", nspname)));
1338 aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
1339 if (aclresult != ACLCHECK_OK)
1340 aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
1347 * QualifiedNameGetCreationNamespace
1348 * Given a possibly-qualified name for an object (in List-of-Values
1349 * format), determine what namespace the object should be created in.
1350 * Also extract and return the object name (last component of list).
1352 * Note: this does not apply any permissions check. Callers must check
1353 * for CREATE rights on the selected namespace when appropriate.
1355 * This is *not* used for tables. Hence, the TEMP table namespace is
1356 * never selected as the creation target.
1359 QualifiedNameGetCreationNamespace(List *names, char **objname_p)
1365 /* deconstruct the name list */
1366 DeconstructQualifiedName(names, &schemaname, &objname);
1370 /* use exact schema given */
1371 namespaceId = GetSysCacheOid(NAMESPACENAME,
1372 CStringGetDatum(schemaname),
1374 if (!OidIsValid(namespaceId))
1376 (errcode(ERRCODE_UNDEFINED_SCHEMA),
1377 errmsg("schema \"%s\" does not exist", schemaname)));
1378 /* we do not check for USAGE rights here! */
1382 /* use the default creation namespace */
1383 recomputeNamespacePath();
1384 namespaceId = defaultCreationNamespace;
1385 if (!OidIsValid(namespaceId))
1387 (errcode(ERRCODE_UNDEFINED_SCHEMA),
1388 errmsg("no schema has been selected to create in")));
1391 *objname_p = objname;
1396 * makeRangeVarFromNameList
1397 * Utility routine to convert a qualified-name list into RangeVar form.
1400 makeRangeVarFromNameList(List *names)
1402 RangeVar *rel = makeRangeVar(NULL, NULL);
1404 switch (list_length(names))
1407 rel->relname = strVal(linitial(names));
1410 rel->schemaname = strVal(linitial(names));
1411 rel->relname = strVal(lsecond(names));
1414 rel->catalogname = strVal(linitial(names));
1415 rel->schemaname = strVal(lsecond(names));
1416 rel->relname = strVal(lthird(names));
1420 (errcode(ERRCODE_SYNTAX_ERROR),
1421 errmsg("improper relation name (too many dotted names): %s",
1422 NameListToString(names))));
1431 * Utility routine to convert a qualified-name list into a string.
1433 * This is used primarily to form error messages, and so we do not quote
1434 * the list elements, for the sake of legibility.
1437 NameListToString(List *names)
1439 StringInfoData string;
1442 initStringInfo(&string);
1446 if (l != list_head(names))
1447 appendStringInfoChar(&string, '.');
1448 appendStringInfoString(&string, strVal(lfirst(l)));
1455 * NameListToQuotedString
1456 * Utility routine to convert a qualified-name list into a string.
1458 * Same as above except that names will be double-quoted where necessary,
1459 * so the string could be re-parsed (eg, by textToQualifiedNameList).
1462 NameListToQuotedString(List *names)
1464 StringInfoData string;
1467 initStringInfo(&string);
1471 if (l != list_head(names))
1472 appendStringInfoChar(&string, '.');
1473 appendStringInfoString(&string, quote_identifier(strVal(lfirst(l))));
1480 * isTempNamespace - is the given namespace my temporary-table namespace?
1483 isTempNamespace(Oid namespaceId)
1485 if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
1491 * isAnyTempNamespace - is the given namespace a temporary-table namespace
1492 * (either my own, or another backend's)?
1495 isAnyTempNamespace(Oid namespaceId)
1500 /* If the namespace name starts with "pg_temp_", say "true" */
1501 nspname = get_namespace_name(namespaceId);
1503 return false; /* no such namespace? */
1504 result = (strncmp(nspname, "pg_temp_", 8) == 0);
1510 * isOtherTempNamespace - is the given namespace some other backend's
1511 * temporary-table namespace?
1514 isOtherTempNamespace(Oid namespaceId)
1516 /* If it's my own temp namespace, say "false" */
1517 if (isTempNamespace(namespaceId))
1519 /* Else, if the namespace name starts with "pg_temp_", say "true" */
1520 return isAnyTempNamespace(namespaceId);
1524 * PushSpecialNamespace - push a "special" namespace onto the front of the
1527 * This is a slightly messy hack intended only for support of CREATE SCHEMA.
1528 * Although the API is defined to allow a stack of pushed namespaces, we
1529 * presently only support one at a time.
1531 * The pushed namespace will be removed from the search path at end of
1532 * transaction, whether commit or abort.
1535 PushSpecialNamespace(Oid namespaceId)
1537 Assert(!OidIsValid(mySpecialNamespace));
1538 mySpecialNamespace = namespaceId;
1539 namespaceSearchPathValid = false;
1543 * PopSpecialNamespace - remove previously pushed special namespace.
1546 PopSpecialNamespace(Oid namespaceId)
1548 Assert(mySpecialNamespace == namespaceId);
1549 mySpecialNamespace = InvalidOid;
1550 namespaceSearchPathValid = false;
1554 * FindConversionByName - find a conversion by possibly qualified name
1557 FindConversionByName(List *name)
1560 char *conversion_name;
1565 /* deconstruct the name list */
1566 DeconstructQualifiedName(name, &schemaname, &conversion_name);
1570 /* use exact schema given */
1571 namespaceId = LookupExplicitNamespace(schemaname);
1572 return FindConversion(conversion_name, namespaceId);
1576 /* search for it in search path */
1577 recomputeNamespacePath();
1579 foreach(l, namespaceSearchPath)
1581 namespaceId = lfirst_oid(l);
1582 conoid = FindConversion(conversion_name, namespaceId);
1583 if (OidIsValid(conoid))
1588 /* Not found in path */
1593 * FindDefaultConversionProc - find default encoding conversion proc
1596 FindDefaultConversionProc(int4 for_encoding, int4 to_encoding)
1601 recomputeNamespacePath();
1603 foreach(l, namespaceSearchPath)
1605 Oid namespaceId = lfirst_oid(l);
1607 proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
1608 if (OidIsValid(proc))
1612 /* Not found in path */
1617 * recomputeNamespacePath - recompute path derived variables if needed.
1620 recomputeNamespacePath(void)
1622 Oid roleid = GetUserId();
1629 MemoryContext oldcxt;
1632 * Do nothing if path is already valid.
1634 if (namespaceSearchPathValid && namespaceUser == roleid)
1637 /* Need a modifiable copy of namespace_search_path string */
1638 rawname = pstrdup(namespace_search_path);
1640 /* Parse string into list of identifiers */
1641 if (!SplitIdentifierString(rawname, ',', &namelist))
1643 /* syntax error in name list */
1644 /* this should not happen if GUC checked check_search_path */
1645 elog(ERROR, "invalid list syntax");
1649 * Convert the list of names to a list of OIDs. If any names are not
1650 * recognizable or we don't have read access, just leave them out of the
1651 * list. (We can't raise an error, since the search_path setting has
1652 * already been accepted.) Don't make duplicate entries, either.
1655 foreach(l, namelist)
1657 char *curname = (char *) lfirst(l);
1660 if (strcmp(curname, "$user") == 0)
1662 /* $user --- substitute namespace matching user name, if any */
1665 tuple = SearchSysCache(AUTHOID,
1666 ObjectIdGetDatum(roleid),
1668 if (HeapTupleIsValid(tuple))
1672 rname = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname);
1673 namespaceId = GetSysCacheOid(NAMESPACENAME,
1674 CStringGetDatum(rname),
1676 ReleaseSysCache(tuple);
1677 if (OidIsValid(namespaceId) &&
1678 !list_member_oid(oidlist, namespaceId) &&
1679 pg_namespace_aclcheck(namespaceId, roleid,
1680 ACL_USAGE) == ACLCHECK_OK)
1681 oidlist = lappend_oid(oidlist, namespaceId);
1686 /* normal namespace reference */
1687 namespaceId = GetSysCacheOid(NAMESPACENAME,
1688 CStringGetDatum(curname),
1690 if (OidIsValid(namespaceId) &&
1691 !list_member_oid(oidlist, namespaceId) &&
1692 pg_namespace_aclcheck(namespaceId, roleid,
1693 ACL_USAGE) == ACLCHECK_OK)
1694 oidlist = lappend_oid(oidlist, namespaceId);
1699 * Remember the first member of the explicit list.
1702 firstNS = InvalidOid;
1704 firstNS = linitial_oid(oidlist);
1707 * Add any implicitly-searched namespaces to the list. Note these go on
1708 * the front, not the back; also notice that we do not check USAGE
1709 * permissions for these.
1711 if (!list_member_oid(oidlist, PG_CATALOG_NAMESPACE))
1712 oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
1714 if (OidIsValid(myTempNamespace) &&
1715 !list_member_oid(oidlist, myTempNamespace))
1716 oidlist = lcons_oid(myTempNamespace, oidlist);
1718 if (OidIsValid(mySpecialNamespace) &&
1719 !list_member_oid(oidlist, mySpecialNamespace))
1720 oidlist = lcons_oid(mySpecialNamespace, oidlist);
1723 * Now that we've successfully built the new list of namespace OIDs, save
1724 * it in permanent storage.
1726 oldcxt = MemoryContextSwitchTo(TopMemoryContext);
1727 newpath = list_copy(oidlist);
1728 MemoryContextSwitchTo(oldcxt);
1730 /* Now safe to assign to state variable. */
1731 list_free(namespaceSearchPath);
1732 namespaceSearchPath = newpath;
1735 * Update info derived from search path.
1737 firstExplicitNamespace = firstNS;
1738 if (OidIsValid(mySpecialNamespace))
1739 defaultCreationNamespace = mySpecialNamespace;
1741 defaultCreationNamespace = firstNS;
1743 /* Mark the path valid. */
1744 namespaceSearchPathValid = true;
1745 namespaceUser = roleid;
1749 list_free(namelist);
1754 * InitTempTableNamespace
1755 * Initialize temp table namespace on first use in a particular backend
1758 InitTempTableNamespace(void)
1760 char namespaceName[NAMEDATALEN];
1764 * First, do permission check to see if we are authorized to make temp
1765 * tables. We use a nonstandard error message here since "databasename:
1766 * permission denied" might be a tad cryptic.
1768 * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
1769 * that's necessary since current user ID could change during the session.
1770 * But there's no need to make the namespace in the first place until a
1771 * temp table creation request is made by someone with appropriate rights.
1773 if (pg_database_aclcheck(MyDatabaseId, GetUserId(),
1774 ACL_CREATE_TEMP) != ACLCHECK_OK)
1776 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1777 errmsg("permission denied to create temporary tables in database \"%s\"",
1778 get_database_name(MyDatabaseId))));
1780 snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
1782 namespaceId = GetSysCacheOid(NAMESPACENAME,
1783 CStringGetDatum(namespaceName),
1785 if (!OidIsValid(namespaceId))
1788 * First use of this temp namespace in this database; create it. The
1789 * temp namespaces are always owned by the superuser. We leave their
1790 * permissions at default --- i.e., no access except to superuser ---
1791 * to ensure that unprivileged users can't peek at other backends'
1792 * temp tables. This works because the places that access the temp
1793 * namespace for my own backend skip permissions checks on it.
1795 namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID);
1796 /* Advance command counter to make namespace visible */
1797 CommandCounterIncrement();
1802 * If the namespace already exists, clean it out (in case the former
1803 * owner crashed without doing so).
1805 RemoveTempRelations(namespaceId);
1809 * Okay, we've prepared the temp namespace ... but it's not committed yet,
1810 * so all our work could be undone by transaction rollback. Set flag for
1811 * AtEOXact_Namespace to know what to do.
1813 myTempNamespace = namespaceId;
1815 /* It should not be done already. */
1816 AssertState(myTempNamespaceSubID == InvalidSubTransactionId);
1817 myTempNamespaceSubID = GetCurrentSubTransactionId();
1819 namespaceSearchPathValid = false; /* need to rebuild list */
1823 * End-of-transaction cleanup for namespaces.
1826 AtEOXact_Namespace(bool isCommit)
1829 * If we abort the transaction in which a temp namespace was selected,
1830 * we'll have to do any creation or cleanout work over again. So, just
1831 * forget the namespace entirely until next time. On the other hand, if
1832 * we commit then register an exit callback to clean out the temp tables
1833 * at backend shutdown. (We only want to register the callback once per
1834 * session, so this is a good place to do it.)
1836 if (myTempNamespaceSubID != InvalidSubTransactionId)
1839 on_shmem_exit(RemoveTempRelationsCallback, 0);
1842 myTempNamespace = InvalidOid;
1843 namespaceSearchPathValid = false; /* need to rebuild list */
1845 myTempNamespaceSubID = InvalidSubTransactionId;
1849 * Clean up if someone failed to do PopSpecialNamespace
1851 if (OidIsValid(mySpecialNamespace))
1853 mySpecialNamespace = InvalidOid;
1854 namespaceSearchPathValid = false; /* need to rebuild list */
1859 * AtEOSubXact_Namespace
1861 * At subtransaction commit, propagate the temp-namespace-creation
1862 * flag to the parent subtransaction.
1864 * At subtransaction abort, forget the flag if we set it up.
1867 AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid,
1868 SubTransactionId parentSubid)
1870 if (myTempNamespaceSubID == mySubid)
1873 myTempNamespaceSubID = parentSubid;
1876 myTempNamespaceSubID = InvalidSubTransactionId;
1877 /* TEMP namespace creation failed, so reset state */
1878 myTempNamespace = InvalidOid;
1879 namespaceSearchPathValid = false; /* need to rebuild list */
1885 * Remove all relations in the specified temp namespace.
1887 * This is called at backend shutdown (if we made any temp relations).
1888 * It is also called when we begin using a pre-existing temp namespace,
1889 * in order to clean out any relations that might have been created by
1890 * a crashed backend.
1893 RemoveTempRelations(Oid tempNamespaceId)
1895 ObjectAddress object;
1898 * We want to get rid of everything in the target namespace, but not the
1899 * namespace itself (deleting it only to recreate it later would be a
1900 * waste of cycles). We do this by finding everything that has a
1901 * dependency on the namespace.
1903 object.classId = NamespaceRelationId;
1904 object.objectId = tempNamespaceId;
1905 object.objectSubId = 0;
1907 deleteWhatDependsOn(&object, false);
1911 * Callback to remove temp relations at backend exit.
1914 RemoveTempRelationsCallback(int code, Datum arg)
1916 if (OidIsValid(myTempNamespace)) /* should always be true */
1918 /* Need to ensure we have a usable transaction. */
1919 AbortOutOfAnyTransaction();
1920 StartTransactionCommand();
1922 RemoveTempRelations(myTempNamespace);
1924 CommitTransactionCommand();
1930 * Routines for handling the GUC variable 'search_path'.
1933 /* assign_hook: validate new search_path, do extra actions as needed */
1935 assign_search_path(const char *newval, bool doit, GucSource source)
1941 /* Need a modifiable copy of string */
1942 rawname = pstrdup(newval);
1944 /* Parse string into list of identifiers */
1945 if (!SplitIdentifierString(rawname, ',', &namelist))
1947 /* syntax error in name list */
1949 list_free(namelist);
1954 * If we aren't inside a transaction, we cannot do database access so
1955 * cannot verify the individual names. Must accept the list on faith.
1957 if (source >= PGC_S_INTERACTIVE && IsTransactionState())
1960 * Verify that all the names are either valid namespace names or
1961 * "$user". We do not require $user to correspond to a valid
1962 * namespace. We do not check for USAGE rights, either; should we?
1964 * When source == PGC_S_TEST, we are checking the argument of an ALTER
1965 * DATABASE SET or ALTER USER SET command. It could be that the
1966 * intended use of the search path is for some other database, so we
1967 * should not error out if it mentions schemas not present in the
1968 * current database. We reduce the message to NOTICE instead.
1970 foreach(l, namelist)
1972 char *curname = (char *) lfirst(l);
1974 if (strcmp(curname, "$user") == 0)
1976 if (!SearchSysCacheExists(NAMESPACENAME,
1977 CStringGetDatum(curname),
1979 ereport((source == PGC_S_TEST) ? NOTICE : ERROR,
1980 (errcode(ERRCODE_UNDEFINED_SCHEMA),
1981 errmsg("schema \"%s\" does not exist", curname)));
1986 list_free(namelist);
1989 * We mark the path as needing recomputation, but don't do anything until
1990 * it's needed. This avoids trying to do database access during GUC
1994 namespaceSearchPathValid = false;
2000 * InitializeSearchPath: initialize module during InitPostgres.
2002 * This is called after we are up enough to be able to do catalog lookups.
2005 InitializeSearchPath(void)
2007 if (IsBootstrapProcessingMode())
2010 * In bootstrap mode, the search path must be 'pg_catalog' so that
2011 * tables are created in the proper namespace; ignore the GUC setting.
2013 MemoryContext oldcxt;
2015 oldcxt = MemoryContextSwitchTo(TopMemoryContext);
2016 namespaceSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
2017 MemoryContextSwitchTo(oldcxt);
2018 defaultCreationNamespace = PG_CATALOG_NAMESPACE;
2019 firstExplicitNamespace = PG_CATALOG_NAMESPACE;
2020 namespaceSearchPathValid = true;
2021 namespaceUser = GetUserId();
2026 * In normal mode, arrange for a callback on any syscache invalidation
2027 * of pg_namespace rows.
2029 CacheRegisterSyscacheCallback(NAMESPACEOID,
2032 /* Force search path to be recomputed on next use */
2033 namespaceSearchPathValid = false;
2039 * Syscache inval callback function
2042 NamespaceCallback(Datum arg, Oid relid)
2044 /* Force search path to be recomputed on next use */
2045 namespaceSearchPathValid = false;
2049 * Fetch the active search path. The return value is a palloc'ed list
2050 * of OIDs; the caller is responsible for freeing this storage as
2053 * The returned list includes the implicitly-prepended namespaces only if
2054 * includeImplicit is true.
2057 fetch_search_path(bool includeImplicit)
2061 recomputeNamespacePath();
2063 result = list_copy(namespaceSearchPath);
2064 if (!includeImplicit)
2066 while (result && linitial_oid(result) != firstExplicitNamespace)
2067 result = list_delete_first(result);
2074 * Export the FooIsVisible functions as SQL-callable functions.
2078 pg_table_is_visible(PG_FUNCTION_ARGS)
2080 Oid oid = PG_GETARG_OID(0);
2082 PG_RETURN_BOOL(RelationIsVisible(oid));
2086 pg_type_is_visible(PG_FUNCTION_ARGS)
2088 Oid oid = PG_GETARG_OID(0);
2090 PG_RETURN_BOOL(TypeIsVisible(oid));
2094 pg_function_is_visible(PG_FUNCTION_ARGS)
2096 Oid oid = PG_GETARG_OID(0);
2098 PG_RETURN_BOOL(FunctionIsVisible(oid));
2102 pg_operator_is_visible(PG_FUNCTION_ARGS)
2104 Oid oid = PG_GETARG_OID(0);
2106 PG_RETURN_BOOL(OperatorIsVisible(oid));
2110 pg_opclass_is_visible(PG_FUNCTION_ARGS)
2112 Oid oid = PG_GETARG_OID(0);
2114 PG_RETURN_BOOL(OpclassIsVisible(oid));
2118 pg_conversion_is_visible(PG_FUNCTION_ARGS)
2120 Oid oid = PG_GETARG_OID(0);
2122 PG_RETURN_BOOL(ConversionIsVisible(oid));
2126 pg_my_temp_schema(PG_FUNCTION_ARGS)
2128 PG_RETURN_OID(myTempNamespace);
2132 pg_is_other_temp_schema(PG_FUNCTION_ARGS)
2134 Oid oid = PG_GETARG_OID(0);
2136 PG_RETURN_BOOL(isOtherTempNamespace(oid));