Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Defines | Typedefs | Functions | Variables

namespace.h File Reference

#include "nodes/primnodes.h"
#include "storage/lock.h"
Include dependency graph for namespace.h:

Go to the source code of this file.

Data Structures

struct  _FuncCandidateList
struct  OverrideSearchPath

Defines

#define RangeVarGetRelid(relation, lockmode, missing_ok)   RangeVarGetRelidExtended(relation, lockmode, missing_ok, false, NULL, NULL)

Typedefs

typedef struct _FuncCandidateListFuncCandidateList
typedef struct OverrideSearchPath OverrideSearchPath
typedef void(* RangeVarGetRelidCallback )(const RangeVar *relation, Oid relId, Oid oldRelId, void *callback_arg)

Functions

Oid RangeVarGetRelidExtended (const RangeVar *relation, LOCKMODE lockmode, bool missing_ok, bool nowait, RangeVarGetRelidCallback callback, void *callback_arg)
Oid RangeVarGetCreationNamespace (const RangeVar *newRelation)
Oid RangeVarGetAndCheckCreationNamespace (RangeVar *newRelation, LOCKMODE lockmode, Oid *existing_relation_id)
void RangeVarAdjustRelationPersistence (RangeVar *newRelation, Oid nspid)
Oid RelnameGetRelid (const char *relname)
bool RelationIsVisible (Oid relid)
Oid TypenameGetTypid (const char *typname)
bool TypeIsVisible (Oid typid)
FuncCandidateList FuncnameGetCandidates (List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults)
bool FunctionIsVisible (Oid funcid)
Oid OpernameGetOprid (List *names, Oid oprleft, Oid oprright)
FuncCandidateList OpernameGetCandidates (List *names, char oprkind)
bool OperatorIsVisible (Oid oprid)
Oid OpclassnameGetOpcid (Oid amid, const char *opcname)
bool OpclassIsVisible (Oid opcid)
Oid OpfamilynameGetOpfid (Oid amid, const char *opfname)
bool OpfamilyIsVisible (Oid opfid)
Oid CollationGetCollid (const char *collname)
bool CollationIsVisible (Oid collid)
Oid ConversionGetConid (const char *conname)
bool ConversionIsVisible (Oid conid)
Oid get_ts_parser_oid (List *names, bool missing_ok)
bool TSParserIsVisible (Oid prsId)
Oid get_ts_dict_oid (List *names, bool missing_ok)
bool TSDictionaryIsVisible (Oid dictId)
Oid get_ts_template_oid (List *names, bool missing_ok)
bool TSTemplateIsVisible (Oid tmplId)
Oid get_ts_config_oid (List *names, bool missing_ok)
bool TSConfigIsVisible (Oid cfgid)
void DeconstructQualifiedName (List *names, char **nspname_p, char **objname_p)
Oid LookupNamespaceNoError (const char *nspname)
Oid LookupExplicitNamespace (const char *nspname, bool missing_ok)
Oid get_namespace_oid (const char *nspname, bool missing_ok)
Oid LookupCreationNamespace (const char *nspname)
void CheckSetNamespace (Oid oldNspOid, Oid nspOid, Oid classid, Oid objid)
Oid QualifiedNameGetCreationNamespace (List *names, char **objname_p)
RangeVarmakeRangeVarFromNameList (List *names)
char * NameListToString (List *names)
char * NameListToQuotedString (List *names)
bool isTempNamespace (Oid namespaceId)
bool isTempToastNamespace (Oid namespaceId)
bool isTempOrToastNamespace (Oid namespaceId)
bool isAnyTempNamespace (Oid namespaceId)
bool isOtherTempNamespace (Oid namespaceId)
int GetTempNamespaceBackendId (Oid namespaceId)
Oid GetTempToastNamespace (void)
void ResetTempTableNamespace (void)
OverrideSearchPathGetOverrideSearchPath (MemoryContext context)
OverrideSearchPathCopyOverrideSearchPath (OverrideSearchPath *path)
bool OverrideSearchPathMatchesCurrent (OverrideSearchPath *path)
void PushOverrideSearchPath (OverrideSearchPath *newpath)
void PopOverrideSearchPath (void)
Oid get_collation_oid (List *collname, bool missing_ok)
Oid get_conversion_oid (List *conname, bool missing_ok)
Oid FindDefaultConversionProc (int32 for_encoding, int32 to_encoding)
void InitializeSearchPath (void)
void AtEOXact_Namespace (bool isCommit)
void AtEOSubXact_Namespace (bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Listfetch_search_path (bool includeImplicit)
int fetch_search_path_array (Oid *sarray, int sarray_len)

Variables

char * namespace_search_path

Define Documentation

#define RangeVarGetRelid (   relation,
  lockmode,
  missing_ok 
)    RangeVarGetRelidExtended(relation, lockmode, missing_ok, false, NULL, NULL)

Typedef Documentation

typedef void(* RangeVarGetRelidCallback)(const RangeVar *relation, Oid relId, Oid oldRelId, void *callback_arg)

Definition at line 50 of file namespace.h.


Function Documentation

void AtEOSubXact_Namespace ( bool  isCommit,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)

Definition at line 3725 of file namespace.c.

References activeCreationNamespace, activeTempCreationPending, baseCreationNamespace, baseSearchPathValid, baseTempCreationPending, OverrideStackEntry::creationNamespace, elog, GetCurrentTransactionNestLevel(), linitial, list_delete_first(), list_free(), myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, OverrideStackEntry::nestLevel, pfree(), OverrideStackEntry::searchPath, and WARNING.

Referenced by AbortSubTransaction(), and CommitSubTransaction().

{
    OverrideStackEntry *entry;

    if (myTempNamespaceSubID == mySubid)
    {
        if (isCommit)
            myTempNamespaceSubID = parentSubid;
        else
        {
            myTempNamespaceSubID = InvalidSubTransactionId;
            /* TEMP namespace creation failed, so reset state */
            myTempNamespace = InvalidOid;
            myTempToastNamespace = InvalidOid;
            baseSearchPathValid = false;        /* need to rebuild list */
        }
    }

    /*
     * Clean up if someone failed to do PopOverrideSearchPath
     */
    while (overrideStack)
    {
        entry = (OverrideStackEntry *) linitial(overrideStack);
        if (entry->nestLevel < GetCurrentTransactionNestLevel())
            break;
        if (isCommit)
            elog(WARNING, "leaked override search path");
        overrideStack = list_delete_first(overrideStack);
        list_free(entry->searchPath);
        pfree(entry);
    }

    /* Activate the next level down. */
    if (overrideStack)
    {
        entry = (OverrideStackEntry *) linitial(overrideStack);
        activeSearchPath = entry->searchPath;
        activeCreationNamespace = entry->creationNamespace;
        activeTempCreationPending = false;      /* XXX is this OK? */
    }
    else
    {
        /* If not baseSearchPathValid, this is useless but harmless */
        activeSearchPath = baseSearchPath;
        activeCreationNamespace = baseCreationNamespace;
        activeTempCreationPending = baseTempCreationPending;
    }
}

void AtEOXact_Namespace ( bool  isCommit  ) 

Definition at line 3670 of file namespace.c.

References activeCreationNamespace, activeTempCreationPending, baseCreationNamespace, baseSearchPathValid, baseTempCreationPending, elog, InvalidSubTransactionId, linitial, list_delete_first(), list_free(), myTempNamespace, myTempNamespaceSubID, myTempToastNamespace, on_shmem_exit(), pfree(), RemoveTempRelationsCallback(), OverrideStackEntry::searchPath, and WARNING.

Referenced by AbortTransaction(), CommitTransaction(), and PrepareTransaction().

{
    /*
     * If we abort the transaction in which a temp namespace was selected,
     * we'll have to do any creation or cleanout work over again.  So, just
     * forget the namespace entirely until next time.  On the other hand, if
     * we commit then register an exit callback to clean out the temp tables
     * at backend shutdown.  (We only want to register the callback once per
     * session, so this is a good place to do it.)
     */
    if (myTempNamespaceSubID != InvalidSubTransactionId)
    {
        if (isCommit)
            on_shmem_exit(RemoveTempRelationsCallback, 0);
        else
        {
            myTempNamespace = InvalidOid;
            myTempToastNamespace = InvalidOid;
            baseSearchPathValid = false;        /* need to rebuild list */
        }
        myTempNamespaceSubID = InvalidSubTransactionId;
    }

    /*
     * Clean up if someone failed to do PopOverrideSearchPath
     */
    if (overrideStack)
    {
        if (isCommit)
            elog(WARNING, "leaked override search path");
        while (overrideStack)
        {
            OverrideStackEntry *entry;

            entry = (OverrideStackEntry *) linitial(overrideStack);
            overrideStack = list_delete_first(overrideStack);
            list_free(entry->searchPath);
            pfree(entry);
        }
        /* If not baseSearchPathValid, this is useless but harmless */
        activeSearchPath = baseSearchPath;
        activeCreationNamespace = baseCreationNamespace;
        activeTempCreationPending = baseTempCreationPending;
    }
}

void CheckSetNamespace ( Oid  oldNspOid,
Oid  nspOid,
Oid  classid,
Oid  objid 
)

Definition at line 2758 of file namespace.c.

References ereport, errcode(), errmsg(), ERROR, get_namespace_name(), getObjectDescriptionOids(), isAnyTempNamespace(), PG_TOAST_NAMESPACE, ProcedureRelationId, and RelationRelationId.

Referenced by AlterObjectNamespace_internal(), AlterTableNamespace(), and AlterTypeNamespaceInternal().

{
    if (oldNspOid == nspOid)
        ereport(ERROR,
                (classid == RelationRelationId ?
                 errcode(ERRCODE_DUPLICATE_TABLE) :
                 classid == ProcedureRelationId ?
                 errcode(ERRCODE_DUPLICATE_FUNCTION) :
                 errcode(ERRCODE_DUPLICATE_OBJECT),
                 errmsg("%s is already in schema \"%s\"",
                        getObjectDescriptionOids(classid, objid),
                        get_namespace_name(nspOid))));

    /* disallow renaming into or out of temp schemas */
    if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
        ereport(ERROR,
                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
            errmsg("cannot move objects into or out of temporary schemas")));

    /* same for TOAST schema */
    if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
        ereport(ERROR,
                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                 errmsg("cannot move objects into or out of TOAST schema")));
}

Oid CollationGetCollid ( const char *  collname  ) 

Definition at line 1918 of file namespace.c.

References COLLNAMEENCNSP, GetDatabaseEncoding(), GetSysCacheOid3, Int32GetDatum, lfirst_oid, myTempNamespace, ObjectIdGetDatum, OidIsValid, PointerGetDatum, and recomputeNamespacePath().

Referenced by CollationIsVisible().

{
    int32       dbencoding = GetDatabaseEncoding();
    ListCell   *l;

    recomputeNamespacePath();

    foreach(l, activeSearchPath)
    {
        Oid         namespaceId = lfirst_oid(l);
        Oid         collid;

        if (namespaceId == myTempNamespace)
            continue;           /* do not look in temp namespace */

        /* Check for database-encoding-specific entry */
        collid = GetSysCacheOid3(COLLNAMEENCNSP,
                                 PointerGetDatum(collname),
                                 Int32GetDatum(dbencoding),
                                 ObjectIdGetDatum(namespaceId));
        if (OidIsValid(collid))
            return collid;

        /* Check for any-encoding entry */
        collid = GetSysCacheOid3(COLLNAMEENCNSP,
                                 PointerGetDatum(collname),
                                 Int32GetDatum(-1),
                                 ObjectIdGetDatum(namespaceId));
        if (OidIsValid(collid))
            return collid;
    }

    /* Not found in path */
    return InvalidOid;
}

bool CollationIsVisible ( Oid  collid  ) 

Definition at line 1961 of file namespace.c.

References CollationGetCollid(), COLLOID, elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_member_oid(), NameStr, ObjectIdGetDatum, PG_CATALOG_NAMESPACE, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1.

Referenced by generate_collation_name(), and pg_collation_is_visible().

{
    HeapTuple   colltup;
    Form_pg_collation collform;
    Oid         collnamespace;
    bool        visible;

    colltup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
    if (!HeapTupleIsValid(colltup))
        elog(ERROR, "cache lookup failed for collation %u", collid);
    collform = (Form_pg_collation) GETSTRUCT(colltup);

    recomputeNamespacePath();

    /*
     * Quick check: if it ain't in the path at all, it ain't visible. Items in
     * the system namespace are surely in the path and so we needn't even do
     * list_member_oid() for them.
     */
    collnamespace = collform->collnamespace;
    if (collnamespace != PG_CATALOG_NAMESPACE &&
        !list_member_oid(activeSearchPath, collnamespace))
        visible = false;
    else
    {
        /*
         * If it is in the path, it might still not be visible; it could be
         * hidden by another conversion of the same name earlier in the path.
         * So we must do a slow check to see if this conversion would be found
         * by CollationGetCollid.
         */
        char       *collname = NameStr(collform->collname);

        visible = (CollationGetCollid(collname) == collid);
    }

    ReleaseSysCache(colltup);

    return visible;
}

Oid ConversionGetConid ( const char *  conname  ) 

Definition at line 2011 of file namespace.c.

References CONNAMENSP, GetSysCacheOid2, lfirst_oid, myTempNamespace, ObjectIdGetDatum, OidIsValid, PointerGetDatum, and recomputeNamespacePath().

Referenced by ConversionIsVisible().

{
    Oid         conid;
    ListCell   *l;

    recomputeNamespacePath();

    foreach(l, activeSearchPath)
    {
        Oid         namespaceId = lfirst_oid(l);

        if (namespaceId == myTempNamespace)
            continue;           /* do not look in temp namespace */

        conid = GetSysCacheOid2(CONNAMENSP,
                                PointerGetDatum(conname),
                                ObjectIdGetDatum(namespaceId));
        if (OidIsValid(conid))
            return conid;
    }

    /* Not found in path */
    return InvalidOid;
}

bool ConversionIsVisible ( Oid  conid  ) 

Definition at line 2043 of file namespace.c.

References ConversionGetConid(), CONVOID, elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_member_oid(), NameStr, ObjectIdGetDatum, PG_CATALOG_NAMESPACE, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1.

Referenced by pg_conversion_is_visible().

{
    HeapTuple   contup;
    Form_pg_conversion conform;
    Oid         connamespace;
    bool        visible;

    contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid));
    if (!HeapTupleIsValid(contup))
        elog(ERROR, "cache lookup failed for conversion %u", conid);
    conform = (Form_pg_conversion) GETSTRUCT(contup);

    recomputeNamespacePath();

    /*
     * Quick check: if it ain't in the path at all, it ain't visible. Items in
     * the system namespace are surely in the path and so we needn't even do
     * list_member_oid() for them.
     */
    connamespace = conform->connamespace;
    if (connamespace != PG_CATALOG_NAMESPACE &&
        !list_member_oid(activeSearchPath, connamespace))
        visible = false;
    else
    {
        /*
         * If it is in the path, it might still not be visible; it could be
         * hidden by another conversion of the same name earlier in the path.
         * So we must do a slow check to see if this conversion would be found
         * by ConversionGetConid.
         */
        char       *conname = NameStr(conform->conname);

        visible = (ConversionGetConid(conname) == conid);
    }

    ReleaseSysCache(contup);

    return visible;
}

OverrideSearchPath* CopyOverrideSearchPath ( OverrideSearchPath path  ) 

Definition at line 3113 of file namespace.c.

References OverrideSearchPath::addCatalog, OverrideSearchPath::addTemp, list_copy(), palloc(), and OverrideSearchPath::schemas.

Referenced by CopyCachedPlan().

{
    OverrideSearchPath *result;

    result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
    result->schemas = list_copy(path->schemas);
    result->addCatalog = path->addCatalog;
    result->addTemp = path->addTemp;

    return result;
}

void DeconstructQualifiedName ( List names,
char **  nspname_p,
char **  objname_p 
)

Definition at line 2599 of file namespace.c.

References ereport, errcode(), errmsg(), ERROR, get_database_name(), linitial, list_length(), lsecond, lthird, MyDatabaseId, NameListToString(), and strVal.

Referenced by FuncnameGetCandidates(), get_collation_oid(), get_conversion_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), GetIndexOpClass(), LookupTypeName(), make_oper_cache_key(), OpClassCacheLookup(), OpernameGetCandidates(), OpernameGetOprid(), OpFamilyCacheLookup(), and QualifiedNameGetCreationNamespace().

{
    char       *catalogname;
    char       *schemaname = NULL;
    char       *objname = NULL;

    switch (list_length(names))
    {
        case 1:
            objname = strVal(linitial(names));
            break;
        case 2:
            schemaname = strVal(linitial(names));
            objname = strVal(lsecond(names));
            break;
        case 3:
            catalogname = strVal(linitial(names));
            schemaname = strVal(lsecond(names));
            objname = strVal(lthird(names));

            /*
             * We check the catalog name and then ignore it.
             */
            if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
                ereport(ERROR,
                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                  errmsg("cross-database references are not implemented: %s",
                         NameListToString(names))));
            break;
        default:
            ereport(ERROR,
                    (errcode(ERRCODE_SYNTAX_ERROR),
                errmsg("improper qualified name (too many dotted names): %s",
                       NameListToString(names))));
            break;
    }

    *nspname_p = schemaname;
    *objname_p = objname;
}

List* fetch_search_path ( bool  includeImplicit  ) 

Definition at line 3945 of file namespace.c.

References activeCreationNamespace, activeTempCreationPending, InitTempTableNamespace(), linitial_oid, list_copy(), list_delete_first(), and recomputeNamespacePath().

Referenced by AfterTriggerSetState(), CreateExtension(), current_schema(), and current_schemas().

{
    List       *result;

    recomputeNamespacePath();

    /*
     * If the temp namespace should be first, force it to exist.  This is so
     * that callers can trust the result to reflect the actual default
     * creation namespace.  It's a bit bogus to do this here, since
     * current_schema() is supposedly a stable function without side-effects,
     * but the alternatives seem worse.
     */
    if (activeTempCreationPending)
    {
        InitTempTableNamespace();
        recomputeNamespacePath();
    }

    result = list_copy(activeSearchPath);
    if (!includeImplicit)
    {
        while (result && linitial_oid(result) != activeCreationNamespace)
            result = list_delete_first(result);
    }

    return result;
}

int fetch_search_path_array ( Oid sarray,
int  sarray_len 
)

Definition at line 3985 of file namespace.c.

References lfirst_oid, myTempNamespace, and recomputeNamespacePath().

Referenced by make_oper_cache_key().

{
    int         count = 0;
    ListCell   *l;

    recomputeNamespacePath();

    foreach(l, activeSearchPath)
    {
        Oid         namespaceId = lfirst_oid(l);

        if (namespaceId == myTempNamespace)
            continue;           /* do not include temp namespace */

        if (count < sarray_len)
            sarray[count] = namespaceId;
        count++;
    }

    return count;
}

Oid FindDefaultConversionProc ( int32  for_encoding,
int32  to_encoding 
)

Definition at line 3390 of file namespace.c.

References FindDefaultConversion(), lfirst_oid, myTempNamespace, OidIsValid, and recomputeNamespacePath().

Referenced by pg_do_encoding_conversion(), and PrepareClientEncoding().

{
    Oid         proc;
    ListCell   *l;

    recomputeNamespacePath();

    foreach(l, activeSearchPath)
    {
        Oid         namespaceId = lfirst_oid(l);

        if (namespaceId == myTempNamespace)
            continue;           /* do not look in temp namespace */

        proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
        if (OidIsValid(proc))
            return proc;
    }

    /* Not found in path */
    return InvalidOid;
}

FuncCandidateList FuncnameGetCandidates ( List names,
int  nargs,
List argnames,
bool  expand_variadic,
bool  expand_defaults 
)

Definition at line 910 of file namespace.c.

References _FuncCandidateList::argnumbers, _FuncCandidateList::args, Assert, CStringGetDatum, DeconstructQualifiedName(), GETSTRUCT, HeapTupleGetOid, i, lfirst_oid, LookupExplicitNamespace(), MatchNamedCall(), Max, catclist::members, memcmp(), myTempNamespace, catclist::n_members, _FuncCandidateList::nargs, _FuncCandidateList::ndargs, _FuncCandidateList::next, NIL, NULL, _FuncCandidateList::nvargs, _FuncCandidateList::oid, OidIsValid, catclist::ordered, palloc(), _FuncCandidateList::pathpos, pfree(), PROCNAMEARGSNSP, recomputeNamespacePath(), ReleaseSysCacheList, SearchSysCacheList1, and catctup::tuple.

Referenced by func_get_detail(), FunctionIsVisible(), LookupFuncName(), regprocedurein(), regprocin(), and regprocout().

{
    FuncCandidateList resultList = NULL;
    bool        any_special = false;
    char       *schemaname;
    char       *funcname;
    Oid         namespaceId;
    CatCList   *catlist;
    int         i;

    /* check for caller error */
    Assert(nargs >= 0 || !(expand_variadic | expand_defaults));

    /* deconstruct the name list */
    DeconstructQualifiedName(names, &schemaname, &funcname);

    if (schemaname)
    {
        /* use exact schema given */
        namespaceId = LookupExplicitNamespace(schemaname, false);
    }
    else
    {
        /* flag to indicate we need namespace search */
        namespaceId = InvalidOid;
        recomputeNamespacePath();
    }

    /* Search syscache by name only */
    catlist = SearchSysCacheList1(PROCNAMEARGSNSP, CStringGetDatum(funcname));

    for (i = 0; i < catlist->n_members; i++)
    {
        HeapTuple   proctup = &catlist->members[i]->tuple;
        Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
        int         pronargs = procform->pronargs;
        int         effective_nargs;
        int         pathpos = 0;
        bool        variadic;
        bool        use_defaults;
        Oid         va_elem_type;
        int        *argnumbers = NULL;
        FuncCandidateList newResult;

        if (OidIsValid(namespaceId))
        {
            /* Consider only procs in specified namespace */
            if (procform->pronamespace != namespaceId)
                continue;
        }
        else
        {
            /*
             * Consider only procs that are in the search path and are not in
             * the temp namespace.
             */
            ListCell   *nsp;

            foreach(nsp, activeSearchPath)
            {
                if (procform->pronamespace == lfirst_oid(nsp) &&
                    procform->pronamespace != myTempNamespace)
                    break;
                pathpos++;
            }
            if (nsp == NULL)
                continue;       /* proc is not in search path */
        }

        if (argnames != NIL)
        {
            /*
             * Call uses named or mixed notation
             *
             * Named or mixed notation can match a variadic function only if
             * expand_variadic is off; otherwise there is no way to match the
             * presumed-nameless parameters expanded from the variadic array.
             */
            if (OidIsValid(procform->provariadic) && expand_variadic)
                continue;
            va_elem_type = InvalidOid;
            variadic = false;

            /*
             * Check argument count.
             */
            Assert(nargs >= 0); /* -1 not supported with argnames */

            if (pronargs > nargs && expand_defaults)
            {
                /* Ignore if not enough default expressions */
                if (nargs + procform->pronargdefaults < pronargs)
                    continue;
                use_defaults = true;
            }
            else
                use_defaults = false;

            /* Ignore if it doesn't match requested argument count */
            if (pronargs != nargs && !use_defaults)
                continue;

            /* Check for argument name match, generate positional mapping */
            if (!MatchNamedCall(proctup, nargs, argnames,
                                &argnumbers))
                continue;

            /* Named argument matching is always "special" */
            any_special = true;
        }
        else
        {
            /*
             * Call uses positional notation
             *
             * Check if function is variadic, and get variadic element type if
             * so.  If expand_variadic is false, we should just ignore
             * variadic-ness.
             */
            if (pronargs <= nargs && expand_variadic)
            {
                va_elem_type = procform->provariadic;
                variadic = OidIsValid(va_elem_type);
                any_special |= variadic;
            }
            else
            {
                va_elem_type = InvalidOid;
                variadic = false;
            }

            /*
             * Check if function can match by using parameter defaults.
             */
            if (pronargs > nargs && expand_defaults)
            {
                /* Ignore if not enough default expressions */
                if (nargs + procform->pronargdefaults < pronargs)
                    continue;
                use_defaults = true;
                any_special = true;
            }
            else
                use_defaults = false;

            /* Ignore if it doesn't match requested argument count */
            if (nargs >= 0 && pronargs != nargs && !variadic && !use_defaults)
                continue;
        }

        /*
         * We must compute the effective argument list so that we can easily
         * compare it to earlier results.  We waste a palloc cycle if it gets
         * masked by an earlier result, but really that's a pretty infrequent
         * case so it's not worth worrying about.
         */
        effective_nargs = Max(pronargs, nargs);
        newResult = (FuncCandidateList)
            palloc(sizeof(struct _FuncCandidateList) - sizeof(Oid)
                   + effective_nargs * sizeof(Oid));
        newResult->pathpos = pathpos;
        newResult->oid = HeapTupleGetOid(proctup);
        newResult->nargs = effective_nargs;
        newResult->argnumbers = argnumbers;
        if (argnumbers)
        {
            /* Re-order the argument types into call's logical order */
            Oid        *proargtypes = procform->proargtypes.values;
            int         i;

            for (i = 0; i < pronargs; i++)
                newResult->args[i] = proargtypes[argnumbers[i]];
        }
        else
        {
            /* Simple positional case, just copy proargtypes as-is */
            memcpy(newResult->args, procform->proargtypes.values,
                   pronargs * sizeof(Oid));
        }
        if (variadic)
        {
            int         i;

            newResult->nvargs = effective_nargs - pronargs + 1;
            /* Expand variadic argument into N copies of element type */
            for (i = pronargs - 1; i < effective_nargs; i++)
                newResult->args[i] = va_elem_type;
        }
        else
            newResult->nvargs = 0;
        newResult->ndargs = use_defaults ? pronargs - nargs : 0;

        /*
         * Does it have the same arguments as something we already accepted?
         * If so, decide what to do to avoid returning duplicate argument
         * lists.  We can skip this check for the single-namespace case if no
         * special (named, variadic or defaults) match has been made, since
         * then the unique index on pg_proc guarantees all the matches have
         * different argument lists.
         */
        if (resultList != NULL &&
            (any_special || !OidIsValid(namespaceId)))
        {
            /*
             * If we have an ordered list from SearchSysCacheList (the normal
             * case), then any conflicting proc must immediately adjoin this
             * one in the list, so we only need to look at the newest result
             * item.  If we have an unordered list, we have to scan the whole
             * result list.  Also, if either the current candidate or any
             * previous candidate is a special match, we can't assume that
             * conflicts are adjacent.
             *
             * We ignore defaulted arguments in deciding what is a match.
             */
            FuncCandidateList prevResult;

            if (catlist->ordered && !any_special)
            {
                /* ndargs must be 0 if !any_special */
                if (effective_nargs == resultList->nargs &&
                    memcmp(newResult->args,
                           resultList->args,
                           effective_nargs * sizeof(Oid)) == 0)
                    prevResult = resultList;
                else
                    prevResult = NULL;
            }
            else
            {
                int         cmp_nargs = newResult->nargs - newResult->ndargs;

                for (prevResult = resultList;
                     prevResult;
                     prevResult = prevResult->next)
                {
                    if (cmp_nargs == prevResult->nargs - prevResult->ndargs &&
                        memcmp(newResult->args,
                               prevResult->args,
                               cmp_nargs * sizeof(Oid)) == 0)
                        break;
                }
            }

            if (prevResult)
            {
                /*
                 * We have a match with a previous result.  Decide which one
                 * to keep, or mark it ambiguous if we can't decide.  The
                 * logic here is preference > 0 means prefer the old result,
                 * preference < 0 means prefer the new, preference = 0 means
                 * ambiguous.
                 */
                int         preference;

                if (pathpos != prevResult->pathpos)
                {
                    /*
                     * Prefer the one that's earlier in the search path.
                     */
                    preference = pathpos - prevResult->pathpos;
                }
                else if (variadic && prevResult->nvargs == 0)
                {
                    /*
                     * With variadic functions we could have, for example,
                     * both foo(numeric) and foo(variadic numeric[]) in the
                     * same namespace; if so we prefer the non-variadic match
                     * on efficiency grounds.
                     */
                    preference = 1;
                }
                else if (!variadic && prevResult->nvargs > 0)
                {
                    preference = -1;
                }
                else
                {
                    /*----------
                     * We can't decide.  This can happen with, for example,
                     * both foo(numeric, variadic numeric[]) and
                     * foo(variadic numeric[]) in the same namespace, or
                     * both foo(int) and foo (int, int default something)
                     * in the same namespace, or both foo(a int, b text)
                     * and foo(b text, a int) in the same namespace.
                     *----------
                     */
                    preference = 0;
                }

                if (preference > 0)
                {
                    /* keep previous result */
                    pfree(newResult);
                    continue;
                }
                else if (preference < 0)
                {
                    /* remove previous result from the list */
                    if (prevResult == resultList)
                        resultList = prevResult->next;
                    else
                    {
                        FuncCandidateList prevPrevResult;

                        for (prevPrevResult = resultList;
                             prevPrevResult;
                             prevPrevResult = prevPrevResult->next)
                        {
                            if (prevResult == prevPrevResult->next)
                            {
                                prevPrevResult->next = prevResult->next;
                                break;
                            }
                        }
                        Assert(prevPrevResult); /* assert we found it */
                    }
                    pfree(prevResult);
                    /* fall through to add newResult to list */
                }
                else
                {
                    /* mark old result as ambiguous, discard new */
                    prevResult->oid = InvalidOid;
                    pfree(newResult);
                    continue;
                }
            }
        }

        /*
         * Okay to add it to result list
         */
        newResult->next = resultList;
        resultList = newResult;
    }

    ReleaseSysCacheList(catlist);

    return resultList;
}

bool FunctionIsVisible ( Oid  funcid  ) 

Definition at line 1378 of file namespace.c.

References _FuncCandidateList::args, elog, ERROR, FuncnameGetCandidates(), GETSTRUCT, HeapTupleIsValid, list_make1, list_member_oid(), makeString(), memcmp(), NameStr, _FuncCandidateList::next, NIL, ObjectIdGetDatum, _FuncCandidateList::oid, PG_CATALOG_NAMESPACE, PROCOID, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1.

Referenced by format_procedure_internal(), and pg_function_is_visible().

{
    HeapTuple   proctup;
    Form_pg_proc procform;
    Oid         pronamespace;
    bool        visible;

    proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
    if (!HeapTupleIsValid(proctup))
        elog(ERROR, "cache lookup failed for function %u", funcid);
    procform = (Form_pg_proc) GETSTRUCT(proctup);

    recomputeNamespacePath();

    /*
     * Quick check: if it ain't in the path at all, it ain't visible. Items in
     * the system namespace are surely in the path and so we needn't even do
     * list_member_oid() for them.
     */
    pronamespace = procform->pronamespace;
    if (pronamespace != PG_CATALOG_NAMESPACE &&
        !list_member_oid(activeSearchPath, pronamespace))
        visible = false;
    else
    {
        /*
         * If it is in the path, it might still not be visible; it could be
         * hidden by another proc of the same name and arguments earlier in
         * the path.  So we must do a slow check to see if this is the same
         * proc that would be found by FuncnameGetCandidates.
         */
        char       *proname = NameStr(procform->proname);
        int         nargs = procform->pronargs;
        FuncCandidateList clist;

        visible = false;

        clist = FuncnameGetCandidates(list_make1(makeString(proname)),
                                      nargs, NIL, false, false);

        for (; clist; clist = clist->next)
        {
            if (memcmp(clist->args, procform->proargtypes.values,
                       nargs * sizeof(Oid)) == 0)
            {
                /* Found the expected entry; is it the right proc? */
                visible = (clist->oid == funcid);
                break;
            }
        }
    }

    ReleaseSysCache(proctup);

    return visible;
}

Oid get_collation_oid ( List collname,
bool  missing_ok 
)

Definition at line 3262 of file namespace.c.

References COLLNAMEENCNSP, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetDatabaseEncoding(), GetDatabaseEncodingName(), GetSysCacheOid3, Int32GetDatum, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum, OidIsValid, PointerGetDatum, and recomputeNamespacePath().

Referenced by ComputeIndexAttrs(), DefineCollation(), DefineDomain(), DefineRange(), get_object_address(), and LookupCollation().

{
    char       *schemaname;
    char       *collation_name;
    int32       dbencoding = GetDatabaseEncoding();
    Oid         namespaceId;
    Oid         colloid;
    ListCell   *l;

    /* deconstruct the name list */
    DeconstructQualifiedName(name, &schemaname, &collation_name);

    if (schemaname)
    {
        /* use exact schema given */
        namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
        if (missing_ok && !OidIsValid(namespaceId))
            return InvalidOid;

        /* first try for encoding-specific entry, then any-encoding */
        colloid = GetSysCacheOid3(COLLNAMEENCNSP,
                                  PointerGetDatum(collation_name),
                                  Int32GetDatum(dbencoding),
                                  ObjectIdGetDatum(namespaceId));
        if (OidIsValid(colloid))
            return colloid;
        colloid = GetSysCacheOid3(COLLNAMEENCNSP,
                                  PointerGetDatum(collation_name),
                                  Int32GetDatum(-1),
                                  ObjectIdGetDatum(namespaceId));
        if (OidIsValid(colloid))
            return colloid;
    }
    else
    {
        /* search for it in search path */
        recomputeNamespacePath();

        foreach(l, activeSearchPath)
        {
            namespaceId = lfirst_oid(l);

            if (namespaceId == myTempNamespace)
                continue;       /* do not look in temp namespace */

            colloid = GetSysCacheOid3(COLLNAMEENCNSP,
                                      PointerGetDatum(collation_name),
                                      Int32GetDatum(dbencoding),
                                      ObjectIdGetDatum(namespaceId));
            if (OidIsValid(colloid))
                return colloid;
            colloid = GetSysCacheOid3(COLLNAMEENCNSP,
                                      PointerGetDatum(collation_name),
                                      Int32GetDatum(-1),
                                      ObjectIdGetDatum(namespaceId));
            if (OidIsValid(colloid))
                return colloid;
        }
    }

    /* Not found in path */
    if (!missing_ok)
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_OBJECT),
                 errmsg("collation \"%s\" for encoding \"%s\" does not exist",
                        NameListToString(name), GetDatabaseEncodingName())));
    return InvalidOid;
}

Oid get_conversion_oid ( List conname,
bool  missing_ok 
)

Definition at line 3335 of file namespace.c.

References CONNAMENSP, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum, OidIsValid, PointerGetDatum, and recomputeNamespacePath().

Referenced by get_object_address().

{
    char       *schemaname;
    char       *conversion_name;
    Oid         namespaceId;
    Oid         conoid = InvalidOid;
    ListCell   *l;

    /* deconstruct the name list */
    DeconstructQualifiedName(name, &schemaname, &conversion_name);

    if (schemaname)
    {
        /* use exact schema given */
        namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
        if (missing_ok && !OidIsValid(namespaceId))
            conoid = InvalidOid;
        else
            conoid = GetSysCacheOid2(CONNAMENSP,
                                     PointerGetDatum(conversion_name),
                                     ObjectIdGetDatum(namespaceId));
    }
    else
    {
        /* search for it in search path */
        recomputeNamespacePath();

        foreach(l, activeSearchPath)
        {
            namespaceId = lfirst_oid(l);

            if (namespaceId == myTempNamespace)
                continue;       /* do not look in temp namespace */

            conoid = GetSysCacheOid2(CONNAMENSP,
                                     PointerGetDatum(conversion_name),
                                     ObjectIdGetDatum(namespaceId));
            if (OidIsValid(conoid))
                return conoid;
        }
    }

    /* Not found in path */
    if (!OidIsValid(conoid) && !missing_ok)
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_OBJECT),
                 errmsg("conversion \"%s\" does not exist",
                        NameListToString(name))));
    return conoid;
}

Oid get_namespace_oid ( const char *  nspname,
bool  missing_ok 
)
Oid get_ts_config_oid ( List names,
bool  missing_ok 
)

Definition at line 2469 of file namespace.c.

References DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum, OidIsValid, PointerGetDatum, recomputeNamespacePath(), and TSCONFIGNAMENSP.

Referenced by check_TSCurrentConfig(), DefineTSConfiguration(), get_object_address(), GetTSConfigTuple(), getTSCurrentConfig(), regconfigin(), and tsvector_update_trigger().

{
    char       *schemaname;
    char       *config_name;
    Oid         namespaceId;
    Oid         cfgoid = InvalidOid;
    ListCell   *l;

    /* deconstruct the name list */
    DeconstructQualifiedName(names, &schemaname, &config_name);

    if (schemaname)
    {
        /* use exact schema given */
        namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
        if (missing_ok && !OidIsValid(namespaceId))
            cfgoid = InvalidOid;
        else
            cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP,
                                     PointerGetDatum(config_name),
                                     ObjectIdGetDatum(namespaceId));
    }
    else
    {
        /* search for it in search path */
        recomputeNamespacePath();

        foreach(l, activeSearchPath)
        {
            namespaceId = lfirst_oid(l);

            if (namespaceId == myTempNamespace)
                continue;       /* do not look in temp namespace */

            cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP,
                                     PointerGetDatum(config_name),
                                     ObjectIdGetDatum(namespaceId));
            if (OidIsValid(cfgoid))
                break;
        }
    }

    if (!OidIsValid(cfgoid) && !missing_ok)
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_OBJECT),
                 errmsg("text search configuration \"%s\" does not exist",
                        NameListToString(names))));

    return cfgoid;
}

Oid get_ts_dict_oid ( List names,
bool  missing_ok 
)

Definition at line 2216 of file namespace.c.

References DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum, OidIsValid, PointerGetDatum, recomputeNamespacePath(), and TSDICTNAMENSP.

Referenced by AlterTSDictionary(), get_object_address(), MakeConfigurationMapping(), regdictionaryin(), thesaurus_init(), tsa_set_curdict_byname(), and unaccent_dict().

{
    char       *schemaname;
    char       *dict_name;
    Oid         namespaceId;
    Oid         dictoid = InvalidOid;
    ListCell   *l;

    /* deconstruct the name list */
    DeconstructQualifiedName(names, &schemaname, &dict_name);

    if (schemaname)
    {
        /* use exact schema given */
        namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
        if (missing_ok && !OidIsValid(namespaceId))
            dictoid = InvalidOid;
        else
            dictoid = GetSysCacheOid2(TSDICTNAMENSP,
                                      PointerGetDatum(dict_name),
                                      ObjectIdGetDatum(namespaceId));
    }
    else
    {
        /* search for it in search path */
        recomputeNamespacePath();

        foreach(l, activeSearchPath)
        {
            namespaceId = lfirst_oid(l);

            if (namespaceId == myTempNamespace)
                continue;       /* do not look in temp namespace */

            dictoid = GetSysCacheOid2(TSDICTNAMENSP,
                                      PointerGetDatum(dict_name),
                                      ObjectIdGetDatum(namespaceId));
            if (OidIsValid(dictoid))
                break;
        }
    }

    if (!OidIsValid(dictoid) && !missing_ok)
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_OBJECT),
                 errmsg("text search dictionary \"%s\" does not exist",
                        NameListToString(names))));

    return dictoid;
}

Oid get_ts_parser_oid ( List names,
bool  missing_ok 
)

Definition at line 2090 of file namespace.c.

References DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum, OidIsValid, PointerGetDatum, recomputeNamespacePath(), and TSPARSERNAMENSP.

Referenced by DefineTSConfiguration(), get_object_address(), GetCurrentParser(), ts_parse_byname(), ts_token_type_byname(), and tsa_set_curprs_byname().

{
    char       *schemaname;
    char       *parser_name;
    Oid         namespaceId;
    Oid         prsoid = InvalidOid;
    ListCell   *l;

    /* deconstruct the name list */
    DeconstructQualifiedName(names, &schemaname, &parser_name);

    if (schemaname)
    {
        /* use exact schema given */
        namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
        if (missing_ok && !OidIsValid(namespaceId))
            prsoid = InvalidOid;
        else
            prsoid = GetSysCacheOid2(TSPARSERNAMENSP,
                                     PointerGetDatum(parser_name),
                                     ObjectIdGetDatum(namespaceId));
    }
    else
    {
        /* search for it in search path */
        recomputeNamespacePath();

        foreach(l, activeSearchPath)
        {
            namespaceId = lfirst_oid(l);

            if (namespaceId == myTempNamespace)
                continue;       /* do not look in temp namespace */

            prsoid = GetSysCacheOid2(TSPARSERNAMENSP,
                                     PointerGetDatum(parser_name),
                                     ObjectIdGetDatum(namespaceId));
            if (OidIsValid(prsoid))
                break;
        }
    }

    if (!OidIsValid(prsoid) && !missing_ok)
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_OBJECT),
                 errmsg("text search parser \"%s\" does not exist",
                        NameListToString(names))));

    return prsoid;
}

Oid get_ts_template_oid ( List names,
bool  missing_ok 
)

Definition at line 2343 of file namespace.c.

References DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, GetSysCacheOid2, lfirst_oid, LookupExplicitNamespace(), myTempNamespace, NameListToString(), ObjectIdGetDatum, OidIsValid, PointerGetDatum, recomputeNamespacePath(), and TSTEMPLATENAMENSP.

Referenced by DefineTSDictionary(), and get_object_address().

{
    char       *schemaname;
    char       *template_name;
    Oid         namespaceId;
    Oid         tmploid = InvalidOid;
    ListCell   *l;

    /* deconstruct the name list */
    DeconstructQualifiedName(names, &schemaname, &template_name);

    if (schemaname)
    {
        /* use exact schema given */
        namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
        if (missing_ok && !OidIsValid(namespaceId))
            tmploid = InvalidOid;
        else
            tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP,
                                      PointerGetDatum(template_name),
                                      ObjectIdGetDatum(namespaceId));
    }
    else
    {
        /* search for it in search path */
        recomputeNamespacePath();

        foreach(l, activeSearchPath)
        {
            namespaceId = lfirst_oid(l);

            if (namespaceId == myTempNamespace)
                continue;       /* do not look in temp namespace */

            tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP,
                                      PointerGetDatum(template_name),
                                      ObjectIdGetDatum(namespaceId));
            if (OidIsValid(tmploid))
                break;
        }
    }

    if (!OidIsValid(tmploid) && !missing_ok)
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_OBJECT),
                 errmsg("text search template \"%s\" does not exist",
                        NameListToString(names))));

    return tmploid;
}

OverrideSearchPath* GetOverrideSearchPath ( MemoryContext  context  ) 
int GetTempNamespaceBackendId ( Oid  namespaceId  ) 

Definition at line 3036 of file namespace.c.

References get_namespace_name(), and pfree().

Referenced by do_autovacuum(), pg_relation_filepath(), and RelationBuildDesc().

{
    int         result;
    char       *nspname;

    /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
    nspname = get_namespace_name(namespaceId);
    if (!nspname)
        return InvalidBackendId;    /* no such namespace? */
    if (strncmp(nspname, "pg_temp_", 8) == 0)
        result = atoi(nspname + 8);
    else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
        result = atoi(nspname + 14);
    else
        result = InvalidBackendId;
    pfree(nspname);
    return result;
}

Oid GetTempToastNamespace ( void   ) 

Definition at line 3061 of file namespace.c.

References Assert, myTempToastNamespace, and OidIsValid.

Referenced by create_toast_table().

void InitializeSearchPath ( void   ) 

Definition at line 3887 of file namespace.c.

References activeCreationNamespace, activeTempCreationPending, baseCreationNamespace, baseSearchPathValid, baseTempCreationPending, CacheRegisterSyscacheCallback(), GetUserId(), IsBootstrapProcessingMode, list_make1_oid, MemoryContextSwitchTo(), NamespaceCallback(), NAMESPACEOID, namespaceUser, PG_CATALOG_NAMESPACE, and TopMemoryContext.

Referenced by InitPostgres().

{
    if (IsBootstrapProcessingMode())
    {
        /*
         * In bootstrap mode, the search path must be 'pg_catalog' so that
         * tables are created in the proper namespace; ignore the GUC setting.
         */
        MemoryContext oldcxt;

        oldcxt = MemoryContextSwitchTo(TopMemoryContext);
        baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
        MemoryContextSwitchTo(oldcxt);
        baseCreationNamespace = PG_CATALOG_NAMESPACE;
        baseTempCreationPending = false;
        baseSearchPathValid = true;
        namespaceUser = GetUserId();
        activeSearchPath = baseSearchPath;
        activeCreationNamespace = baseCreationNamespace;
        activeTempCreationPending = baseTempCreationPending;
    }
    else
    {
        /*
         * In normal mode, arrange for a callback on any syscache invalidation
         * of pg_namespace rows.
         */
        CacheRegisterSyscacheCallback(NAMESPACEOID,
                                      NamespaceCallback,
                                      (Datum) 0);
        /* Force search path to be recomputed on next use */
        baseSearchPathValid = false;
    }
}

bool isAnyTempNamespace ( Oid  namespaceId  ) 

Definition at line 2997 of file namespace.c.

References get_namespace_name(), and pfree().

Referenced by CheckSetNamespace(), EventTriggerSQLDropAddObject(), isOtherTempNamespace(), and RangeVarAdjustRelationPersistence().

{
    bool        result;
    char       *nspname;

    /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
    nspname = get_namespace_name(namespaceId);
    if (!nspname)
        return false;           /* no such namespace? */
    result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
        (strncmp(nspname, "pg_toast_temp_", 14) == 0);
    pfree(nspname);
    return result;
}

bool isOtherTempNamespace ( Oid  namespaceId  ) 

Definition at line 3020 of file namespace.c.

References isAnyTempNamespace(), and isTempOrToastNamespace().

Referenced by pg_is_other_temp_schema().

{
    /* If it's my own temp namespace, say "false" */
    if (isTempOrToastNamespace(namespaceId))
        return false;
    /* Else, if it's any temp namespace, say "true" */
    return isAnyTempNamespace(namespaceId);
}

bool isTempNamespace ( Oid  namespaceId  ) 

Definition at line 2959 of file namespace.c.

References myTempNamespace, and OidIsValid.

Referenced by ExecCheckXactReadOnly(), pg_namespace_aclmask(), and ReindexDatabase().

{
    if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
        return true;
    return false;
}

bool isTempOrToastNamespace ( Oid  namespaceId  ) 
bool isTempToastNamespace ( Oid  namespaceId  ) 

Definition at line 2971 of file namespace.c.

References myTempToastNamespace, and OidIsValid.

Referenced by IsToastNamespace().

{
    if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
        return true;
    return false;
}

Oid LookupCreationNamespace ( const char *  nspname  ) 

Definition at line 2726 of file namespace.c.

References ACL_CREATE, ACL_KIND_NAMESPACE, aclcheck_error(), ACLCHECK_OK, get_namespace_oid(), GetUserId(), InitTempTableNamespace(), myTempNamespace, OidIsValid, and pg_namespace_aclcheck().

Referenced by AlterExtensionNamespace(), AlterTypeNamespace(), and ExecAlterObjectSchemaStmt().

{
    Oid         namespaceId;
    AclResult   aclresult;

    /* check for pg_temp alias */
    if (strcmp(nspname, "pg_temp") == 0)
    {
        /* Initialize temp namespace if first time through */
        if (!OidIsValid(myTempNamespace))
            InitTempTableNamespace();
        return myTempNamespace;
    }

    namespaceId = get_namespace_oid(nspname, false);

    aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
    if (aclresult != ACLCHECK_OK)
        aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
                       nspname);

    return namespaceId;
}

Oid LookupExplicitNamespace ( const char *  nspname,
bool  missing_ok 
)

Definition at line 2683 of file namespace.c.

References ACL_KIND_NAMESPACE, ACL_USAGE, aclcheck_error(), ACLCHECK_OK, get_namespace_oid(), GetUserId(), InvokeNamespaceSearchHook, myTempNamespace, OidIsValid, and pg_namespace_aclcheck().

Referenced by AfterTriggerSetState(), FuncnameGetCandidates(), get_collation_oid(), get_conversion_oid(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), GetIndexOpClass(), LookupTypeName(), make_oper_cache_key(), objectsInSchemaToOids(), OpClassCacheLookup(), OpernameGetCandidates(), OpernameGetOprid(), OpFamilyCacheLookup(), RangeVarGetRelidExtended(), schema_to_xml(), schema_to_xml_and_xmlschema(), and schema_to_xmlschema_internal().

{
    Oid         namespaceId;
    AclResult   aclresult;

    /* check for pg_temp alias */
    if (strcmp(nspname, "pg_temp") == 0)
    {
        if (OidIsValid(myTempNamespace))
            return myTempNamespace;

        /*
         * Since this is used only for looking up existing objects, there is
         * no point in trying to initialize the temp namespace here; and doing
         * so might create problems for some callers --- just fall through.
         */
    }

    namespaceId = get_namespace_oid(nspname, missing_ok);
    if (missing_ok && !OidIsValid(namespaceId))
        return InvalidOid;
    
    aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_USAGE);
    if (aclresult != ACLCHECK_OK)
        aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
                       nspname);
    /* Schema search hook for this lookup */
    InvokeNamespaceSearchHook(namespaceId, true);

    return namespaceId;
}

Oid LookupNamespaceNoError ( const char *  nspname  ) 

Definition at line 2653 of file namespace.c.

References get_namespace_oid(), InvokeNamespaceSearchHook, myTempNamespace, and OidIsValid.

Referenced by refnameRangeTblEntry().

{
    /* check for pg_temp alias */
    if (strcmp(nspname, "pg_temp") == 0)
    {
        if (OidIsValid(myTempNamespace))
        {
            InvokeNamespaceSearchHook(myTempNamespace, true);
            return myTempNamespace;
        }

        /*
         * Since this is used only for looking up existing objects, there is
         * no point in trying to initialize the temp namespace here; and doing
         * so might create problems for some callers. Just report "not found".
         */
        return InvalidOid;
    }

    return get_namespace_oid(nspname, true);
}

RangeVar* makeRangeVarFromNameList ( List names  ) 
char* NameListToQuotedString ( List names  ) 

Definition at line 2938 of file namespace.c.

References appendStringInfoChar(), appendStringInfoString(), initStringInfo(), lfirst, list_head(), quote_identifier(), and strVal.

{
    StringInfoData string;
    ListCell   *l;

    initStringInfo(&string);

    foreach(l, names)
    {
        if (l != list_head(names))
            appendStringInfoChar(&string, '.');
        appendStringInfoString(&string, quote_identifier(strVal(lfirst(l))));
    }

    return string.data;
}

char* NameListToString ( List names  ) 

Definition at line 2904 of file namespace.c.

References appendStringInfoChar(), appendStringInfoString(), elog, ERROR, initStringInfo(), IsA, lfirst, list_head(), name, nodeTag, and strVal.

Referenced by AggregateCreate(), AlterFunction(), AlterTSConfiguration(), AlterTSDictionary(), check_object_ownership(), CreateConversionCommand(), CreateEventTrigger(), CreateProceduralLanguage(), CreateTrigger(), DeconstructQualifiedName(), defGetString(), DefineOperator(), DefineType(), does_not_exist_skipping(), dropOperators(), dropProcedures(), ExpandColumnRefStar(), findRangeSubOpclass(), findTypeAnalyzeFunction(), findTypeInputFunction(), findTypeOutputFunction(), findTypeTypmodinFunction(), findTypeTypmodoutFunction(), func_signature_string(), get_collation_oid(), get_conversion_oid(), get_object_address_attribute(), get_ts_config_oid(), get_ts_dict_oid(), get_ts_parser_oid(), get_ts_template_oid(), GetIndexOpClass(), lookup_fdw_handler_func(), LookupAggNameTypeNames(), LookupTypeName(), makeRangeVarFromNameList(), op_signature_string(), OpClassCacheLookup(), OperatorCreate(), OpFamilyCacheLookup(), ParseFuncOrColumn(), plpgsql_post_column_ref(), RemoveObjects(), storeOperators(), storeProcedures(), and transformColumnRef().

{
    StringInfoData string;
    ListCell   *l;

    initStringInfo(&string);

    foreach(l, names)
    {
        Node       *name = (Node *) lfirst(l);

        if (l != list_head(names))
            appendStringInfoChar(&string, '.');

        if (IsA(name, String))
            appendStringInfoString(&string, strVal(name));
        else if (IsA(name, A_Star))
            appendStringInfoString(&string, "*");
        else
            elog(ERROR, "unexpected node type in name list: %d",
                 (int) nodeTag(name));
    }

    return string.data;
}

bool OpclassIsVisible ( Oid  opcid  ) 

Definition at line 1788 of file namespace.c.

References CLAOID, elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_member_oid(), NameStr, ObjectIdGetDatum, OpclassnameGetOpcid(), PG_CATALOG_NAMESPACE, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1.

Referenced by get_opclass_name(), getObjectDescription(), and pg_opclass_is_visible().

{
    HeapTuple   opctup;
    Form_pg_opclass opcform;
    Oid         opcnamespace;
    bool        visible;

    opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid));
    if (!HeapTupleIsValid(opctup))
        elog(ERROR, "cache lookup failed for opclass %u", opcid);
    opcform = (Form_pg_opclass) GETSTRUCT(opctup);

    recomputeNamespacePath();

    /*
     * Quick check: if it ain't in the path at all, it ain't visible. Items in
     * the system namespace are surely in the path and so we needn't even do
     * list_member_oid() for them.
     */
    opcnamespace = opcform->opcnamespace;
    if (opcnamespace != PG_CATALOG_NAMESPACE &&
        !list_member_oid(activeSearchPath, opcnamespace))
        visible = false;
    else
    {
        /*
         * If it is in the path, it might still not be visible; it could be
         * hidden by another opclass of the same name earlier in the path. So
         * we must do a slow check to see if this opclass would be found by
         * OpclassnameGetOpcid.
         */
        char       *opcname = NameStr(opcform->opcname);

        visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid);
    }

    ReleaseSysCache(opctup);

    return visible;
}

Oid OpclassnameGetOpcid ( Oid  amid,
const char *  opcname 
)

Definition at line 1755 of file namespace.c.

References CLAAMNAMENSP, GetSysCacheOid3, lfirst_oid, myTempNamespace, ObjectIdGetDatum, OidIsValid, PointerGetDatum, and recomputeNamespacePath().

Referenced by GetIndexOpClass(), OpClassCacheLookup(), and OpclassIsVisible().

{
    Oid         opcid;
    ListCell   *l;

    recomputeNamespacePath();

    foreach(l, activeSearchPath)
    {
        Oid         namespaceId = lfirst_oid(l);

        if (namespaceId == myTempNamespace)
            continue;           /* do not look in temp namespace */

        opcid = GetSysCacheOid3(CLAAMNAMENSP,
                                ObjectIdGetDatum(amid),
                                PointerGetDatum(opcname),
                                ObjectIdGetDatum(namespaceId));
        if (OidIsValid(opcid))
            return opcid;
    }

    /* Not found in path */
    return InvalidOid;
}

bool OperatorIsVisible ( Oid  oprid  ) 

Definition at line 1702 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_make1, list_member_oid(), makeString(), NameStr, ObjectIdGetDatum, OpernameGetOprid(), OPEROID, PG_CATALOG_NAMESPACE, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1.

Referenced by format_operator_internal(), and pg_operator_is_visible().

{
    HeapTuple   oprtup;
    Form_pg_operator oprform;
    Oid         oprnamespace;
    bool        visible;

    oprtup = SearchSysCache1(OPEROID, ObjectIdGetDatum(oprid));
    if (!HeapTupleIsValid(oprtup))
        elog(ERROR, "cache lookup failed for operator %u", oprid);
    oprform = (Form_pg_operator) GETSTRUCT(oprtup);

    recomputeNamespacePath();

    /*
     * Quick check: if it ain't in the path at all, it ain't visible. Items in
     * the system namespace are surely in the path and so we needn't even do
     * list_member_oid() for them.
     */
    oprnamespace = oprform->oprnamespace;
    if (oprnamespace != PG_CATALOG_NAMESPACE &&
        !list_member_oid(activeSearchPath, oprnamespace))
        visible = false;
    else
    {
        /*
         * If it is in the path, it might still not be visible; it could be
         * hidden by another operator of the same name and arguments earlier
         * in the path.  So we must do a slow check to see if this is the same
         * operator that would be found by OpernameGetOprId.
         */
        char       *oprname = NameStr(oprform->oprname);

        visible = (OpernameGetOprid(list_make1(makeString(oprname)),
                                    oprform->oprleft, oprform->oprright)
                   == oprid);
    }

    ReleaseSysCache(oprtup);

    return visible;
}

FuncCandidateList OpernameGetCandidates ( List names,
char  oprkind 
)

Definition at line 1545 of file namespace.c.

References _FuncCandidateList::argnumbers, _FuncCandidateList::args, Assert, CStringGetDatum, DeconstructQualifiedName(), GETSTRUCT, HeapTupleGetOid, i, lfirst_oid, LookupExplicitNamespace(), catclist::members, myTempNamespace, catclist::n_members, _FuncCandidateList::nargs, _FuncCandidateList::ndargs, _FuncCandidateList::next, NULL, _FuncCandidateList::nvargs, _FuncCandidateList::oid, OidIsValid, OPERNAMENSP, catclist::ordered, palloc(), _FuncCandidateList::pathpos, recomputeNamespacePath(), ReleaseSysCacheList, SearchSysCacheList1, SPACE_PER_OP, and catctup::tuple.

Referenced by left_oper(), oper(), regoperin(), regoperout(), and right_oper().

{
    FuncCandidateList resultList = NULL;
    char       *resultSpace = NULL;
    int         nextResult = 0;
    char       *schemaname;
    char       *opername;
    Oid         namespaceId;
    CatCList   *catlist;
    int         i;

    /* deconstruct the name list */
    DeconstructQualifiedName(names, &schemaname, &opername);

    if (schemaname)
    {
        /* use exact schema given */
        namespaceId = LookupExplicitNamespace(schemaname, false);
    }
    else
    {
        /* flag to indicate we need namespace search */
        namespaceId = InvalidOid;
        recomputeNamespacePath();
    }

    /* Search syscache by name only */
    catlist = SearchSysCacheList1(OPERNAMENSP, CStringGetDatum(opername));

    /*
     * In typical scenarios, most if not all of the operators found by the
     * catcache search will end up getting returned; and there can be quite a
     * few, for common operator names such as '=' or '+'.  To reduce the time
     * spent in palloc, we allocate the result space as an array large enough
     * to hold all the operators.  The original coding of this routine did a
     * separate palloc for each operator, but profiling revealed that the
     * pallocs used an unreasonably large fraction of parsing time.
     */
#define SPACE_PER_OP MAXALIGN(sizeof(struct _FuncCandidateList) + sizeof(Oid))

    if (catlist->n_members > 0)
        resultSpace = palloc(catlist->n_members * SPACE_PER_OP);

    for (i = 0; i < catlist->n_members; i++)
    {
        HeapTuple   opertup = &catlist->members[i]->tuple;
        Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
        int         pathpos = 0;
        FuncCandidateList newResult;

        /* Ignore operators of wrong kind, if specific kind requested */
        if (oprkind && operform->oprkind != oprkind)
            continue;

        if (OidIsValid(namespaceId))
        {
            /* Consider only opers in specified namespace */
            if (operform->oprnamespace != namespaceId)
                continue;
            /* No need to check args, they must all be different */
        }
        else
        {
            /*
             * Consider only opers that are in the search path and are not in
             * the temp namespace.
             */
            ListCell   *nsp;

            foreach(nsp, activeSearchPath)
            {
                if (operform->oprnamespace == lfirst_oid(nsp) &&
                    operform->oprnamespace != myTempNamespace)
                    break;
                pathpos++;
            }
            if (nsp == NULL)
                continue;       /* oper is not in search path */

            /*
             * Okay, it's in the search path, but does it have the same
             * arguments as something we already accepted?  If so, keep only
             * the one that appears earlier in the search path.
             *
             * If we have an ordered list from SearchSysCacheList (the normal
             * case), then any conflicting oper must immediately adjoin this
             * one in the list, so we only need to look at the newest result
             * item.  If we have an unordered list, we have to scan the whole
             * result list.
             */
            if (resultList)
            {
                FuncCandidateList prevResult;

                if (catlist->ordered)
                {
                    if (operform->oprleft == resultList->args[0] &&
                        operform->oprright == resultList->args[1])
                        prevResult = resultList;
                    else
                        prevResult = NULL;
                }
                else
                {
                    for (prevResult = resultList;
                         prevResult;
                         prevResult = prevResult->next)
                    {
                        if (operform->oprleft == prevResult->args[0] &&
                            operform->oprright == prevResult->args[1])
                            break;
                    }
                }
                if (prevResult)
                {
                    /* We have a match with a previous result */
                    Assert(pathpos != prevResult->pathpos);
                    if (pathpos > prevResult->pathpos)
                        continue;       /* keep previous result */
                    /* replace previous result */
                    prevResult->pathpos = pathpos;
                    prevResult->oid = HeapTupleGetOid(opertup);
                    continue;   /* args are same, of course */
                }
            }
        }

        /*
         * Okay to add it to result list
         */
        newResult = (FuncCandidateList) (resultSpace + nextResult);
        nextResult += SPACE_PER_OP;

        newResult->pathpos = pathpos;
        newResult->oid = HeapTupleGetOid(opertup);
        newResult->nargs = 2;
        newResult->nvargs = 0;
        newResult->ndargs = 0;
        newResult->argnumbers = NULL;
        newResult->args[0] = operform->oprleft;
        newResult->args[1] = operform->oprright;
        newResult->next = resultList;
        resultList = newResult;
    }

    ReleaseSysCacheList(catlist);

    return resultList;
}

Oid OpernameGetOprid ( List names,
Oid  oprleft,
Oid  oprright 
)

Definition at line 1448 of file namespace.c.

References CStringGetDatum, DeconstructQualifiedName(), GETSTRUCT, HeapTupleGetOid, HeapTupleIsValid, i, lfirst_oid, LookupExplicitNamespace(), catclist::members, myTempNamespace, catclist::n_members, ObjectIdGetDatum, OPERNAMENSP, recomputeNamespacePath(), ReleaseSysCache(), ReleaseSysCacheList, SearchSysCache4, SearchSysCacheList3, and catctup::tuple.

Referenced by binary_oper_exact(), left_oper(), LookupOperName(), OperatorIsVisible(), regoperatorin(), and right_oper().

{
    char       *schemaname;
    char       *opername;
    CatCList   *catlist;
    ListCell   *l;

    /* deconstruct the name list */
    DeconstructQualifiedName(names, &schemaname, &opername);

    if (schemaname)
    {
        /* search only in exact schema given */
        Oid         namespaceId;
        HeapTuple   opertup;

        namespaceId = LookupExplicitNamespace(schemaname, false);
        opertup = SearchSysCache4(OPERNAMENSP,
                                  CStringGetDatum(opername),
                                  ObjectIdGetDatum(oprleft),
                                  ObjectIdGetDatum(oprright),
                                  ObjectIdGetDatum(namespaceId));
        if (HeapTupleIsValid(opertup))
        {
            Oid         result = HeapTupleGetOid(opertup);

            ReleaseSysCache(opertup);
            return result;
        }
        return InvalidOid;
    }

    /* Search syscache by name and argument types */
    catlist = SearchSysCacheList3(OPERNAMENSP,
                                  CStringGetDatum(opername),
                                  ObjectIdGetDatum(oprleft),
                                  ObjectIdGetDatum(oprright));

    if (catlist->n_members == 0)
    {
        /* no hope, fall out early */
        ReleaseSysCacheList(catlist);
        return InvalidOid;
    }

    /*
     * We have to find the list member that is first in the search path, if
     * there's more than one.  This doubly-nested loop looks ugly, but in
     * practice there should usually be few catlist members.
     */
    recomputeNamespacePath();

    foreach(l, activeSearchPath)
    {
        Oid         namespaceId = lfirst_oid(l);
        int         i;

        if (namespaceId == myTempNamespace)
            continue;           /* do not look in temp namespace */

        for (i = 0; i < catlist->n_members; i++)
        {
            HeapTuple   opertup = &catlist->members[i]->tuple;
            Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);

            if (operform->oprnamespace == namespaceId)
            {
                Oid         result = HeapTupleGetOid(opertup);

                ReleaseSysCacheList(catlist);
                return result;
            }
        }
    }

    ReleaseSysCacheList(catlist);
    return InvalidOid;
}

bool OpfamilyIsVisible ( Oid  opfid  ) 

Definition at line 1871 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, list_member_oid(), NameStr, ObjectIdGetDatum, OpfamilynameGetOpfid(), OPFAMILYOID, PG_CATALOG_NAMESPACE, recomputeNamespacePath(), ReleaseSysCache(), and SearchSysCache1.

Referenced by getOpFamilyDescription(), and pg_opfamily_is_visible().

{
    HeapTuple   opftup;
    Form_pg_opfamily opfform;
    Oid         opfnamespace;
    bool        visible;

    opftup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
    if (!HeapTupleIsValid(opftup))
        elog(ERROR, "cache lookup failed for opfamily %u", opfid);
    opfform = (Form_pg_opfamily) GETSTRUCT(opftup);

    recomputeNamespacePath();

    /*
     * Quick check: if it ain't in the path at all, it ain't visible. Items in
     * the system namespace are surely in the path and so we needn't even do
     * list_member_oid() for them.
     */
    opfnamespace = opfform->opfnamespace;
    if (opfnamespace != PG_CATALOG_NAMESPACE &&
        !list_member_oid(activeSearchPath, opfnamespace))
        visible = false;
    else
    {
        /*
         * If it is in the path, it might still not be visible; it could be
         * hidden by another opfamily of the same name earlier in the path. So
         * we must do a slow check to see if this opfamily would be found by
         * OpfamilynameGetOpfid.
         */
        char       *opfname = NameStr(opfform->opfname);

        visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid);
    }

    ReleaseSysCache(opftup);

    return visible;
}

Oid OpfamilynameGetOpfid ( Oid  amid,
const char *  opfname 
)

Definition at line 1838 of file namespace.c.

References GetSysCacheOid3, lfirst_oid, myTempNamespace, ObjectIdGetDatum, OidIsValid, OPFAMILYAMNAMENSP, PointerGetDatum, and recomputeNamespacePath().

Referenced by OpFamilyCacheLookup(), and OpfamilyIsVisible().

{
    Oid         opfid;
    ListCell   *l;

    recomputeNamespacePath();

    foreach(l, activeSearchPath)
    {
        Oid         namespaceId = lfirst_oid(l);

        if (namespaceId == myTempNamespace)
            continue;           /* do not look in temp namespace */

        opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP,
                                ObjectIdGetDatum(amid),
                                PointerGetDatum(opfname),
                                ObjectIdGetDatum(namespaceId));
        if (OidIsValid(opfid))
            return opfid;
    }

    /* Not found in path */
    return InvalidOid;
}

bool OverrideSearchPathMatchesCurrent ( OverrideSearchPath path  ) 

Definition at line 3129 of file namespace.c.

References OverrideSearchPath::addCatalog, OverrideSearchPath::addTemp, cur, CurrentMemoryContext, equal(), GetOverrideSearchPath(), list_free(), pfree(), and OverrideSearchPath::schemas.

Referenced by RevalidateCachedQuery().

{
    /* Easiest way to do this is GetOverrideSearchPath() and compare */
    bool        result;
    OverrideSearchPath *cur;

    cur = GetOverrideSearchPath(CurrentMemoryContext);
    if (path->addCatalog == cur->addCatalog &&
        path->addTemp == cur->addTemp &&
        equal(path->schemas, cur->schemas))
        result = true;
    else
        result = false;
    list_free(cur->schemas);
    pfree(cur);
    return result;
}

void PopOverrideSearchPath ( void   ) 

Definition at line 3224 of file namespace.c.

References activeCreationNamespace, activeTempCreationPending, baseCreationNamespace, baseTempCreationPending, OverrideStackEntry::creationNamespace, elog, ERROR, GetCurrentTransactionNestLevel(), linitial, list_delete_first(), list_free(), OverrideStackEntry::nestLevel, NIL, pfree(), and OverrideStackEntry::searchPath.

Referenced by CreateSchemaCommand().

{
    OverrideStackEntry *entry;

    /* Sanity checks. */
    if (overrideStack == NIL)
        elog(ERROR, "bogus PopOverrideSearchPath call");
    entry = (OverrideStackEntry *) linitial(overrideStack);
    if (entry->nestLevel != GetCurrentTransactionNestLevel())
        elog(ERROR, "bogus PopOverrideSearchPath call");

    /* Pop the stack and free storage. */
    overrideStack = list_delete_first(overrideStack);
    list_free(entry->searchPath);
    pfree(entry);

    /* Activate the next level down. */
    if (overrideStack)
    {
        entry = (OverrideStackEntry *) linitial(overrideStack);
        activeSearchPath = entry->searchPath;
        activeCreationNamespace = entry->creationNamespace;
        activeTempCreationPending = false;      /* XXX is this OK? */
    }
    else
    {
        /* If not baseSearchPathValid, this is useless but harmless */
        activeSearchPath = baseSearchPath;
        activeCreationNamespace = baseCreationNamespace;
        activeTempCreationPending = baseTempCreationPending;
    }
}

void PushOverrideSearchPath ( OverrideSearchPath newpath  ) 

Definition at line 3165 of file namespace.c.

References activeCreationNamespace, activeTempCreationPending, OverrideSearchPath::addCatalog, OverrideSearchPath::addTemp, OverrideStackEntry::creationNamespace, GetCurrentTransactionNestLevel(), lcons(), lcons_oid(), linitial_oid, list_copy(), MemoryContextSwitchTo(), myTempNamespace, OverrideStackEntry::nestLevel, NIL, OidIsValid, palloc(), PG_CATALOG_NAMESPACE, OverrideSearchPath::schemas, OverrideStackEntry::searchPath, and TopMemoryContext.

Referenced by CreateSchemaCommand().

{
    OverrideStackEntry *entry;
    List       *oidlist;
    Oid         firstNS;
    MemoryContext oldcxt;

    /*
     * Copy the list for safekeeping, and insert implicitly-searched
     * namespaces as needed.  This code should track recomputeNamespacePath.
     */
    oldcxt = MemoryContextSwitchTo(TopMemoryContext);

    oidlist = list_copy(newpath->schemas);

    /*
     * Remember the first member of the explicit list.
     */
    if (oidlist == NIL)
        firstNS = InvalidOid;
    else
        firstNS = linitial_oid(oidlist);

    /*
     * Add any implicitly-searched namespaces to the list.  Note these go on
     * the front, not the back; also notice that we do not check USAGE
     * permissions for these.
     */
    if (newpath->addCatalog)
        oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);

    if (newpath->addTemp && OidIsValid(myTempNamespace))
        oidlist = lcons_oid(myTempNamespace, oidlist);

    /*
     * Build the new stack entry, then insert it at the head of the list.
     */
    entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
    entry->searchPath = oidlist;
    entry->creationNamespace = firstNS;
    entry->nestLevel = GetCurrentTransactionNestLevel();

    overrideStack = lcons(entry, overrideStack);

    /* And make it active. */
    activeSearchPath = entry->searchPath;
    activeCreationNamespace = entry->creationNamespace;
    activeTempCreationPending = false;  /* XXX is this OK? */

    MemoryContextSwitchTo(oldcxt);
}

Oid QualifiedNameGetCreationNamespace ( List names,
char **  objname_p 
)

Definition at line 2797 of file namespace.c.

References activeCreationNamespace, activeTempCreationPending, DeconstructQualifiedName(), ereport, errcode(), errmsg(), ERROR, get_namespace_oid(), InitTempTableNamespace(), myTempNamespace, OidIsValid, and recomputeNamespacePath().

Referenced by compute_return_type(), CreateConversionCommand(), CreateFunction(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineRange(), DefineTSConfiguration(), DefineTSDictionary(), DefineTSParser(), DefineTSTemplate(), DefineType(), and get_other_operator().

{
    char       *schemaname;
    Oid         namespaceId;

    /* deconstruct the name list */
    DeconstructQualifiedName(names, &schemaname, objname_p);

    if (schemaname)
    {
        /* check for pg_temp alias */
        if (strcmp(schemaname, "pg_temp") == 0)
        {
            /* Initialize temp namespace if first time through */
            if (!OidIsValid(myTempNamespace))
                InitTempTableNamespace();
            return myTempNamespace;
        }
        /* use exact schema given */
        namespaceId = get_namespace_oid(schemaname, false);
        /* we do not check for USAGE rights here! */
    }
    else
    {
        /* use the default creation namespace */
        recomputeNamespacePath();
        if (activeTempCreationPending)
        {
            /* Need to initialize temp namespace */
            InitTempTableNamespace();
            return myTempNamespace;
        }
        namespaceId = activeCreationNamespace;
        if (!OidIsValid(namespaceId))
            ereport(ERROR,
                    (errcode(ERRCODE_UNDEFINED_SCHEMA),
                     errmsg("no schema has been selected to create in")));
    }

    return namespaceId;
}

void RangeVarAdjustRelationPersistence ( RangeVar newRelation,
Oid  nspid 
)

Definition at line 626 of file namespace.c.

References ereport, errcode(), errmsg(), ERROR, isAnyTempNamespace(), isTempOrToastNamespace(), RangeVar::relpersistence, RELPERSISTENCE_PERMANENT, and RELPERSISTENCE_TEMP.

Referenced by DefineCompositeType(), RangeVarGetAndCheckCreationNamespace(), and transformColumnDefinition().

{
    switch (newRelation->relpersistence)
    {
        case RELPERSISTENCE_TEMP:
            if (!isTempOrToastNamespace(nspid))
            {
                if (isAnyTempNamespace(nspid))
                    ereport(ERROR,
                            (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                             errmsg("cannot create relations in temporary schemas of other sessions")));
                else
                    ereport(ERROR,
                            (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                             errmsg("cannot create temporary relation in non-temporary schema")));
            }
            break;
        case RELPERSISTENCE_PERMANENT:
            if (isTempOrToastNamespace(nspid))
                newRelation->relpersistence = RELPERSISTENCE_TEMP;
            else if (isAnyTempNamespace(nspid))
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                         errmsg("cannot create relations in temporary schemas of other sessions")));
            break;
        default:
            if (isAnyTempNamespace(nspid))
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                         errmsg("only temporary relations may be created in temporary schemas")));
    }
}

Oid RangeVarGetAndCheckCreationNamespace ( RangeVar newRelation,
LOCKMODE  lockmode,
Oid existing_relation_id 
)

Definition at line 519 of file namespace.c.

References AccessShareLock, ACL_CREATE, ACL_KIND_CLASS, ACL_KIND_NAMESPACE, aclcheck_error(), ACLCHECK_NOT_OWNER, ACLCHECK_OK, Assert, RangeVar::catalogname, ereport, errcode(), errmsg(), ERROR, get_database_name(), get_namespace_name(), get_relname_relid(), GetUserId(), IsBootstrapProcessingMode, LockDatabaseObject(), LockRelationOid(), MyDatabaseId, NamespaceRelationId, NoLock, NULL, OidIsValid, pg_class_ownercheck(), pg_namespace_aclcheck(), RangeVarAdjustRelationPersistence(), RangeVarGetCreationNamespace(), RangeVar::relname, RangeVar::schemaname, SharedInvalidMessageCounter, UnlockDatabaseObject(), and UnlockRelationOid().

Referenced by AlterTableNamespace(), DefineCompositeType(), DefineRelation(), DefineVirtualRelation(), and transformCreateStmt().

{
    uint64      inval_count;
    Oid         relid;
    Oid         oldrelid = InvalidOid;
    Oid         nspid;
    Oid         oldnspid = InvalidOid;
    bool        retry = false;

    /*
     * We check the catalog name and then ignore it.
     */
    if (relation->catalogname)
    {
        if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
            ereport(ERROR,
                    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                     errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
                            relation->catalogname, relation->schemaname,
                            relation->relname)));
    }

    /*
     * As in RangeVarGetRelidExtended(), we guard against concurrent DDL
     * operations by tracking whether any invalidation messages are processed
     * while we're doing the name lookups and acquiring locks.  See comments
     * in that function for a more detailed explanation of this logic.
     */
    for (;;)
    {
        AclResult   aclresult;

        inval_count = SharedInvalidMessageCounter;

        /* Look up creation namespace and check for existing relation. */
        nspid = RangeVarGetCreationNamespace(relation);
        Assert(OidIsValid(nspid));
        if (existing_relation_id != NULL)
            relid = get_relname_relid(relation->relname, nspid);
        else
            relid = InvalidOid;

        /*
         * In bootstrap processing mode, we don't bother with permissions or
         * locking.  Permissions might not be working yet, and locking is
         * unnecessary.
         */
        if (IsBootstrapProcessingMode())
            break;

        /* Check namespace permissions. */
        aclresult = pg_namespace_aclcheck(nspid, GetUserId(), ACL_CREATE);
        if (aclresult != ACLCHECK_OK)
            aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
                           get_namespace_name(nspid));

        if (retry)
        {
            /* If nothing changed, we're done. */
            if (relid == oldrelid && nspid == oldnspid)
                break;
            /* If creation namespace has changed, give up old lock. */
            if (nspid != oldnspid)
                UnlockDatabaseObject(NamespaceRelationId, oldnspid, 0,
                                     AccessShareLock);
            /* If name points to something different, give up old lock. */
            if (relid != oldrelid && OidIsValid(oldrelid) && lockmode != NoLock)
                UnlockRelationOid(oldrelid, lockmode);
        }

        /* Lock namespace. */
        if (nspid != oldnspid)
            LockDatabaseObject(NamespaceRelationId, nspid, 0, AccessShareLock);

        /* Lock relation, if required if and we have permission. */
        if (lockmode != NoLock && OidIsValid(relid))
        {
            if (!pg_class_ownercheck(relid, GetUserId()))
                aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
                               relation->relname);
            if (relid != oldrelid)
                LockRelationOid(relid, lockmode);
        }

        /* If no invalidation message were processed, we're done! */
        if (inval_count == SharedInvalidMessageCounter)
            break;

        /* Something may have changed, so recheck our work. */
        retry = true;
        oldrelid = relid;
        oldnspid = nspid;
    }

    RangeVarAdjustRelationPersistence(relation, nspid);
    if (existing_relation_id != NULL)
        *existing_relation_id = relid;
    return nspid;
}

Oid RangeVarGetCreationNamespace ( const RangeVar newRelation  ) 

Definition at line 432 of file namespace.c.

References activeCreationNamespace, activeTempCreationPending, RangeVar::catalogname, ereport, errcode(), errmsg(), ERROR, get_database_name(), get_namespace_oid(), InitTempTableNamespace(), MyDatabaseId, myTempNamespace, OidIsValid, recomputeNamespacePath(), RangeVar::relname, RangeVar::relpersistence, RELPERSISTENCE_TEMP, and RangeVar::schemaname.

Referenced by RangeVarGetAndCheckCreationNamespace(), and transformColumnDefinition().

{
    Oid         namespaceId;

    /*
     * We check the catalog name and then ignore it.
     */
    if (newRelation->catalogname)
    {
        if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
            ereport(ERROR,
                    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                     errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
                            newRelation->catalogname, newRelation->schemaname,
                            newRelation->relname)));
    }

    if (newRelation->schemaname)
    {
        /* check for pg_temp alias */
        if (strcmp(newRelation->schemaname, "pg_temp") == 0)
        {
            /* Initialize temp namespace if first time through */
            if (!OidIsValid(myTempNamespace))
                InitTempTableNamespace();
            return myTempNamespace;
        }
        /* use exact schema given */
        namespaceId = get_namespace_oid(newRelation->schemaname, false);
        /* we do not check for USAGE rights here! */
    }
    else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
    {
        /* Initialize temp namespace if first time through */
        if (!OidIsValid(myTempNamespace))
            InitTempTableNamespace();
        return myTempNamespace;
    }
    else
    {
        /* use the default creation namespace */
        recomputeNamespacePath();
        if (activeTempCreationPending)
        {
            /* Need to initialize temp namespace */
            InitTempTableNamespace();
            return myTempNamespace;
        }
        namespaceId = activeCreationNamespace;
        if (!OidIsValid(namespaceId))
            ereport(ERROR,
                    (errcode(ERRCODE_UNDEFINED_SCHEMA),
                     errmsg("no schema has been selected to create in")));
    }

    /* Note: callers will check for CREATE rights when appropriate */

    return namespaceId;
}

Oid RangeVarGetRelidExtended ( const RangeVar relation,
LOCKMODE  lockmode,
bool  missing_ok,
bool  nowait,
RangeVarGetRelidCallback  callback,
void *  callback_arg 
)

Definition at line 230 of file namespace.c.

References AcceptInvalidationMessages(), callback(), RangeVar::catalogname, ConditionalLockRelationOid(), ereport, errcode(), errmsg(), ERROR, get_database_name(), get_relname_relid(), LockRelationOid(), LookupExplicitNamespace(), MyDatabaseId, myTempNamespace, NoLock, OidIsValid, RangeVar::relname, RelnameGetRelid(), RangeVar::relpersistence, RELPERSISTENCE_TEMP, RangeVar::schemaname, SharedInvalidMessageCounter, and UnlockRelationOid().

Referenced by AlterTableLookupRelation(), AlterTableNamespace(), cluster(), ExecRefreshMatView(), LockTableCommand(), ReindexIndex(), ReindexTable(), RemoveRelations(), renameatt(), RenameConstraint(), RenameRelation(), RenameRewriteRule(), and renametrig().

{
    uint64      inval_count;
    Oid         relId;
    Oid         oldRelId = InvalidOid;
    bool        retry = false;

    /*
     * We check the catalog name and then ignore it.
     */
    if (relation->catalogname)
    {
        if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
            ereport(ERROR,
                    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                     errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
                            relation->catalogname, relation->schemaname,
                            relation->relname)));
    }

    /*
     * DDL operations can change the results of a name lookup.  Since all such
     * operations will generate invalidation messages, we keep track of
     * whether any such messages show up while we're performing the operation,
     * and retry until either (1) no more invalidation messages show up or (2)
     * the answer doesn't change.
     *
     * But if lockmode = NoLock, then we assume that either the caller is OK
     * with the answer changing under them, or that they already hold some
     * appropriate lock, and therefore return the first answer we get without
     * checking for invalidation messages.  Also, if the requested lock is
     * already held, no LockRelationOid will not AcceptInvalidationMessages,
     * so we may fail to notice a change.  We could protect against that case
     * by calling AcceptInvalidationMessages() before beginning this loop, but
     * that would add a significant amount overhead, so for now we don't.
     */
    for (;;)
    {
        /*
         * Remember this value, so that, after looking up the relation name
         * and locking its OID, we can check whether any invalidation messages
         * have been processed that might require a do-over.
         */
        inval_count = SharedInvalidMessageCounter;

        /*
         * Some non-default relpersistence value may have been specified.  The
         * parser never generates such a RangeVar in simple DML, but it can
         * happen in contexts such as "CREATE TEMP TABLE foo (f1 int PRIMARY
         * KEY)".  Such a command will generate an added CREATE INDEX
         * operation, which must be careful to find the temp table, even when
         * pg_temp is not first in the search path.
         */
        if (relation->relpersistence == RELPERSISTENCE_TEMP)
        {
            if (!OidIsValid(myTempNamespace))
                relId = InvalidOid;     /* this probably can't happen? */
            else
            {
                if (relation->schemaname)
                {
                    Oid         namespaceId;

                    namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
                    /*
                     *  For missing_ok, allow a non-existant schema name to
                     *  return InvalidOid.
                     */
                    if (namespaceId != myTempNamespace)
                        ereport(ERROR,
                                (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                                 errmsg("temporary tables cannot specify a schema name")));
                }

                relId = get_relname_relid(relation->relname, myTempNamespace);
            }
        }
        else if (relation->schemaname)
        {
            Oid         namespaceId;

            /* use exact schema given */
            namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
            if (missing_ok && !OidIsValid(namespaceId))
                relId = InvalidOid;
            else
                relId = get_relname_relid(relation->relname, namespaceId);
        }
        else
        {
            /* search the namespace path */
            relId = RelnameGetRelid(relation->relname);
        }

        /*
         * Invoke caller-supplied callback, if any.
         *
         * This callback is a good place to check permissions: we haven't
         * taken the table lock yet (and it's really best to check permissions
         * before locking anything!), but we've gotten far enough to know what
         * OID we think we should lock.  Of course, concurrent DDL might
         * change things while we're waiting for the lock, but in that case
         * the callback will be invoked again for the new OID.
         */
        if (callback)
            callback(relation, relId, oldRelId, callback_arg);

        /*
         * If no lock requested, we assume the caller knows what they're
         * doing.  They should have already acquired a heavyweight lock on
         * this relation earlier in the processing of this same statement, so
         * it wouldn't be appropriate to AcceptInvalidationMessages() here, as
         * that might pull the rug out from under them.
         */
        if (lockmode == NoLock)
            break;

        /*
         * If, upon retry, we get back the same OID we did last time, then the
         * invalidation messages we processed did not change the final answer.
         * So we're done.
         *
         * If we got a different OID, we've locked the relation that used to
         * have this name rather than the one that does now.  So release the
         * lock.
         */
        if (retry)
        {
            if (relId == oldRelId)
                break;
            if (OidIsValid(oldRelId))
                UnlockRelationOid(oldRelId, lockmode);
        }

        /*
         * Lock relation.  This will also accept any pending invalidation
         * messages.  If we got back InvalidOid, indicating not found, then
         * there's nothing to lock, but we accept invalidation messages
         * anyway, to flush any negative catcache entries that may be
         * lingering.
         */
        if (!OidIsValid(relId))
            AcceptInvalidationMessages();
        else if (!nowait)
            LockRelationOid(relId, lockmode);
        else if (!ConditionalLockRelationOid(relId, lockmode))
        {
            if (relation->schemaname)
                ereport(ERROR,
                        (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
                         errmsg("could not obtain lock on relation \"%s.%s\"",
                                relation->schemaname, relation->relname)));
            else
                ereport(ERROR,
                        (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
                         errmsg("could not obtain lock on relation \"%s\"",
                                relation->relname)));
        }

        /*
         * If no invalidation message were processed, we're done!
         */
        if (inval_count == SharedInvalidMessageCounter)
            break;

        /*
         * Something may have changed.  Let's repeat the name lookup, to make
         * sure this name still references the same relation it did
         * previously.
         */
        retry = true;
        oldRelId = relId;
    }

    if (!OidIsValid(relId) && !missing_ok)
    {
        if (relation->schemaname)
            ereport(ERROR,
                    (errcode(ERRCODE_UNDEFINED_TABLE),
                     errmsg("relation \"%s.%s\" does not exist",
                            relation->schemaname, relation->relname)));
        else
            ereport(ERROR,
                    (errcode(ERRCODE_UNDEFINED_TABLE),
                     errmsg("relation \"%s\" does not exist",
                            relation->relname)));
    }
    return relId;
}

bool RelationIsVisible ( Oid  relid  ) 

Definition at line 693 of file namespace.c.

References elog, ERROR, get_relname_relid(), GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), NameStr, ObjectIdGetDatum, OidIsValid, PG_CATALOG_NAMESPACE, recomputeNamespacePath(), ReleaseSysCache(), RELOID, and SearchSysCache1.

Referenced by generate_relation_name(), getRelationDescription(), pg_table_is_visible(), and regclassout().

{
    HeapTuple   reltup;
    Form_pg_class relform;
    Oid         relnamespace;
    bool        visible;

    reltup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
    if (!HeapTupleIsValid(reltup))
        elog(ERROR, "cache lookup failed for relation %u", relid);
    relform = (Form_pg_class) GETSTRUCT(reltup);

    recomputeNamespacePath();

    /*
     * Quick check: if it ain't in the path at all, it ain't visible. Items in
     * the system namespace are surely in the path and so we needn't even do
     * list_member_oid() for them.
     */
    relnamespace = relform->relnamespace;
    if (relnamespace != PG_CATALOG_NAMESPACE &&
        !list_member_oid(activeSearchPath, relnamespace))
        visible = false;
    else
    {
        /*
         * If it is in the path, it might still not be visible; it could be
         * hidden by another relation of the same name earlier in the path. So
         * we must do a slow check for conflicting relations.
         */
        char       *relname = NameStr(relform->relname);
        ListCell   *l;

        visible = false;
        foreach(l, activeSearchPath)
        {
            Oid         namespaceId = lfirst_oid(l);

            if (namespaceId == relnamespace)
            {
                /* Found it first in path */
                visible = true;
                break;
            }
            if (OidIsValid(get_relname_relid(relname, namespaceId)))
            {
                /* Found something else first in path */
                break;
            }
        }
    }

    ReleaseSysCache(reltup);

    return visible;
}

Oid RelnameGetRelid ( const char *  relname  ) 

Definition at line 665 of file namespace.c.

References get_relname_relid(), lfirst_oid, OidIsValid, and recomputeNamespacePath().

Referenced by plpgsql_parse_cwordtype(), plpgsql_parse_wordrowtype(), and RangeVarGetRelidExtended().

{
    Oid         relid;
    ListCell   *l;

    recomputeNamespacePath();

    foreach(l, activeSearchPath)
    {
        Oid         namespaceId = lfirst_oid(l);

        relid = get_relname_relid(relname, namespaceId);
        if (OidIsValid(relid))
            return relid;
    }

    /* Not found in path */
    return InvalidOid;
}

void ResetTempTableNamespace ( void   ) 
bool TSConfigIsVisible ( Oid  cfgid  ) 

Definition at line 2527 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), myTempNamespace, name, NameStr, ObjectIdGetDatum, PG_CATALOG_NAMESPACE, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1, SearchSysCacheExists2, TSCONFIGNAMENSP, and TSCONFIGOID.

Referenced by pg_ts_config_is_visible(), and regconfigout().

{
    HeapTuple   tup;
    Form_pg_ts_config form;
    Oid         namespace;
    bool        visible;

    tup = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(cfgid));
    if (!HeapTupleIsValid(tup))
        elog(ERROR, "cache lookup failed for text search configuration %u",
             cfgid);
    form = (Form_pg_ts_config) GETSTRUCT(tup);

    recomputeNamespacePath();

    /*
     * Quick check: if it ain't in the path at all, it ain't visible. Items in
     * the system namespace are surely in the path and so we needn't even do
     * list_member_oid() for them.
     */
    namespace = form->cfgnamespace;
    if (namespace != PG_CATALOG_NAMESPACE &&
        !list_member_oid(activeSearchPath, namespace))
        visible = false;
    else
    {
        /*
         * If it is in the path, it might still not be visible; it could be
         * hidden by another configuration of the same name earlier in the
         * path. So we must do a slow check for conflicting configurations.
         */
        char       *name = NameStr(form->cfgname);
        ListCell   *l;

        visible = false;
        foreach(l, activeSearchPath)
        {
            Oid         namespaceId = lfirst_oid(l);

            if (namespaceId == myTempNamespace)
                continue;       /* do not look in temp namespace */

            if (namespaceId == namespace)
            {
                /* Found it first in path */
                visible = true;
                break;
            }
            if (SearchSysCacheExists2(TSCONFIGNAMENSP,
                                      PointerGetDatum(name),
                                      ObjectIdGetDatum(namespaceId)))
            {
                /* Found something else first in path */
                break;
            }
        }
    }

    ReleaseSysCache(tup);

    return visible;
}

bool TSDictionaryIsVisible ( Oid  dictId  ) 

Definition at line 2274 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), myTempNamespace, name, NameStr, ObjectIdGetDatum, PG_CATALOG_NAMESPACE, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1, SearchSysCacheExists2, TSDICTNAMENSP, and TSDICTOID.

Referenced by pg_ts_dict_is_visible(), and regdictionaryout().

{
    HeapTuple   tup;
    Form_pg_ts_dict form;
    Oid         namespace;
    bool        visible;

    tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId));
    if (!HeapTupleIsValid(tup))
        elog(ERROR, "cache lookup failed for text search dictionary %u",
             dictId);
    form = (Form_pg_ts_dict) GETSTRUCT(tup);

    recomputeNamespacePath();

    /*
     * Quick check: if it ain't in the path at all, it ain't visible. Items in
     * the system namespace are surely in the path and so we needn't even do
     * list_member_oid() for them.
     */
    namespace = form->dictnamespace;
    if (namespace != PG_CATALOG_NAMESPACE &&
        !list_member_oid(activeSearchPath, namespace))
        visible = false;
    else
    {
        /*
         * If it is in the path, it might still not be visible; it could be
         * hidden by another dictionary of the same name earlier in the path.
         * So we must do a slow check for conflicting dictionaries.
         */
        char       *name = NameStr(form->dictname);
        ListCell   *l;

        visible = false;
        foreach(l, activeSearchPath)
        {
            Oid         namespaceId = lfirst_oid(l);

            if (namespaceId == myTempNamespace)
                continue;       /* do not look in temp namespace */

            if (namespaceId == namespace)
            {
                /* Found it first in path */
                visible = true;
                break;
            }
            if (SearchSysCacheExists2(TSDICTNAMENSP,
                                      PointerGetDatum(name),
                                      ObjectIdGetDatum(namespaceId)))
            {
                /* Found something else first in path */
                break;
            }
        }
    }

    ReleaseSysCache(tup);

    return visible;
}

bool TSParserIsVisible ( Oid  prsId  ) 

Definition at line 2148 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), myTempNamespace, name, NameStr, ObjectIdGetDatum, PG_CATALOG_NAMESPACE, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1, SearchSysCacheExists2, TSPARSERNAMENSP, and TSPARSEROID.

Referenced by pg_ts_parser_is_visible().

{
    HeapTuple   tup;
    Form_pg_ts_parser form;
    Oid         namespace;
    bool        visible;

    tup = SearchSysCache1(TSPARSEROID, ObjectIdGetDatum(prsId));
    if (!HeapTupleIsValid(tup))
        elog(ERROR, "cache lookup failed for text search parser %u", prsId);
    form = (Form_pg_ts_parser) GETSTRUCT(tup);

    recomputeNamespacePath();

    /*
     * Quick check: if it ain't in the path at all, it ain't visible. Items in
     * the system namespace are surely in the path and so we needn't even do
     * list_member_oid() for them.
     */
    namespace = form->prsnamespace;
    if (namespace != PG_CATALOG_NAMESPACE &&
        !list_member_oid(activeSearchPath, namespace))
        visible = false;
    else
    {
        /*
         * If it is in the path, it might still not be visible; it could be
         * hidden by another parser of the same name earlier in the path. So
         * we must do a slow check for conflicting parsers.
         */
        char       *name = NameStr(form->prsname);
        ListCell   *l;

        visible = false;
        foreach(l, activeSearchPath)
        {
            Oid         namespaceId = lfirst_oid(l);

            if (namespaceId == myTempNamespace)
                continue;       /* do not look in temp namespace */

            if (namespaceId == namespace)
            {
                /* Found it first in path */
                visible = true;
                break;
            }
            if (SearchSysCacheExists2(TSPARSERNAMENSP,
                                      PointerGetDatum(name),
                                      ObjectIdGetDatum(namespaceId)))
            {
                /* Found something else first in path */
                break;
            }
        }
    }

    ReleaseSysCache(tup);

    return visible;
}

bool TSTemplateIsVisible ( Oid  tmplId  ) 

Definition at line 2401 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), myTempNamespace, name, NameStr, ObjectIdGetDatum, PG_CATALOG_NAMESPACE, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1, SearchSysCacheExists2, TSTEMPLATENAMENSP, and TSTEMPLATEOID.

Referenced by pg_ts_template_is_visible().

{
    HeapTuple   tup;
    Form_pg_ts_template form;
    Oid         namespace;
    bool        visible;

    tup = SearchSysCache1(TSTEMPLATEOID, ObjectIdGetDatum(tmplId));
    if (!HeapTupleIsValid(tup))
        elog(ERROR, "cache lookup failed for text search template %u", tmplId);
    form = (Form_pg_ts_template) GETSTRUCT(tup);

    recomputeNamespacePath();

    /*
     * Quick check: if it ain't in the path at all, it ain't visible. Items in
     * the system namespace are surely in the path and so we needn't even do
     * list_member_oid() for them.
     */
    namespace = form->tmplnamespace;
    if (namespace != PG_CATALOG_NAMESPACE &&
        !list_member_oid(activeSearchPath, namespace))
        visible = false;
    else
    {
        /*
         * If it is in the path, it might still not be visible; it could be
         * hidden by another template of the same name earlier in the path. So
         * we must do a slow check for conflicting templates.
         */
        char       *name = NameStr(form->tmplname);
        ListCell   *l;

        visible = false;
        foreach(l, activeSearchPath)
        {
            Oid         namespaceId = lfirst_oid(l);

            if (namespaceId == myTempNamespace)
                continue;       /* do not look in temp namespace */

            if (namespaceId == namespace)
            {
                /* Found it first in path */
                visible = true;
                break;
            }
            if (SearchSysCacheExists2(TSTEMPLATENAMENSP,
                                      PointerGetDatum(name),
                                      ObjectIdGetDatum(namespaceId)))
            {
                /* Found something else first in path */
                break;
            }
        }
    }

    ReleaseSysCache(tup);

    return visible;
}

bool TypeIsVisible ( Oid  typid  ) 

Definition at line 788 of file namespace.c.

References elog, ERROR, GETSTRUCT, HeapTupleIsValid, lfirst_oid, list_member_oid(), NameStr, ObjectIdGetDatum, PG_CATALOG_NAMESPACE, PointerGetDatum, recomputeNamespacePath(), ReleaseSysCache(), SearchSysCache1, SearchSysCacheExists2, TYPENAMENSP, and TYPEOID.

Referenced by format_type_internal(), and pg_type_is_visible().

{
    HeapTuple   typtup;
    Form_pg_type typform;
    Oid         typnamespace;
    bool        visible;

    typtup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
    if (!HeapTupleIsValid(typtup))
        elog(ERROR, "cache lookup failed for type %u", typid);
    typform = (Form_pg_type) GETSTRUCT(typtup);

    recomputeNamespacePath();

    /*
     * Quick check: if it ain't in the path at all, it ain't visible. Items in
     * the system namespace are surely in the path and so we needn't even do
     * list_member_oid() for them.
     */
    typnamespace = typform->typnamespace;
    if (typnamespace != PG_CATALOG_NAMESPACE &&
        !list_member_oid(activeSearchPath, typnamespace))
        visible = false;
    else
    {
        /*
         * If it is in the path, it might still not be visible; it could be
         * hidden by another type of the same name earlier in the path. So we
         * must do a slow check for conflicting types.
         */
        char       *typname = NameStr(typform->typname);
        ListCell   *l;

        visible = false;
        foreach(l, activeSearchPath)
        {
            Oid         namespaceId = lfirst_oid(l);

            if (namespaceId == typnamespace)
            {
                /* Found it first in path */
                visible = true;
                break;
            }
            if (SearchSysCacheExists2(TYPENAMENSP,
                                      PointerGetDatum(typname),
                                      ObjectIdGetDatum(namespaceId)))
            {
                /* Found something else first in path */
                break;
            }
        }
    }

    ReleaseSysCache(typtup);

    return visible;
}

Oid TypenameGetTypid ( const char *  typname  ) 

Definition at line 759 of file namespace.c.

References GetSysCacheOid2, lfirst_oid, ObjectIdGetDatum, OidIsValid, PointerGetDatum, recomputeNamespacePath(), and TYPENAMENSP.

Referenced by LookupTypeName().

{
    Oid         typid;
    ListCell   *l;

    recomputeNamespacePath();

    foreach(l, activeSearchPath)
    {
        Oid         namespaceId = lfirst_oid(l);

        typid = GetSysCacheOid2(TYPENAMENSP,
                                PointerGetDatum(typname),
                                ObjectIdGetDatum(namespaceId));
        if (OidIsValid(typid))
            return typid;
    }

    /* Not found in path */
    return InvalidOid;
}


Variable Documentation

Definition at line 187 of file namespace.c.

Referenced by recomputeNamespacePath().