LCOV - differential code coverage report
Current view: top level - src/backend/catalog - namespace.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 85.6 % 1433 1227 1 35 119 51 43 772 15 397 111 789 1 6
Current Date: 2023-04-08 17:13:01 Functions: 89.0 % 91 81 10 79 2 10 81
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (120,180] days: 87.5 % 8 7 1 7
Legend: Lines: hit not hit (180,240] days: 100.0 % 8 8 8
(240..) days: 85.5 % 1417 1212 35 119 51 43 772 397 111 789
Function coverage date bins:
(180,240] days: 100.0 % 2 2 2
(240..) days: 43.9 % 180 79 10 79 10 81

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * namespace.c
                                  4                 :  *    code to support accessing and searching namespaces
                                  5                 :  *
                                  6                 :  * This is separate from pg_namespace.c, which contains the routines that
                                  7                 :  * directly manipulate the pg_namespace system catalog.  This module
                                  8                 :  * provides routines associated with defining a "namespace search path"
                                  9                 :  * and implementing search-path-controlled searches.
                                 10                 :  *
                                 11                 :  *
                                 12                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                 13                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                 14                 :  *
                                 15                 :  * IDENTIFICATION
                                 16                 :  *    src/backend/catalog/namespace.c
                                 17                 :  *
                                 18                 :  *-------------------------------------------------------------------------
                                 19                 :  */
                                 20                 : #include "postgres.h"
                                 21                 : 
                                 22                 : #include "access/htup_details.h"
                                 23                 : #include "access/parallel.h"
                                 24                 : #include "access/xact.h"
                                 25                 : #include "access/xlog.h"
                                 26                 : #include "catalog/dependency.h"
                                 27                 : #include "catalog/objectaccess.h"
                                 28                 : #include "catalog/pg_authid.h"
                                 29                 : #include "catalog/pg_collation.h"
                                 30                 : #include "catalog/pg_conversion.h"
                                 31                 : #include "catalog/pg_database.h"
                                 32                 : #include "catalog/pg_namespace.h"
                                 33                 : #include "catalog/pg_opclass.h"
                                 34                 : #include "catalog/pg_operator.h"
                                 35                 : #include "catalog/pg_opfamily.h"
                                 36                 : #include "catalog/pg_proc.h"
                                 37                 : #include "catalog/pg_statistic_ext.h"
                                 38                 : #include "catalog/pg_ts_config.h"
                                 39                 : #include "catalog/pg_ts_dict.h"
                                 40                 : #include "catalog/pg_ts_parser.h"
                                 41                 : #include "catalog/pg_ts_template.h"
                                 42                 : #include "catalog/pg_type.h"
                                 43                 : #include "commands/dbcommands.h"
                                 44                 : #include "funcapi.h"
                                 45                 : #include "mb/pg_wchar.h"
                                 46                 : #include "miscadmin.h"
                                 47                 : #include "nodes/makefuncs.h"
                                 48                 : #include "parser/parse_func.h"
                                 49                 : #include "storage/ipc.h"
                                 50                 : #include "storage/lmgr.h"
                                 51                 : #include "storage/sinvaladt.h"
                                 52                 : #include "utils/acl.h"
                                 53                 : #include "utils/builtins.h"
                                 54                 : #include "utils/catcache.h"
                                 55                 : #include "utils/guc_hooks.h"
                                 56                 : #include "utils/inval.h"
                                 57                 : #include "utils/lsyscache.h"
                                 58                 : #include "utils/memutils.h"
                                 59                 : #include "utils/snapmgr.h"
                                 60                 : #include "utils/syscache.h"
                                 61                 : #include "utils/varlena.h"
                                 62                 : 
                                 63                 : 
                                 64                 : /*
                                 65                 :  * The namespace search path is a possibly-empty list of namespace OIDs.
                                 66                 :  * In addition to the explicit list, implicitly-searched namespaces
                                 67                 :  * may be included:
                                 68                 :  *
                                 69                 :  * 1. If a TEMP table namespace has been initialized in this session, it
                                 70                 :  * is implicitly searched first.  (The only time this doesn't happen is
                                 71                 :  * when we are obeying an override search path spec that says not to use the
                                 72                 :  * temp namespace, or the temp namespace is included in the explicit list.)
                                 73                 :  *
                                 74                 :  * 2. The system catalog namespace is always searched.  If the system
                                 75                 :  * namespace is present in the explicit path then it will be searched in
                                 76                 :  * the specified order; otherwise it will be searched after TEMP tables and
                                 77                 :  * *before* the explicit list.  (It might seem that the system namespace
                                 78                 :  * should be implicitly last, but this behavior appears to be required by
                                 79                 :  * SQL99.  Also, this provides a way to search the system namespace first
                                 80                 :  * without thereby making it the default creation target namespace.)
                                 81                 :  *
                                 82                 :  * For security reasons, searches using the search path will ignore the temp
                                 83                 :  * namespace when searching for any object type other than relations and
                                 84                 :  * types.  (We must allow types since temp tables have rowtypes.)
                                 85                 :  *
                                 86                 :  * The default creation target namespace is always the first element of the
                                 87                 :  * explicit list.  If the explicit list is empty, there is no default target.
                                 88                 :  *
                                 89                 :  * The textual specification of search_path can include "$user" to refer to
                                 90                 :  * the namespace named the same as the current user, if any.  (This is just
                                 91                 :  * ignored if there is no such namespace.)  Also, it can include "pg_temp"
                                 92                 :  * to refer to the current backend's temp namespace.  This is usually also
                                 93                 :  * ignorable if the temp namespace hasn't been set up, but there's a special
                                 94                 :  * case: if "pg_temp" appears first then it should be the default creation
                                 95                 :  * target.  We kluge this case a little bit so that the temp namespace isn't
                                 96                 :  * set up until the first attempt to create something in it.  (The reason for
                                 97                 :  * klugery is that we can't create the temp namespace outside a transaction,
                                 98                 :  * but initial GUC processing of search_path happens outside a transaction.)
                                 99                 :  * activeTempCreationPending is true if "pg_temp" appears first in the string
                                100                 :  * but is not reflected in activeCreationNamespace because the namespace isn't
                                101                 :  * set up yet.
                                102                 :  *
                                103                 :  * In bootstrap mode, the search path is set equal to "pg_catalog", so that
                                104                 :  * the system namespace is the only one searched or inserted into.
                                105                 :  * initdb is also careful to set search_path to "pg_catalog" for its
                                106                 :  * post-bootstrap standalone backend runs.  Otherwise the default search
                                107                 :  * path is determined by GUC.  The factory default path contains the PUBLIC
                                108                 :  * namespace (if it exists), preceded by the user's personal namespace
                                109                 :  * (if one exists).
                                110                 :  *
                                111                 :  * We support a stack of "override" search path settings for use within
                                112                 :  * specific sections of backend code.  namespace_search_path is ignored
                                113                 :  * whenever the override stack is nonempty.  activeSearchPath is always
                                114                 :  * the actually active path; it points either to the search list of the
                                115                 :  * topmost stack entry, or to baseSearchPath which is the list derived
                                116                 :  * from namespace_search_path.
                                117                 :  *
                                118                 :  * If baseSearchPathValid is false, then baseSearchPath (and other
                                119                 :  * derived variables) need to be recomputed from namespace_search_path.
                                120                 :  * We mark it invalid upon an assignment to namespace_search_path or receipt
                                121                 :  * of a syscache invalidation event for pg_namespace.  The recomputation
                                122                 :  * is done during the next non-overridden lookup attempt.  Note that an
                                123                 :  * override spec is never subject to recomputation.
                                124                 :  *
                                125                 :  * Any namespaces mentioned in namespace_search_path that are not readable
                                126                 :  * by the current user ID are simply left out of baseSearchPath; so
                                127                 :  * we have to be willing to recompute the path when current userid changes.
                                128                 :  * namespaceUser is the userid the path has been computed for.
                                129                 :  *
                                130                 :  * Note: all data pointed to by these List variables is in TopMemoryContext.
                                131                 :  *
                                132                 :  * activePathGeneration is incremented whenever the effective values of
                                133                 :  * activeSearchPath/activeCreationNamespace/activeTempCreationPending change.
                                134                 :  * This can be used to quickly detect whether any change has happened since
                                135                 :  * a previous examination of the search path state.
                                136                 :  */
                                137                 : 
                                138                 : /* These variables define the actually active state: */
                                139                 : 
                                140                 : static List *activeSearchPath = NIL;
                                141                 : 
                                142                 : /* default place to create stuff; if InvalidOid, no default */
                                143                 : static Oid  activeCreationNamespace = InvalidOid;
                                144                 : 
                                145                 : /* if true, activeCreationNamespace is wrong, it should be temp namespace */
                                146                 : static bool activeTempCreationPending = false;
                                147                 : 
                                148                 : /* current generation counter; make sure this is never zero */
                                149                 : static uint64 activePathGeneration = 1;
                                150                 : 
                                151                 : /* These variables are the values last derived from namespace_search_path: */
                                152                 : 
                                153                 : static List *baseSearchPath = NIL;
                                154                 : 
                                155                 : static Oid  baseCreationNamespace = InvalidOid;
                                156                 : 
                                157                 : static bool baseTempCreationPending = false;
                                158                 : 
                                159                 : static Oid  namespaceUser = InvalidOid;
                                160                 : 
                                161                 : /* The above four values are valid only if baseSearchPathValid */
                                162                 : static bool baseSearchPathValid = true;
                                163                 : 
                                164                 : /* Override requests are remembered in a stack of OverrideStackEntry structs */
                                165                 : 
                                166                 : typedef struct
                                167                 : {
                                168                 :     List       *searchPath;     /* the desired search path */
                                169                 :     Oid         creationNamespace;  /* the desired creation namespace */
                                170                 :     int         nestLevel;      /* subtransaction nesting level */
                                171                 : } OverrideStackEntry;
                                172                 : 
                                173                 : static List *overrideStack = NIL;
                                174                 : 
                                175                 : /*
                                176                 :  * myTempNamespace is InvalidOid until and unless a TEMP namespace is set up
                                177                 :  * in a particular backend session (this happens when a CREATE TEMP TABLE
                                178                 :  * command is first executed).  Thereafter it's the OID of the temp namespace.
                                179                 :  *
                                180                 :  * myTempToastNamespace is the OID of the namespace for my temp tables' toast
                                181                 :  * tables.  It is set when myTempNamespace is, and is InvalidOid before that.
                                182                 :  *
                                183                 :  * myTempNamespaceSubID shows whether we've created the TEMP namespace in the
                                184                 :  * current subtransaction.  The flag propagates up the subtransaction tree,
                                185                 :  * so the main transaction will correctly recognize the flag if all
                                186                 :  * intermediate subtransactions commit.  When it is InvalidSubTransactionId,
                                187                 :  * we either haven't made the TEMP namespace yet, or have successfully
                                188                 :  * committed its creation, depending on whether myTempNamespace is valid.
                                189                 :  */
                                190                 : static Oid  myTempNamespace = InvalidOid;
                                191                 : 
                                192                 : static Oid  myTempToastNamespace = InvalidOid;
                                193                 : 
                                194                 : static SubTransactionId myTempNamespaceSubID = InvalidSubTransactionId;
                                195                 : 
                                196                 : /*
                                197                 :  * This is the user's textual search path specification --- it's the value
                                198                 :  * of the GUC variable 'search_path'.
                                199                 :  */
                                200                 : char       *namespace_search_path = NULL;
                                201                 : 
                                202                 : 
                                203                 : /* Local functions */
                                204                 : static void recomputeNamespacePath(void);
                                205                 : static void AccessTempTableNamespace(bool force);
                                206                 : static void InitTempTableNamespace(void);
                                207                 : static void RemoveTempRelations(Oid tempNamespaceId);
                                208                 : static void RemoveTempRelationsCallback(int code, Datum arg);
                                209                 : static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue);
                                210                 : static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames,
                                211                 :                            bool include_out_arguments, int pronargs,
                                212                 :                            int **argnumbers);
                                213                 : 
                                214                 : 
                                215                 : /*
                                216                 :  * RangeVarGetRelidExtended
                                217                 :  *      Given a RangeVar describing an existing relation,
                                218                 :  *      select the proper namespace and look up the relation OID.
                                219                 :  *
                                220                 :  * If the schema or relation is not found, return InvalidOid if flags contains
                                221                 :  * RVR_MISSING_OK, otherwise raise an error.
                                222                 :  *
                                223                 :  * If flags contains RVR_NOWAIT, throw an error if we'd have to wait for a
                                224                 :  * lock.
                                225                 :  *
                                226                 :  * If flags contains RVR_SKIP_LOCKED, return InvalidOid if we'd have to wait
                                227                 :  * for a lock.
                                228                 :  *
                                229                 :  * flags cannot contain both RVR_NOWAIT and RVR_SKIP_LOCKED.
                                230                 :  *
                                231                 :  * Note that if RVR_MISSING_OK and RVR_SKIP_LOCKED are both specified, a
                                232                 :  * return value of InvalidOid could either mean the relation is missing or it
                                233                 :  * could not be locked.
                                234                 :  *
                                235                 :  * Callback allows caller to check permissions or acquire additional locks
                                236                 :  * prior to grabbing the relation lock.
                                237                 :  */
                                238                 : Oid
 4148 rhaas                     239 GIC      528885 : RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode,
 1836 andres                    240 ECB             :                          uint32 flags,
                                241                 :                          RangeVarGetRelidCallback callback, void *callback_arg)
                                242                 : {
                                243                 :     uint64      inval_count;
                                244                 :     Oid         relId;
 4293 rhaas                     245 GIC      528885 :     Oid         oldRelId = InvalidOid;
 4293 rhaas                     246 CBC      528885 :     bool        retry = false;
 1836 andres                    247          528885 :     bool        missing_ok = (flags & RVR_MISSING_OK) != 0;
 7684 tgl                       248 ECB             : 
                                249                 :     /* verify that flags do no conflict */
 1836 andres                    250 GIC      528885 :     Assert(!((flags & RVR_NOWAIT) && (flags & RVR_SKIP_LOCKED)));
 1836 andres                    251 ECB             : 
                                252                 :     /*
                                253                 :      * We check the catalog name and then ignore it.
                                254                 :      */
 7684 tgl                       255 GIC      528885 :     if (relation->catalogname)
 7684 tgl                       256 ECB             :     {
 7226 peter_e                   257 GIC          39 :         if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
 7202 tgl                       258 CBC          39 :             ereport(ERROR,
 7202 tgl                       259 ECB             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                260                 :                      errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
                                261                 :                             relation->catalogname, relation->schemaname,
                                262                 :                             relation->relname)));
                                263                 :     }
                                264                 : 
                                265                 :     /*
                                266                 :      * DDL operations can change the results of a name lookup.  Since all such
                                267                 :      * operations will generate invalidation messages, we keep track of
                                268                 :      * whether any such messages show up while we're performing the operation,
                                269                 :      * and retry until either (1) no more invalidation messages show up or (2)
                                270                 :      * the answer doesn't change.
                                271                 :      *
                                272                 :      * But if lockmode = NoLock, then we assume that either the caller is OK
                                273                 :      * with the answer changing under them, or that they already hold some
                                274                 :      * appropriate lock, and therefore return the first answer we get without
                                275                 :      * checking for invalidation messages.  Also, if the requested lock is
                                276                 :      * already held, LockRelationOid will not AcceptInvalidationMessages, so
                                277                 :      * we may fail to notice a change.  We could protect against that case by
                                278                 :      * calling AcceptInvalidationMessages() before beginning this loop, but
                                279                 :      * that would add a significant amount overhead, so for now we don't.
                                280                 :      */
                                281                 :     for (;;)
                                282                 :     {
                                283                 :         /*
                                284                 :          * Remember this value, so that, after looking up the relation name
                                285                 :          * and locking its OID, we can check whether any invalidation messages
                                286                 :          * have been processed that might require a do-over.
                                287                 :          */
 4293 rhaas                     288 GIC      530398 :         inval_count = SharedInvalidMessageCounter;
 4293 rhaas                     289 ECB             : 
                                290                 :         /*
                                291                 :          * Some non-default relpersistence value may have been specified.  The
                                292                 :          * parser never generates such a RangeVar in simple DML, but it can
                                293                 :          * happen in contexts such as "CREATE TEMP TABLE foo (f1 int PRIMARY
                                294                 :          * KEY)".  Such a command will generate an added CREATE INDEX
                                295                 :          * operation, which must be careful to find the temp table, even when
                                296                 :          * pg_temp is not first in the search path.
                                297                 :          */
 4293 rhaas                     298 GIC      530398 :         if (relation->relpersistence == RELPERSISTENCE_TEMP)
 4293 rhaas                     299 ECB             :         {
 4218 rhaas                     300 GIC         503 :             if (!OidIsValid(myTempNamespace))
 2118 tgl                       301 LBC           0 :                 relId = InvalidOid; /* this probably can't happen? */
 4218 rhaas                     302 EUB             :             else
                                303                 :             {
 4218 rhaas                     304 GIC         503 :                 if (relation->schemaname)
 4218 rhaas                     305 ECB             :                 {
                                306                 :                     Oid         namespaceId;
                                307                 : 
 3725 bruce                     308 GIC          12 :                     namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
 3602 bruce                     309 ECB             : 
                                310                 :                     /*
                                311                 :                      * For missing_ok, allow a non-existent schema name to
                                312                 :                      * return InvalidOid.
                                313                 :                      */
 4218 rhaas                     314 GIC          12 :                     if (namespaceId != myTempNamespace)
 4218 rhaas                     315 LBC           0 :                         ereport(ERROR,
 4218 rhaas                     316 EUB             :                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                                317                 :                                  errmsg("temporary tables cannot specify a schema name")));
                                318                 :                 }
                                319                 : 
 4293 rhaas                     320 GIC         503 :                 relId = get_relname_relid(relation->relname, myTempNamespace);
 4218 rhaas                     321 ECB             :             }
                                322                 :         }
 4293 rhaas                     323 GIC      529895 :         else if (relation->schemaname)
 4293 rhaas                     324 ECB             :         {
                                325                 :             Oid         namespaceId;
                                326                 : 
                                327                 :             /* use exact schema given */
 3725 bruce                     328 GIC      109416 :             namespaceId = LookupExplicitNamespace(relation->schemaname, missing_ok);
 3725 bruce                     329 CBC      109364 :             if (missing_ok && !OidIsValid(namespaceId))
                                330              42 :                 relId = InvalidOid;
 3725 bruce                     331 ECB             :             else
 3725 bruce                     332 GIC      109322 :                 relId = get_relname_relid(relation->relname, namespaceId);
 4293 rhaas                     333 ECB             :         }
                                334                 :         else
                                335                 :         {
                                336                 :             /* search the namespace path */
 4293 rhaas                     337 GIC      420479 :             relId = RelnameGetRelid(relation->relname);
 4293 rhaas                     338 ECB             :         }
                                339                 : 
                                340                 :         /*
                                341                 :          * Invoke caller-supplied callback, if any.
                                342                 :          *
                                343                 :          * This callback is a good place to check permissions: we haven't
                                344                 :          * taken the table lock yet (and it's really best to check permissions
                                345                 :          * before locking anything!), but we've gotten far enough to know what
                                346                 :          * OID we think we should lock.  Of course, concurrent DDL might
                                347                 :          * change things while we're waiting for the lock, but in that case
                                348                 :          * the callback will be invoked again for the new OID.
                                349                 :          */
 4148 rhaas                     350 GIC      530346 :         if (callback)
 4148 rhaas                     351 CBC       68411 :             callback(relation, relId, oldRelId, callback_arg);
 4148 rhaas                     352 ECB             : 
                                353                 :         /*
                                354                 :          * If no lock requested, we assume the caller knows what they're
                                355                 :          * doing.  They should have already acquired a heavyweight lock on
                                356                 :          * this relation earlier in the processing of this same statement, so
                                357                 :          * it wouldn't be appropriate to AcceptInvalidationMessages() here, as
                                358                 :          * that might pull the rug out from under them.
                                359                 :          */
 4293 rhaas                     360 GIC      530183 :         if (lockmode == NoLock)
 4293 rhaas                     361 CBC      101858 :             break;
 4293 rhaas                     362 ECB             : 
                                363                 :         /*
                                364                 :          * If, upon retry, we get back the same OID we did last time, then the
                                365                 :          * invalidation messages we processed did not change the final answer.
                                366                 :          * So we're done.
                                367                 :          *
                                368                 :          * If we got a different OID, we've locked the relation that used to
                                369                 :          * have this name rather than the one that does now.  So release the
                                370                 :          * lock.
                                371                 :          */
 4166 rhaas                     372 GIC      428325 :         if (retry)
 4166 rhaas                     373 ECB             :         {
 4166 rhaas                     374 GIC        1552 :             if (relId == oldRelId)
 4166 rhaas                     375 CBC        1546 :                 break;
                                376               6 :             if (OidIsValid(oldRelId))
                                377               6 :                 UnlockRelationOid(oldRelId, lockmode);
 4166 rhaas                     378 ECB             :         }
                                379                 : 
                                380                 :         /*
                                381                 :          * Lock relation.  This will also accept any pending invalidation
                                382                 :          * messages.  If we got back InvalidOid, indicating not found, then
                                383                 :          * there's nothing to lock, but we accept invalidation messages
                                384                 :          * anyway, to flush any negative catcache entries that may be
                                385                 :          * lingering.
                                386                 :          */
 4293 rhaas                     387 GIC      426779 :         if (!OidIsValid(relId))
 4293 rhaas                     388 CBC         948 :             AcceptInvalidationMessages();
 1836 andres                    389          425831 :         else if (!(flags & (RVR_NOWAIT | RVR_SKIP_LOCKED)))
 4293 rhaas                     390          425514 :             LockRelationOid(relId, lockmode);
                                391             317 :         else if (!ConditionalLockRelationOid(relId, lockmode))
 4293 rhaas                     392 ECB             :         {
 1836 andres                    393 GIC           8 :             int         elevel = (flags & RVR_SKIP_LOCKED) ? DEBUG1 : ERROR;
 1836 andres                    394 ECB             : 
 4293 rhaas                     395 GIC           8 :             if (relation->schemaname)
 1836 andres                    396 LBC           0 :                 ereport(elevel,
 4293 rhaas                     397 EUB             :                         (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
                                398                 :                          errmsg("could not obtain lock on relation \"%s.%s\"",
                                399                 :                                 relation->schemaname, relation->relname)));
                                400                 :             else
 1836 andres                    401 GIC           8 :                 ereport(elevel,
 4293 rhaas                     402 ECB             :                         (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
                                403                 :                          errmsg("could not obtain lock on relation \"%s\"",
                                404                 :                                 relation->relname)));
                                405                 : 
 1836 andres                    406 GIC           4 :             return InvalidOid;
 4293 rhaas                     407 ECB             :         }
                                408                 : 
                                409                 :         /*
                                410                 :          * If no invalidation message were processed, we're done!
                                411                 :          */
 4293 rhaas                     412 GIC      426764 :         if (inval_count == SharedInvalidMessageCounter)
 4293 rhaas                     413 CBC      425212 :             break;
 4293 rhaas                     414 ECB             : 
                                415                 :         /*
                                416                 :          * Something may have changed.  Let's repeat the name lookup, to make
                                417                 :          * sure this name still references the same relation it did
                                418                 :          * previously.
                                419                 :          */
 4293 rhaas                     420 GIC        1552 :         retry = true;
 4293 rhaas                     421 CBC        1552 :         oldRelId = relId;
 7684 tgl                       422 ECB             :     }
                                423                 : 
 1836 andres                    424 GIC      528616 :     if (!OidIsValid(relId))
 7684 tgl                       425 ECB             :     {
 1836 andres                    426 GIC         986 :         int         elevel = missing_ok ? DEBUG1 : ERROR;
 1836 andres                    427 ECB             : 
 7684 tgl                       428 GIC         986 :         if (relation->schemaname)
 1836 andres                    429 CBC         130 :             ereport(elevel,
 7202 tgl                       430 ECB             :                     (errcode(ERRCODE_UNDEFINED_TABLE),
                                431                 :                      errmsg("relation \"%s.%s\" does not exist",
                                432                 :                             relation->schemaname, relation->relname)));
                                433                 :         else
 1836 andres                    434 GIC         856 :             ereport(elevel,
 7202 tgl                       435 ECB             :                     (errcode(ERRCODE_UNDEFINED_TABLE),
                                436                 :                      errmsg("relation \"%s\" does not exist",
                                437                 :                             relation->relname)));
                                438                 :     }
 7684 tgl                       439 GIC      528394 :     return relId;
 7684 tgl                       440 ECB             : }
                                441                 : 
                                442                 : /*
                                443                 :  * RangeVarGetCreationNamespace
                                444                 :  *      Given a RangeVar describing a to-be-created relation,
                                445                 :  *      choose which namespace to create it in.
                                446                 :  *
                                447                 :  * Note: calling this may result in a CommandCounterIncrement operation.
                                448                 :  * That will happen on the first request for a temp table in any particular
                                449                 :  * backend run; we will need to either create or clean out the temp schema.
                                450                 :  */
                                451                 : Oid
 7684 tgl                       452 GIC      126763 : RangeVarGetCreationNamespace(const RangeVar *newRelation)
 7684 tgl                       453 ECB             : {
                                454                 :     Oid         namespaceId;
                                455                 : 
                                456                 :     /*
                                457                 :      * We check the catalog name and then ignore it.
                                458                 :      */
 7684 tgl                       459 GIC      126763 :     if (newRelation->catalogname)
 7684 tgl                       460 ECB             :     {
 7226 peter_e                   461 UIC           0 :         if (strcmp(newRelation->catalogname, get_database_name(MyDatabaseId)) != 0)
 7202 tgl                       462 UBC           0 :             ereport(ERROR,
 7202 tgl                       463 EUB             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                464                 :                      errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
                                465                 :                             newRelation->catalogname, newRelation->schemaname,
                                466                 :                             newRelation->relname)));
                                467                 :     }
                                468                 : 
 7684 tgl                       469 GIC      126763 :     if (newRelation->schemaname)
 7684 tgl                       470 ECB             :     {
                                471                 :         /* check for pg_temp alias */
 5833 tgl                       472 GIC       19070 :         if (strcmp(newRelation->schemaname, "pg_temp") == 0)
 5833 tgl                       473 ECB             :         {
                                474                 :             /* Initialize temp namespace */
 1542 michael                   475 GIC          37 :             AccessTempTableNamespace(false);
 5833 tgl                       476 CBC          37 :             return myTempNamespace;
 5833 tgl                       477 ECB             :         }
                                478                 :         /* use exact schema given */
 4630 rhaas                     479 GIC       19033 :         namespaceId = get_namespace_oid(newRelation->schemaname, false);
 7559 tgl                       480 ECB             :         /* we do not check for USAGE rights here! */
                                481                 :     }
 4298 rhaas                     482 GIC      107693 :     else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
 4298 rhaas                     483 ECB             :     {
                                484                 :         /* Initialize temp namespace */
 1542 michael                   485 GIC        2921 :         AccessTempTableNamespace(false);
 4298 rhaas                     486 CBC        2921 :         return myTempNamespace;
 4298 rhaas                     487 ECB             :     }
                                488                 :     else
                                489                 :     {
                                490                 :         /* use the default creation namespace */
 7650 tgl                       491 GIC      104772 :         recomputeNamespacePath();
 5833 tgl                       492 CBC      104772 :         if (activeTempCreationPending)
 5833 tgl                       493 ECB             :         {
                                494                 :             /* Need to initialize temp namespace */
 1542 michael                   495 UIC           0 :             AccessTempTableNamespace(true);
 5833 tgl                       496 UBC           0 :             return myTempNamespace;
 5833 tgl                       497 EUB             :         }
 5861 tgl                       498 GIC      104772 :         namespaceId = activeCreationNamespace;
 7664 tgl                       499 CBC      104772 :         if (!OidIsValid(namespaceId))
 7202 tgl                       500 LBC           0 :             ereport(ERROR,
 7202 tgl                       501 EUB             :                     (errcode(ERRCODE_UNDEFINED_SCHEMA),
                                502                 :                      errmsg("no schema has been selected to create in")));
                                503                 :     }
                                504                 : 
                                505                 :     /* Note: callers will check for CREATE rights when appropriate */
                                506                 : 
 7684 tgl                       507 GIC      123805 :     return namespaceId;
 7684 tgl                       508 ECB             : }
                                509                 : 
                                510                 : /*
                                511                 :  * RangeVarGetAndCheckCreationNamespace
                                512                 :  *
                                513                 :  * This function returns the OID of the namespace in which a new relation
                                514                 :  * with a given name should be created.  If the user does not have CREATE
                                515                 :  * permission on the target namespace, this function will instead signal
                                516                 :  * an ERROR.
                                517                 :  *
                                518                 :  * If non-NULL, *existing_relation_id is set to the OID of any existing relation
                                519                 :  * with the same name which already exists in that namespace, or to InvalidOid
                                520                 :  * if no such relation exists.
                                521                 :  *
                                522                 :  * If lockmode != NoLock, the specified lock mode is acquired on the existing
                                523                 :  * relation, if any, provided that the current user owns the target relation.
                                524                 :  * However, if lockmode != NoLock and the user does not own the target
                                525                 :  * relation, we throw an ERROR, as we must not try to lock relations the
                                526                 :  * user does not have permissions on.
                                527                 :  *
                                528                 :  * As a side effect, this function acquires AccessShareLock on the target
                                529                 :  * namespace.  Without this, the namespace could be dropped before our
                                530                 :  * transaction commits, leaving behind relations with relnamespace pointing
                                531                 :  * to a no-longer-existent namespace.
                                532                 :  *
                                533                 :  * As a further side-effect, if the selected namespace is a temporary namespace,
                                534                 :  * we mark the RangeVar as RELPERSISTENCE_TEMP.
                                535                 :  */
                                536                 : Oid
 4101 rhaas                     537 GIC      124629 : RangeVarGetAndCheckCreationNamespace(RangeVar *relation,
 4101 rhaas                     538 ECB             :                                      LOCKMODE lockmode,
                                539                 :                                      Oid *existing_relation_id)
                                540                 : {
                                541                 :     uint64      inval_count;
                                542                 :     Oid         relid;
 4101 rhaas                     543 GIC      124629 :     Oid         oldrelid = InvalidOid;
 4101 rhaas                     544 ECB             :     Oid         nspid;
 4101 rhaas                     545 GIC      124629 :     Oid         oldnspid = InvalidOid;
 4101 rhaas                     546 CBC      124629 :     bool        retry = false;
 4367 rhaas                     547 ECB             : 
                                548                 :     /*
                                549                 :      * We check the catalog name and then ignore it.
                                550                 :      */
 4101 rhaas                     551 GIC      124629 :     if (relation->catalogname)
 4101 rhaas                     552 ECB             :     {
 4101 rhaas                     553 UIC           0 :         if (strcmp(relation->catalogname, get_database_name(MyDatabaseId)) != 0)
 4101 rhaas                     554 UBC           0 :             ereport(ERROR,
 4101 rhaas                     555 EUB             :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                556                 :                      errmsg("cross-database references are not implemented: \"%s.%s.%s\"",
                                557                 :                             relation->catalogname, relation->schemaname,
                                558                 :                             relation->relname)));
                                559                 :     }
                                560                 : 
                                561                 :     /*
                                562                 :      * As in RangeVarGetRelidExtended(), we guard against concurrent DDL
                                563                 :      * operations by tracking whether any invalidation messages are processed
                                564                 :      * while we're doing the name lookups and acquiring locks.  See comments
                                565                 :      * in that function for a more detailed explanation of this logic.
                                566                 :      */
                                567                 :     for (;;)
 4367 rhaas                     568 GIC         792 :     {
 4367 rhaas                     569 ECB             :         AclResult   aclresult;
                                570                 : 
 4101 rhaas                     571 GIC      125421 :         inval_count = SharedInvalidMessageCounter;
 4101 rhaas                     572 ECB             : 
                                573                 :         /* Look up creation namespace and check for existing relation. */
 4101 rhaas                     574 GIC      125421 :         nspid = RangeVarGetCreationNamespace(relation);
 4101 rhaas                     575 CBC      125421 :         Assert(OidIsValid(nspid));
                                576          125421 :         if (existing_relation_id != NULL)
                                577           61934 :             relid = get_relname_relid(relation->relname, nspid);
 4101 rhaas                     578 ECB             :         else
 4101 rhaas                     579 GIC       63487 :             relid = InvalidOid;
 4101 rhaas                     580 ECB             : 
                                581                 :         /*
                                582                 :          * In bootstrap processing mode, we don't bother with permissions or
                                583                 :          * locking.  Permissions might not be working yet, and locking is
                                584                 :          * unnecessary.
                                585                 :          */
 4101 rhaas                     586 GIC      125421 :         if (IsBootstrapProcessingMode())
 4101 rhaas                     587 LBC           0 :             break;
 4101 rhaas                     588 EUB             : 
                                589                 :         /* Check namespace permissions. */
  147 peter                     590 GNC      125421 :         aclresult = object_aclcheck(NamespaceRelationId, nspid, GetUserId(), ACL_CREATE);
 4367 rhaas                     591 CBC      125421 :         if (aclresult != ACLCHECK_OK)
 1954 peter_e                   592 LBC           0 :             aclcheck_error(aclresult, OBJECT_SCHEMA,
 4101 rhaas                     593 UBC           0 :                            get_namespace_name(nspid));
 4101 rhaas                     594 EUB             : 
 4101 rhaas                     595 GIC      125421 :         if (retry)
 4101 rhaas                     596 ECB             :         {
                                597                 :             /* If nothing changed, we're done. */
 4101 rhaas                     598 GIC         792 :             if (relid == oldrelid && nspid == oldnspid)
 4101 rhaas                     599 CBC         792 :                 break;
 4101 rhaas                     600 ECB             :             /* If creation namespace has changed, give up old lock. */
 4101 rhaas                     601 UIC           0 :             if (nspid != oldnspid)
 4101 rhaas                     602 UBC           0 :                 UnlockDatabaseObject(NamespaceRelationId, oldnspid, 0,
 4101 rhaas                     603 EUB             :                                      AccessShareLock);
                                604                 :             /* If name points to something different, give up old lock. */
 4101 rhaas                     605 UIC           0 :             if (relid != oldrelid && OidIsValid(oldrelid) && lockmode != NoLock)
 4101 rhaas                     606 UBC           0 :                 UnlockRelationOid(oldrelid, lockmode);
 4101 rhaas                     607 EUB             :         }
                                608                 : 
                                609                 :         /* Lock namespace. */
 4101 rhaas                     610 GIC      124629 :         if (nspid != oldnspid)
 4101 rhaas                     611 CBC      124629 :             LockDatabaseObject(NamespaceRelationId, nspid, 0, AccessShareLock);
 4101 rhaas                     612 ECB             : 
                                613                 :         /* Lock relation, if required if and we have permission. */
 4101 rhaas                     614 GIC      124629 :         if (lockmode != NoLock && OidIsValid(relid))
 4101 rhaas                     615 ECB             :         {
  147 peter                     616 GNC         112 :             if (!object_ownercheck(RelationRelationId, relid, GetUserId()))
 1954 peter_e                   617 LBC           0 :                 aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relid)),
 4101 rhaas                     618 UBC           0 :                                relation->relname);
 4101 rhaas                     619 GBC         112 :             if (relid != oldrelid)
 4101 rhaas                     620 CBC         112 :                 LockRelationOid(relid, lockmode);
 4101 rhaas                     621 ECB             :         }
                                622                 : 
                                623                 :         /* If no invalidation message were processed, we're done! */
 4101 rhaas                     624 GIC      124629 :         if (inval_count == SharedInvalidMessageCounter)
 4101 rhaas                     625 CBC      123837 :             break;
 4101 rhaas                     626 ECB             : 
                                627                 :         /* Something may have changed, so recheck our work. */
 4101 rhaas                     628 GIC         792 :         retry = true;
 4101 rhaas                     629 CBC         792 :         oldrelid = relid;
                                630             792 :         oldnspid = nspid;
 4367 rhaas                     631 ECB             :     }
                                632                 : 
 4101 rhaas                     633 GIC      124629 :     RangeVarAdjustRelationPersistence(relation, nspid);
 4101 rhaas                     634 CBC      124617 :     if (existing_relation_id != NULL)
                                635           61314 :         *existing_relation_id = relid;
                                636          124617 :     return nspid;
 4367 rhaas                     637 ECB             : }
                                638                 : 
                                639                 : /*
                                640                 :  * Adjust the relpersistence for an about-to-be-created relation based on the
                                641                 :  * creation namespace, and throw an error for invalid combinations.
                                642                 :  */
                                643                 : void
 4298 rhaas                     644 GIC      125364 : RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid)
 4298 rhaas                     645 ECB             : {
 4298 rhaas                     646 GIC      125364 :     switch (newRelation->relpersistence)
 4298 rhaas                     647 ECB             :     {
 4298 rhaas                     648 GIC        2705 :         case RELPERSISTENCE_TEMP:
 3149 bruce                     649 CBC        2705 :             if (!isTempOrTempToastNamespace(nspid))
 4298 rhaas                     650 ECB             :             {
 4298 rhaas                     651 GIC           9 :                 if (isAnyTempNamespace(nspid))
 4298 rhaas                     652 LBC           0 :                     ereport(ERROR,
 4298 rhaas                     653 EUB             :                             (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                                654                 :                              errmsg("cannot create relations in temporary schemas of other sessions")));
                                655                 :                 else
 4298 rhaas                     656 GIC           9 :                     ereport(ERROR,
 4298 rhaas                     657 ECB             :                             (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                                658                 :                              errmsg("cannot create temporary relation in non-temporary schema")));
                                659                 :             }
 4298 rhaas                     660 GIC        2696 :             break;
 4298 rhaas                     661 CBC      122501 :         case RELPERSISTENCE_PERMANENT:
 3149 bruce                     662          122501 :             if (isTempOrTempToastNamespace(nspid))
 4298 rhaas                     663              13 :                 newRelation->relpersistence = RELPERSISTENCE_TEMP;
                                664          122488 :             else if (isAnyTempNamespace(nspid))
 4298 rhaas                     665 LBC           0 :                 ereport(ERROR,
 4298 rhaas                     666 EUB             :                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                                667                 :                          errmsg("cannot create relations in temporary schemas of other sessions")));
 4298 rhaas                     668 GIC      122501 :             break;
 4298 rhaas                     669 CBC         158 :         default:
 4279                           670             158 :             if (isAnyTempNamespace(nspid))
                                671               3 :                 ereport(ERROR,
 4279 rhaas                     672 ECB             :                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
                                673                 :                          errmsg("only temporary relations may be created in temporary schemas")));
                                674                 :     }
 4298 rhaas                     675 GIC      125352 : }
 4298 rhaas                     676 ECB             : 
                                677                 : /*
                                678                 :  * RelnameGetRelid
                                679                 :  *      Try to resolve an unqualified relation name.
                                680                 :  *      Returns OID if relation found in search path, else InvalidOid.
                                681                 :  */
                                682                 : Oid
 7684 tgl                       683 GIC      420521 : RelnameGetRelid(const char *relname)
 7684 tgl                       684 ECB             : {
                                685                 :     Oid         relid;
                                686                 :     ListCell   *l;
                                687                 : 
 7650 tgl                       688 GIC      420521 :     recomputeNamespacePath();
 7650 tgl                       689 ECB             : 
 5861 tgl                       690 GIC      592021 :     foreach(l, activeSearchPath)
 7679 tgl                       691 ECB             :     {
 6892 neilc                     692 GIC      591145 :         Oid         namespaceId = lfirst_oid(l);
 7679 tgl                       693 ECB             : 
 7679 tgl                       694 GIC      591145 :         relid = get_relname_relid(relname, namespaceId);
 7679 tgl                       695 CBC      591145 :         if (OidIsValid(relid))
                                696          419645 :             return relid;
 7679 tgl                       697 ECB             :     }
                                698                 : 
                                699                 :     /* Not found in path */
 7679 tgl                       700 GIC         876 :     return InvalidOid;
 7684 tgl                       701 ECB             : }
                                702                 : 
                                703                 : 
                                704                 : /*
                                705                 :  * RelationIsVisible
                                706                 :  *      Determine whether a relation (identified by OID) is visible in the
                                707                 :  *      current search path.  Visible means "would be found by searching
                                708                 :  *      for the unqualified relation name".
                                709                 :  */
                                710                 : bool
 7648 tgl                       711 GIC      120449 : RelationIsVisible(Oid relid)
 7648 tgl                       712 ECB             : {
                                713                 :     HeapTuple   reltup;
                                714                 :     Form_pg_class relform;
                                715                 :     Oid         relnamespace;
                                716                 :     bool        visible;
                                717                 : 
 4802 rhaas                     718 GIC      120449 :     reltup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
 7648 tgl                       719 CBC      120449 :     if (!HeapTupleIsValid(reltup))
 7202 tgl                       720 LBC           0 :         elog(ERROR, "cache lookup failed for relation %u", relid);
 7648 tgl                       721 GBC      120449 :     relform = (Form_pg_class) GETSTRUCT(reltup);
 7648 tgl                       722 ECB             : 
 7632 tgl                       723 GIC      120449 :     recomputeNamespacePath();
 7632 tgl                       724 ECB             : 
                                725                 :     /*
                                726                 :      * Quick check: if it ain't in the path at all, it ain't visible. Items in
                                727                 :      * the system namespace are surely in the path and so we needn't even do
                                728                 :      * list_member_oid() for them.
                                729                 :      */
 7648 tgl                       730 GIC      120449 :     relnamespace = relform->relnamespace;
 7632 tgl                       731 CBC      120449 :     if (relnamespace != PG_CATALOG_NAMESPACE &&
 5861                           732          100430 :         !list_member_oid(activeSearchPath, relnamespace))
 7648                           733           40098 :         visible = false;
 7648 tgl                       734 ECB             :     else
                                735                 :     {
                                736                 :         /*
                                737                 :          * If it is in the path, it might still not be visible; it could be
                                738                 :          * hidden by another relation of the same name earlier in the path. So
                                739                 :          * we must do a slow check for conflicting relations.
                                740                 :          */
 7648 tgl                       741 GIC       80351 :         char       *relname = NameStr(relform->relname);
 6394 tgl                       742 ECB             :         ListCell   *l;
                                743                 : 
 6394 tgl                       744 GIC       80351 :         visible = false;
 5861 tgl                       745 CBC      195724 :         foreach(l, activeSearchPath)
 6394 tgl                       746 ECB             :         {
 6394 tgl                       747 GIC      195724 :             Oid         namespaceId = lfirst_oid(l);
 6394 tgl                       748 ECB             : 
 6394 tgl                       749 GIC      195724 :             if (namespaceId == relnamespace)
 6394 tgl                       750 ECB             :             {
                                751                 :                 /* Found it first in path */
 6394 tgl                       752 GIC       80327 :                 visible = true;
 6394 tgl                       753 CBC       80327 :                 break;
 6394 tgl                       754 ECB             :             }
 6394 tgl                       755 GIC      115397 :             if (OidIsValid(get_relname_relid(relname, namespaceId)))
 6394 tgl                       756 ECB             :             {
                                757                 :                 /* Found something else first in path */
 6394 tgl                       758 GIC          24 :                 break;
 6394 tgl                       759 ECB             :             }
                                760                 :         }
                                761                 :     }
                                762                 : 
 7648 tgl                       763 GIC      120449 :     ReleaseSysCache(reltup);
 7648 tgl                       764 ECB             : 
 7648 tgl                       765 GIC      120449 :     return visible;
 7648 tgl                       766 ECB             : }
                                767                 : 
                                768                 : 
                                769                 : /*
                                770                 :  * TypenameGetTypid
                                771                 :  *      Wrapper for binary compatibility.
                                772                 :  */
                                773                 : Oid
 1343 noah                      774 UIC           0 : TypenameGetTypid(const char *typname)
 1343 noah                      775 EUB             : {
 1343 noah                      776 UIC           0 :     return TypenameGetTypidExtended(typname, true);
 1343 noah                      777 EUB             : }
                                778                 : 
                                779                 : /*
                                780                 :  * TypenameGetTypidExtended
                                781                 :  *      Try to resolve an unqualified datatype name.
                                782                 :  *      Returns OID if type found in search path, else InvalidOid.
                                783                 :  *
                                784                 :  * This is essentially the same as RelnameGetRelid.
                                785                 :  */
                                786                 : Oid
 1343 noah                      787 GIC      450727 : TypenameGetTypidExtended(const char *typname, bool temp_ok)
 7680 tgl                       788 ECB             : {
                                789                 :     Oid         typid;
                                790                 :     ListCell   *l;
                                791                 : 
 7650 tgl                       792 GIC      450727 :     recomputeNamespacePath();
 7650 tgl                       793 ECB             : 
 5861 tgl                       794 GIC      746667 :     foreach(l, activeSearchPath)
 7679 tgl                       795 ECB             :     {
 6892 neilc                     796 GIC      712147 :         Oid         namespaceId = lfirst_oid(l);
 7679 tgl                       797 ECB             : 
 1343 noah                      798 GIC      712147 :         if (!temp_ok && namespaceId == myTempNamespace)
 1343 noah                      799 CBC        2926 :             continue;           /* do not look in temp namespace */
 1343 noah                      800 ECB             : 
 1601 andres                    801 GIC      709221 :         typid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
 4802 rhaas                     802 ECB             :                                 PointerGetDatum(typname),
                                803                 :                                 ObjectIdGetDatum(namespaceId));
 7679 tgl                       804 GIC      709221 :         if (OidIsValid(typid))
 7679 tgl                       805 CBC      416207 :             return typid;
 7679 tgl                       806 ECB             :     }
                                807                 : 
                                808                 :     /* Not found in path */
 7679 tgl                       809 GIC       34520 :     return InvalidOid;
 7680 tgl                       810 ECB             : }
                                811                 : 
                                812                 : /*
                                813                 :  * TypeIsVisible
                                814                 :  *      Determine whether a type (identified by OID) is visible in the
                                815                 :  *      current search path.  Visible means "would be found by searching
                                816                 :  *      for the unqualified type name".
                                817                 :  */
                                818                 : bool
 7648 tgl                       819 GIC      201192 : TypeIsVisible(Oid typid)
 7662 tgl                       820 ECB             : {
                                821                 :     HeapTuple   typtup;
                                822                 :     Form_pg_type typform;
                                823                 :     Oid         typnamespace;
                                824                 :     bool        visible;
                                825                 : 
 4802 rhaas                     826 GIC      201192 :     typtup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
 7648 tgl                       827 CBC      201192 :     if (!HeapTupleIsValid(typtup))
 7202 tgl                       828 LBC           0 :         elog(ERROR, "cache lookup failed for type %u", typid);
 7648 tgl                       829 GBC      201192 :     typform = (Form_pg_type) GETSTRUCT(typtup);
 7662 tgl                       830 ECB             : 
 7632 tgl                       831 GIC      201192 :     recomputeNamespacePath();
 7632 tgl                       832 ECB             : 
                                833                 :     /*
                                834                 :      * Quick check: if it ain't in the path at all, it ain't visible. Items in
                                835                 :      * the system namespace are surely in the path and so we needn't even do
                                836                 :      * list_member_oid() for them.
                                837                 :      */
 7648 tgl                       838 GIC      201192 :     typnamespace = typform->typnamespace;
 7648 tgl                       839 CBC      201192 :     if (typnamespace != PG_CATALOG_NAMESPACE &&
 5861                           840           37472 :         !list_member_oid(activeSearchPath, typnamespace))
 7648                           841            4051 :         visible = false;
 7648 tgl                       842 ECB             :     else
                                843                 :     {
                                844                 :         /*
                                845                 :          * If it is in the path, it might still not be visible; it could be
                                846                 :          * hidden by another type of the same name earlier in the path. So we
                                847                 :          * must do a slow check for conflicting types.
                                848                 :          */
 7648 tgl                       849 GIC      197141 :         char       *typname = NameStr(typform->typname);
 6394 tgl                       850 ECB             :         ListCell   *l;
                                851                 : 
 6394 tgl                       852 GIC      197141 :         visible = false;
 5861 tgl                       853 CBC      248842 :         foreach(l, activeSearchPath)
 6394 tgl                       854 ECB             :         {
 6394 tgl                       855 GIC      248842 :             Oid         namespaceId = lfirst_oid(l);
 6394 tgl                       856 ECB             : 
 6394 tgl                       857 GIC      248842 :             if (namespaceId == typnamespace)
 6394 tgl                       858 ECB             :             {
                                859                 :                 /* Found it first in path */
 6394 tgl                       860 GIC      197135 :                 visible = true;
 6394 tgl                       861 CBC      197135 :                 break;
 6394 tgl                       862 ECB             :             }
 4802 rhaas                     863 GIC       51707 :             if (SearchSysCacheExists2(TYPENAMENSP,
 4802 rhaas                     864 ECB             :                                       PointerGetDatum(typname),
                                865                 :                                       ObjectIdGetDatum(namespaceId)))
                                866                 :             {
                                867                 :                 /* Found something else first in path */
 6394 tgl                       868 GIC           6 :                 break;
 6394 tgl                       869 ECB             :             }
                                870                 :         }
                                871                 :     }
                                872                 : 
 7648 tgl                       873 GIC      201192 :     ReleaseSysCache(typtup);
 7648 tgl                       874 ECB             : 
 7648 tgl                       875 GIC      201192 :     return visible;
 7662 tgl                       876 ECB             : }
                                877                 : 
                                878                 : 
                                879                 : /*
                                880                 :  * FuncnameGetCandidates
                                881                 :  *      Given a possibly-qualified function name and argument count,
                                882                 :  *      retrieve a list of the possible matches.
                                883                 :  *
                                884                 :  * If nargs is -1, we return all functions matching the given name,
                                885                 :  * regardless of argument count.  (argnames must be NIL, and expand_variadic
                                886                 :  * and expand_defaults must be false, in this case.)
                                887                 :  *
                                888                 :  * If argnames isn't NIL, we are considering a named- or mixed-notation call,
                                889                 :  * and only functions having all the listed argument names will be returned.
                                890                 :  * (We assume that length(argnames) <= nargs and all the passed-in names are
                                891                 :  * distinct.)  The returned structs will include an argnumbers array showing
                                892                 :  * the actual argument index for each logical argument position.
                                893                 :  *
                                894                 :  * If expand_variadic is true, then variadic functions having the same number
                                895                 :  * or fewer arguments will be retrieved, with the variadic argument and any
                                896                 :  * additional argument positions filled with the variadic element type.
                                897                 :  * nvargs in the returned struct is set to the number of such arguments.
                                898                 :  * If expand_variadic is false, variadic arguments are not treated specially,
                                899                 :  * and the returned nvargs will always be zero.
                                900                 :  *
                                901                 :  * If expand_defaults is true, functions that could match after insertion of
                                902                 :  * default argument values will also be retrieved.  In this case the returned
                                903                 :  * structs could have nargs > passed-in nargs, and ndargs is set to the number
                                904                 :  * of additional args (which can be retrieved from the function's
                                905                 :  * proargdefaults entry).
                                906                 :  *
                                907                 :  * If include_out_arguments is true, then OUT-mode arguments are considered to
                                908                 :  * be included in the argument list.  Their types are included in the returned
                                909                 :  * arrays, and argnumbers are indexes in proallargtypes not proargtypes.
                                910                 :  * We also set nominalnargs to be the length of proallargtypes not proargtypes.
                                911                 :  * Otherwise OUT-mode arguments are ignored.
                                912                 :  *
                                913                 :  * It is not possible for nvargs and ndargs to both be nonzero in the same
                                914                 :  * list entry, since default insertion allows matches to functions with more
                                915                 :  * than nargs arguments while the variadic transformation requires the same
                                916                 :  * number or less.
                                917                 :  *
                                918                 :  * When argnames isn't NIL, the returned args[] type arrays are not ordered
                                919                 :  * according to the functions' declarations, but rather according to the call:
                                920                 :  * first any positional arguments, then the named arguments, then defaulted
                                921                 :  * arguments (if needed and allowed by expand_defaults).  The argnumbers[]
                                922                 :  * array can be used to map this back to the catalog information.
                                923                 :  * argnumbers[k] is set to the proargtypes or proallargtypes index of the
                                924                 :  * k'th call argument.
                                925                 :  *
                                926                 :  * We search a single namespace if the function name is qualified, else
                                927                 :  * all namespaces in the search path.  In the multiple-namespace case,
                                928                 :  * we arrange for entries in earlier namespaces to mask identical entries in
                                929                 :  * later namespaces.
                                930                 :  *
                                931                 :  * When expanding variadics, we arrange for non-variadic functions to mask
                                932                 :  * variadic ones if the expanded argument list is the same.  It is still
                                933                 :  * possible for there to be conflicts between different variadic functions,
                                934                 :  * however.
                                935                 :  *
                                936                 :  * It is guaranteed that the return list will never contain multiple entries
                                937                 :  * with identical argument lists.  When expand_defaults is true, the entries
                                938                 :  * could have more than nargs positions, but we still guarantee that they are
                                939                 :  * distinct in the first nargs positions.  However, if argnames isn't NIL or
                                940                 :  * either expand_variadic or expand_defaults is true, there might be multiple
                                941                 :  * candidate functions that expand to identical argument lists.  Rather than
                                942                 :  * throw error here, we report such situations by returning a single entry
                                943                 :  * with oid = 0 that represents a set of such conflicting candidates.
                                944                 :  * The caller might end up discarding such an entry anyway, but if it selects
                                945                 :  * such an entry it should react as though the call were ambiguous.
                                946                 :  *
                                947                 :  * If missing_ok is true, an empty list (NULL) is returned if the name was
                                948                 :  * schema-qualified with a schema that does not exist.  Likewise if no
                                949                 :  * candidate is found for other reasons.
                                950                 :  */
                                951                 : FuncCandidateList
 4931 tgl                       952 GIC      376192 : FuncnameGetCandidates(List *names, int nargs, List *argnames,
 3363 alvherre                  953 ECB             :                       bool expand_variadic, bool expand_defaults,
                                954                 :                       bool include_out_arguments, bool missing_ok)
                                955                 : {
 7673 tgl                       956 GIC      376192 :     FuncCandidateList resultList = NULL;
 5225 tgl                       957 CBC      376192 :     bool        any_special = false;
 7559 tgl                       958 ECB             :     char       *schemaname;
                                959                 :     char       *funcname;
                                960                 :     Oid         namespaceId;
                                961                 :     CatCList   *catlist;
                                962                 :     int         i;
                                963                 : 
                                964                 :     /* check for caller error */
 5225 tgl                       965 GIC      376192 :     Assert(nargs >= 0 || !(expand_variadic | expand_defaults));
 5380 tgl                       966 ECB             : 
                                967                 :     /* deconstruct the name list */
 7559 tgl                       968 GIC      376192 :     DeconstructQualifiedName(names, &schemaname, &funcname);
 7673 tgl                       969 ECB             : 
 7673 tgl                       970 GIC      376174 :     if (schemaname)
 7673 tgl                       971 ECB             :     {
                                972                 :         /* use exact schema given */
 3363 alvherre                  973 GIC       61165 :         namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
 3363 alvherre                  974 CBC       61165 :         if (!OidIsValid(namespaceId))
                                975              24 :             return NULL;
 7673 tgl                       976 ECB             :     }
                                977                 :     else
                                978                 :     {
                                979                 :         /* flag to indicate we need namespace search */
 7673 tgl                       980 GIC      315009 :         namespaceId = InvalidOid;
 7650 tgl                       981 CBC      315009 :         recomputeNamespacePath();
 7673 tgl                       982 ECB             :     }
                                983                 : 
                                984                 :     /* Search syscache by name only */
 4802 rhaas                     985 GIC      376150 :     catlist = SearchSysCacheList1(PROCNAMEARGSNSP, CStringGetDatum(funcname));
 7673 tgl                       986 ECB             : 
 7673 tgl                       987 GIC     1238280 :     for (i = 0; i < catlist->n_members; i++)
 7673 tgl                       988 ECB             :     {
 7673 tgl                       989 GIC      862130 :         HeapTuple   proctup = &catlist->members[i]->tuple;
 7673 tgl                       990 CBC      862130 :         Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
  668                           991          862130 :         Oid        *proargtypes = procform->proargtypes.values;
 6585                           992          862130 :         int         pronargs = procform->pronargs;
 5380 tgl                       993 ECB             :         int         effective_nargs;
 7673 tgl                       994 GIC      862130 :         int         pathpos = 0;
 5380 tgl                       995 ECB             :         bool        variadic;
                                996                 :         bool        use_defaults;
                                997                 :         Oid         va_elem_type;
 4931 tgl                       998 GIC      862130 :         int        *argnumbers = NULL;
 7673 tgl                       999 ECB             :         FuncCandidateList newResult;
                               1000                 : 
 7673 tgl                      1001 GIC      862130 :         if (OidIsValid(namespaceId))
 7673 tgl                      1002 ECB             :         {
                               1003                 :             /* Consider only procs in specified namespace */
 7673 tgl                      1004 GIC      155206 :             if (procform->pronamespace != namespaceId)
 7673 tgl                      1005 CBC      252507 :                 continue;
 7673 tgl                      1006 ECB             :         }
                               1007                 :         else
                               1008                 :         {
                               1009                 :             /*
                               1010                 :              * Consider only procs that are in the search path and are not in
                               1011                 :              * the temp namespace.
                               1012                 :              */
                               1013                 :             ListCell   *nsp;
                               1014                 : 
 5861 tgl                      1015 GIC      838268 :             foreach(nsp, activeSearchPath)
 7632 tgl                      1016 ECB             :             {
 5833 tgl                      1017 GIC      836638 :                 if (procform->pronamespace == lfirst_oid(nsp) &&
 5833 tgl                      1018 CBC      705312 :                     procform->pronamespace != myTempNamespace)
 7632                          1019          705294 :                     break;
                               1020          131344 :                 pathpos++;
 7673 tgl                      1021 ECB             :             }
 6892 neilc                    1022 GIC      706924 :             if (nsp == NULL)
 7632 tgl                      1023 CBC        1630 :                 continue;       /* proc is not in search path */
 5380 tgl                      1024 ECB             :         }
                               1025                 : 
                               1026                 :         /*
                               1027                 :          * If we are asked to match to OUT arguments, then use the
                               1028                 :          * proallargtypes array (which includes those); otherwise use
                               1029                 :          * proargtypes (which doesn't).  Of course, if proallargtypes is null,
                               1030                 :          * we always use proargtypes.
                               1031                 :          */
  668 tgl                      1032 GIC      856839 :         if (include_out_arguments)
  668 tgl                      1033 ECB             :         {
                               1034                 :             Datum       proallargtypes;
                               1035                 :             bool        isNull;
                               1036                 : 
  668 tgl                      1037 GIC         290 :             proallargtypes = SysCacheGetAttr(PROCNAMEARGSNSP, proctup,
  668 tgl                      1038 ECB             :                                              Anum_pg_proc_proallargtypes,
                               1039                 :                                              &isNull);
  668 tgl                      1040 GIC         290 :             if (!isNull)
  668 tgl                      1041 ECB             :             {
  668 tgl                      1042 GIC          85 :                 ArrayType  *arr = DatumGetArrayTypeP(proallargtypes);
  668 tgl                      1043 ECB             : 
  668 tgl                      1044 GIC          85 :                 pronargs = ARR_DIMS(arr)[0];
  668 tgl                      1045 CBC          85 :                 if (ARR_NDIM(arr) != 1 ||
                               1046              85 :                     pronargs < 0 ||
                               1047              85 :                     ARR_HASNULL(arr) ||
                               1048              85 :                     ARR_ELEMTYPE(arr) != OIDOID)
  668 tgl                      1049 LBC           0 :                     elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls");
  668 tgl                      1050 GBC          85 :                 Assert(pronargs >= procform->pronargs);
  668 tgl                      1051 CBC          85 :                 proargtypes = (Oid *) ARR_DATA_PTR(arr);
  668 tgl                      1052 ECB             :             }
                               1053                 :         }
                               1054                 : 
 4931 tgl                      1055 GIC      856839 :         if (argnames != NIL)
 4931 tgl                      1056 ECB             :         {
                               1057                 :             /*
                               1058                 :              * Call uses named or mixed notation
                               1059                 :              *
                               1060                 :              * Named or mixed notation can match a variadic function only if
                               1061                 :              * expand_variadic is off; otherwise there is no way to match the
                               1062                 :              * presumed-nameless parameters expanded from the variadic array.
                               1063                 :              */
 4931 tgl                      1064 GIC        8782 :             if (OidIsValid(procform->provariadic) && expand_variadic)
 4931 tgl                      1065 LBC           0 :                 continue;
 4931 tgl                      1066 GBC        8782 :             va_elem_type = InvalidOid;
 4931 tgl                      1067 CBC        8782 :             variadic = false;
 4931 tgl                      1068 ECB             : 
                               1069                 :             /*
                               1070                 :              * Check argument count.
                               1071                 :              */
 4790 bruce                    1072 GIC        8782 :             Assert(nargs >= 0); /* -1 not supported with argnames */
 4931 tgl                      1073 ECB             : 
 4931 tgl                      1074 GIC        8782 :             if (pronargs > nargs && expand_defaults)
 4931 tgl                      1075 ECB             :             {
                               1076                 :                 /* Ignore if not enough default expressions */
 4931 tgl                      1077 GIC        2786 :                 if (nargs + procform->pronargdefaults < pronargs)
 4931 tgl                      1078 LBC           0 :                     continue;
 4931 tgl                      1079 GBC        2786 :                 use_defaults = true;
 4931 tgl                      1080 ECB             :             }
                               1081                 :             else
 4931 tgl                      1082 GIC        5996 :                 use_defaults = false;
 4931 tgl                      1083 ECB             : 
                               1084                 :             /* Ignore if it doesn't match requested argument count */
 4931 tgl                      1085 GIC        8782 :             if (pronargs != nargs && !use_defaults)
 4931 tgl                      1086 CBC        2842 :                 continue;
 4931 tgl                      1087 ECB             : 
                               1088                 :             /* Check for argument name match, generate positional mapping */
 4931 tgl                      1089 GIC        5940 :             if (!MatchNamedCall(proctup, nargs, argnames,
  668 tgl                      1090 ECB             :                                 include_out_arguments, pronargs,
                               1091                 :                                 &argnumbers))
 4931 tgl                      1092 GIC           9 :                 continue;
 4931 tgl                      1093 ECB             : 
                               1094                 :             /* Named argument matching is always "special" */
 4931 tgl                      1095 GIC        5931 :             any_special = true;
 4931 tgl                      1096 ECB             :         }
                               1097                 :         else
                               1098                 :         {
                               1099                 :             /*
                               1100                 :              * Call uses positional notation
                               1101                 :              *
                               1102                 :              * Check if function is variadic, and get variadic element type if
                               1103                 :              * so.  If expand_variadic is false, we should just ignore
                               1104                 :              * variadic-ness.
                               1105                 :              */
 4931 tgl                      1106 GIC      848057 :             if (pronargs <= nargs && expand_variadic)
 4931 tgl                      1107 ECB             :             {
 4931 tgl                      1108 GIC      573635 :                 va_elem_type = procform->provariadic;
 4931 tgl                      1109 CBC      573635 :                 variadic = OidIsValid(va_elem_type);
                               1110          573635 :                 any_special |= variadic;
 4931 tgl                      1111 ECB             :             }
                               1112                 :             else
                               1113                 :             {
 4931 tgl                      1114 GIC      274422 :                 va_elem_type = InvalidOid;
 4931 tgl                      1115 CBC      274422 :                 variadic = false;
 4931 tgl                      1116 ECB             :             }
                               1117                 : 
                               1118                 :             /*
                               1119                 :              * Check if function can match by using parameter defaults.
                               1120                 :              */
 4931 tgl                      1121 GIC      848057 :             if (pronargs > nargs && expand_defaults)
 4931 tgl                      1122 ECB             :             {
                               1123                 :                 /* Ignore if not enough default expressions */
 4931 tgl                      1124 GIC      197430 :                 if (nargs + procform->pronargdefaults < pronargs)
 4931 tgl                      1125 CBC      195510 :                     continue;
                               1126            1920 :                 use_defaults = true;
                               1127            1920 :                 any_special = true;
 4931 tgl                      1128 ECB             :             }
                               1129                 :             else
 4931 tgl                      1130 GIC      650627 :                 use_defaults = false;
 4931 tgl                      1131 ECB             : 
                               1132                 :             /* Ignore if it doesn't match requested argument count */
 4931 tgl                      1133 GIC      652547 :             if (nargs >= 0 && pronargs != nargs && !variadic && !use_defaults)
 4931 tgl                      1134 CBC       48218 :                 continue;
 4931 tgl                      1135 ECB             :         }
                               1136                 : 
                               1137                 :         /*
                               1138                 :          * We must compute the effective argument list so that we can easily
                               1139                 :          * compare it to earlier results.  We waste a palloc cycle if it gets
                               1140                 :          * masked by an earlier result, but really that's a pretty infrequent
                               1141                 :          * case so it's not worth worrying about.
                               1142                 :          */
 5380 tgl                      1143 GIC      610260 :         effective_nargs = Max(pronargs, nargs);
 5380 tgl                      1144 ECB             :         newResult = (FuncCandidateList)
 2970 tgl                      1145 GIC      610260 :             palloc(offsetof(struct _FuncCandidateList, args) +
 2970 tgl                      1146 ECB             :                    effective_nargs * sizeof(Oid));
 5380 tgl                      1147 GIC      610260 :         newResult->pathpos = pathpos;
 1601 andres                   1148 CBC      610260 :         newResult->oid = procform->oid;
  668 tgl                      1149          610260 :         newResult->nominalnargs = pronargs;
 5380                          1150          610260 :         newResult->nargs = effective_nargs;
 4931                          1151          610260 :         newResult->argnumbers = argnumbers;
                               1152          610260 :         if (argnumbers)
 4931 tgl                      1153 ECB             :         {
                               1154                 :             /* Re-order the argument types into call's logical order */
  186 drowley                  1155 GNC       29415 :             for (int j = 0; j < pronargs; j++)
                               1156           23484 :                 newResult->args[j] = proargtypes[argnumbers[j]];
                               1157                 :         }
                               1158                 :         else
                               1159                 :         {
 4931 tgl                      1160 ECB             :             /* Simple positional case, just copy proargtypes as-is */
  668 tgl                      1161 GIC      604329 :             memcpy(newResult->args, proargtypes, pronargs * sizeof(Oid));
 4931 tgl                      1162 ECB             :         }
 5380 tgl                      1163 GIC      610260 :         if (variadic)
 5380 tgl                      1164 ECB             :         {
 5380 tgl                      1165 CBC        3255 :             newResult->nvargs = effective_nargs - pronargs + 1;
                               1166                 :             /* Expand variadic argument into N copies of element type */
  186 drowley                  1167 GNC        9018 :             for (int j = pronargs - 1; j < effective_nargs; j++)
                               1168            5763 :                 newResult->args[j] = va_elem_type;
 5380 tgl                      1169 ECB             :         }
                               1170                 :         else
 5380 tgl                      1171 GIC      607005 :             newResult->nvargs = 0;
 5225                          1172          610260 :         newResult->ndargs = use_defaults ? pronargs - nargs : 0;
                               1173                 : 
                               1174                 :         /*
                               1175                 :          * Does it have the same arguments as something we already accepted?
                               1176                 :          * If so, decide what to do to avoid returning duplicate argument
                               1177                 :          * lists.  We can skip this check for the single-namespace case if no
                               1178                 :          * special (named, variadic or defaults) match has been made, since
 4931 tgl                      1179 ECB             :          * then the unique index on pg_proc guarantees all the matches have
                               1180                 :          * different argument lists.
                               1181                 :          */
 5225 tgl                      1182 GIC      610260 :         if (resultList != NULL &&
                               1183          236192 :             (any_special || !OidIsValid(namespaceId)))
                               1184                 :         {
                               1185                 :             /*
                               1186                 :              * If we have an ordered list from SearchSysCacheList (the normal
                               1187                 :              * case), then any conflicting proc must immediately adjoin this
                               1188                 :              * one in the list, so we only need to look at the newest result
                               1189                 :              * item.  If we have an unordered list, we have to scan the whole
                               1190                 :              * result list.  Also, if either the current candidate or any
                               1191                 :              * previous candidate is a special match, we can't assume that
                               1192                 :              * conflicts are adjacent.
                               1193                 :              *
                               1194                 :              * We ignore defaulted arguments in deciding what is a match.
 7673 tgl                      1195 ECB             :              */
                               1196                 :             FuncCandidateList prevResult;
                               1197                 : 
 5225 tgl                      1198 CBC      181007 :             if (catlist->ordered && !any_special)
 7673 tgl                      1199 ECB             :             {
 5225                          1200                 :                 /* ndargs must be 0 if !any_special */
 5225 tgl                      1201 GIC      180317 :                 if (effective_nargs == resultList->nargs &&
 5225 tgl                      1202 CBC      180314 :                     memcmp(newResult->args,
 5225 tgl                      1203 GIC      180314 :                            resultList->args,
 5225 tgl                      1204 ECB             :                            effective_nargs * sizeof(Oid)) == 0)
 5225 tgl                      1205 GIC           4 :                     prevResult = resultList;
                               1206                 :                 else
                               1207          180313 :                     prevResult = NULL;
 5225 tgl                      1208 ECB             :             }
                               1209                 :             else
                               1210                 :             {
 5050 bruce                    1211 CBC         690 :                 int         cmp_nargs = newResult->nargs - newResult->ndargs;
 7673 tgl                      1212 ECB             : 
 5225 tgl                      1213 GIC         690 :                 for (prevResult = resultList;
 5225 tgl                      1214 CBC         708 :                      prevResult;
                               1215              18 :                      prevResult = prevResult->next)
 7673 tgl                      1216 ECB             :                 {
 5225 tgl                      1217 GIC         690 :                     if (cmp_nargs == prevResult->nargs - prevResult->ndargs &&
 5380 tgl                      1218 CBC         690 :                         memcmp(newResult->args,
 5225 tgl                      1219 GIC         690 :                                prevResult->args,
                               1220                 :                                cmp_nargs * sizeof(Oid)) == 0)
                               1221             672 :                         break;
 7673 tgl                      1222 ECB             :                 }
                               1223                 :             }
                               1224                 : 
 5225 tgl                      1225 GIC      181007 :             if (prevResult)
                               1226                 :             {
                               1227                 :                 /*
                               1228                 :                  * We have a match with a previous result.  Decide which one
                               1229                 :                  * to keep, or mark it ambiguous if we can't decide.  The
                               1230                 :                  * logic here is preference > 0 means prefer the old result,
                               1231                 :                  * preference < 0 means prefer the new, preference = 0 means
                               1232                 :                  * ambiguous.
 5225 tgl                      1233 ECB             :                  */
                               1234                 :                 int         preference;
                               1235                 : 
 5225 tgl                      1236 GIC         676 :                 if (pathpos != prevResult->pathpos)
                               1237                 :                 {
 5225 tgl                      1238 ECB             :                     /*
                               1239                 :                      * Prefer the one that's earlier in the search path.
                               1240                 :                      */
 5225 tgl                      1241 GIC           1 :                     preference = pathpos - prevResult->pathpos;
                               1242                 :                 }
                               1243             675 :                 else if (variadic && prevResult->nvargs == 0)
                               1244                 :                 {
                               1245                 :                     /*
                               1246                 :                      * With variadic functions we could have, for example,
                               1247                 :                      * both foo(numeric) and foo(variadic numeric[]) in the
 5050 bruce                    1248 ECB             :                      * same namespace; if so we prefer the non-variadic match
                               1249                 :                      * on efficiency grounds.
 5380 tgl                      1250                 :                      */
 5225 tgl                      1251 GIC         615 :                     preference = 1;
 5225 tgl                      1252 ECB             :                 }
 5225 tgl                      1253 GIC          60 :                 else if (!variadic && prevResult->nvargs > 0)
                               1254                 :                 {
                               1255              39 :                     preference = -1;
                               1256                 :                 }
                               1257                 :                 else
                               1258                 :                 {
                               1259                 :                     /*----------
                               1260                 :                      * We can't decide.  This can happen with, for example,
                               1261                 :                      * both foo(numeric, variadic numeric[]) and
                               1262                 :                      * foo(variadic numeric[]) in the same namespace, or
                               1263                 :                      * both foo(int) and foo (int, int default something)
                               1264                 :                      * in the same namespace, or both foo(a int, b text)
 4931 tgl                      1265 ECB             :                      * and foo(b text, a int) in the same namespace.
                               1266                 :                      *----------
                               1267                 :                      */
 5225 tgl                      1268 CBC          21 :                     preference = 0;
                               1269                 :                 }
                               1270                 : 
                               1271             676 :                 if (preference > 0)
 5225 tgl                      1272 ECB             :                 {
                               1273                 :                     /* keep previous result */
 5225 tgl                      1274 CBC         616 :                     pfree(newResult);
 5225 tgl                      1275 GIC         616 :                     continue;
                               1276                 :                 }
 5225 tgl                      1277 CBC          60 :                 else if (preference < 0)
 5225 tgl                      1278 ECB             :                 {
                               1279                 :                     /* remove previous result from the list */
 5225 tgl                      1280 GIC          39 :                     if (prevResult == resultList)
                               1281              39 :                         resultList = prevResult->next;
                               1282                 :                     else
 5380 tgl                      1283 EUB             :                     {
 5225                          1284                 :                         FuncCandidateList prevPrevResult;
 5239 peter_e                  1285                 : 
 5225 tgl                      1286 UIC           0 :                         for (prevPrevResult = resultList;
 5225 tgl                      1287 UBC           0 :                              prevPrevResult;
 5225 tgl                      1288 UIC           0 :                              prevPrevResult = prevPrevResult->next)
 5239 peter_e                  1289 EUB             :                         {
 5225 tgl                      1290 UBC           0 :                             if (prevResult == prevPrevResult->next)
                               1291                 :                             {
 5225 tgl                      1292 UIC           0 :                                 prevPrevResult->next = prevResult->next;
 5225 tgl                      1293 UBC           0 :                                 break;
                               1294                 :                             }
 5239 peter_e                  1295 ECB             :                         }
 5050 bruce                    1296 UIC           0 :                         Assert(prevPrevResult); /* assert we found it */
                               1297                 :                     }
 5225 tgl                      1298 GIC          39 :                     pfree(prevResult);
                               1299                 :                     /* fall through to add newResult to list */
                               1300                 :                 }
 5225 tgl                      1301 ECB             :                 else
                               1302                 :                 {
                               1303                 :                     /* mark old result as ambiguous, discard new */
 5225 tgl                      1304 GIC          21 :                     prevResult->oid = InvalidOid;
 5380                          1305              21 :                     pfree(newResult);
 5225                          1306              21 :                     continue;
                               1307                 :                 }
                               1308                 :             }
                               1309                 :         }
                               1310                 : 
 7673 tgl                      1311 ECB             :         /*
                               1312                 :          * Okay to add it to result list
                               1313                 :          */
 7673 tgl                      1314 GIC      609623 :         newResult->next = resultList;
 7673 tgl                      1315 CBC      609623 :         resultList = newResult;
                               1316                 :     }
 7673 tgl                      1317 ECB             : 
 7673 tgl                      1318 GIC      376150 :     ReleaseSysCacheList(catlist);
                               1319                 : 
 7663                          1320          376150 :     return resultList;
                               1321                 : }
                               1322                 : 
                               1323                 : /*
                               1324                 :  * MatchNamedCall
                               1325                 :  *      Given a pg_proc heap tuple and a call's list of argument names,
                               1326                 :  *      check whether the function could match the call.
                               1327                 :  *
                               1328                 :  * The call could match if all supplied argument names are accepted by
                               1329                 :  * the function, in positions after the last positional argument, and there
                               1330                 :  * are defaults for all unsupplied arguments.
                               1331                 :  *
                               1332                 :  * If include_out_arguments is true, we are treating OUT arguments as
                               1333                 :  * included in the argument list.  pronargs is the number of arguments
                               1334                 :  * we're considering (the length of either proargtypes or proallargtypes).
                               1335                 :  *
                               1336                 :  * The number of positional arguments is nargs - list_length(argnames).
                               1337                 :  * Note caller has already done basic checks on argument count.
                               1338                 :  *
                               1339                 :  * On match, return true and fill *argnumbers with a palloc'd array showing
                               1340                 :  * the mapping from call argument positions to actual function argument
                               1341                 :  * numbers.  Defaulted arguments are included in this map, at positions
 4931 tgl                      1342 ECB             :  * after the last supplied argument.
                               1343                 :  */
                               1344                 : static bool
 4931 tgl                      1345 GIC        5940 : MatchNamedCall(HeapTuple proctup, int nargs, List *argnames,
  668 tgl                      1346 ECB             :                bool include_out_arguments, int pronargs,
 4931                          1347                 :                int **argnumbers)
                               1348                 : {
 4931 tgl                      1349 GIC        5940 :     Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup);
                               1350            5940 :     int         numposargs = nargs - list_length(argnames);
                               1351                 :     int         pronallargs;
                               1352                 :     Oid        *p_argtypes;
                               1353                 :     char      **p_argnames;
                               1354                 :     char       *p_argmodes;
                               1355                 :     bool        arggiven[FUNC_MAX_ARGS];
                               1356                 :     bool        isnull;
                               1357                 :     int         ap;             /* call args position */
 4931 tgl                      1358 ECB             :     int         pp;             /* proargs position */
                               1359                 :     ListCell   *lc;
                               1360                 : 
 4931 tgl                      1361 GIC        5940 :     Assert(argnames != NIL);
                               1362            5940 :     Assert(numposargs >= 0);
 4931 tgl                      1363 CBC        5940 :     Assert(nargs <= pronargs);
                               1364                 : 
 4931 tgl                      1365 ECB             :     /* Ignore this function if its proargnames is null */
 4931 tgl                      1366 GBC        5940 :     (void) SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_proargnames,
                               1367                 :                            &isnull);
 4931 tgl                      1368 GIC        5940 :     if (isnull)
 4931 tgl                      1369 LBC           0 :         return false;
                               1370                 : 
 4931 tgl                      1371 ECB             :     /* OK, let's extract the argument names and types */
 4931 tgl                      1372 GIC        5940 :     pronallargs = get_func_arg_info(proctup,
 4931 tgl                      1373 ECB             :                                     &p_argtypes, &p_argnames, &p_argmodes);
 4931 tgl                      1374 GIC        5940 :     Assert(p_argnames != NULL);
                               1375                 : 
  668 tgl                      1376 CBC        5940 :     Assert(include_out_arguments ? (pronargs == pronallargs) : (pronargs <= pronallargs));
  668 tgl                      1377 ECB             : 
                               1378                 :     /* initialize state for matching */
 4931 tgl                      1379 GIC        5940 :     *argnumbers = (int *) palloc(pronargs * sizeof(int));
 4931 tgl                      1380 CBC        5940 :     memset(arggiven, false, pronargs * sizeof(bool));
                               1381                 : 
 4931 tgl                      1382 ECB             :     /* there are numposargs positional args before the named args */
 4931 tgl                      1383 CBC        6688 :     for (ap = 0; ap < numposargs; ap++)
                               1384                 :     {
 4931 tgl                      1385 GIC         748 :         (*argnumbers)[ap] = ap;
                               1386             748 :         arggiven[ap] = true;
 4931 tgl                      1387 ECB             :     }
                               1388                 : 
                               1389                 :     /* now examine the named args */
 4931 tgl                      1390 GIC       23233 :     foreach(lc, argnames)
                               1391                 :     {
 4790 bruce                    1392           17299 :         char       *argname = (char *) lfirst(lc);
 4790 bruce                    1393 ECB             :         bool        found;
                               1394                 :         int         i;
 4931 tgl                      1395                 : 
 4931 tgl                      1396 GIC       17299 :         pp = 0;
                               1397           17299 :         found = false;
 4931 tgl                      1398 CBC       39795 :         for (i = 0; i < pronallargs; i++)
 4931 tgl                      1399 ECB             :         {
  668                          1400                 :             /* consider only input params, except with include_out_arguments */
  668 tgl                      1401 CBC       39792 :             if (!include_out_arguments &&
                               1402           29667 :                 p_argmodes &&
 4931                          1403           29667 :                 (p_argmodes[i] != FUNC_PARAM_IN &&
                               1404              24 :                  p_argmodes[i] != FUNC_PARAM_INOUT &&
 4931 tgl                      1405 GIC          24 :                  p_argmodes[i] != FUNC_PARAM_VARIADIC))
                               1406              24 :                 continue;
 4931 tgl                      1407 CBC       39768 :             if (p_argnames[i] && strcmp(p_argnames[i], argname) == 0)
 4931 tgl                      1408 ECB             :             {
                               1409                 :                 /* fail if argname matches a positional argument */
 4931 tgl                      1410 CBC       17296 :                 if (arggiven[pp])
                               1411               6 :                     return false;
                               1412           17293 :                 arggiven[pp] = true;
 4931 tgl                      1413 GIC       17293 :                 (*argnumbers)[ap] = pp;
                               1414           17293 :                 found = true;
 4931 tgl                      1415 CBC       17293 :                 break;
                               1416                 :             }
                               1417                 :             /* increase pp only for considered parameters */
                               1418           22472 :             pp++;
 4931 tgl                      1419 ECB             :         }
                               1420                 :         /* if name isn't in proargnames, fail */
 4931 tgl                      1421 GIC       17296 :         if (!found)
                               1422               3 :             return false;
 4931 tgl                      1423 CBC       17293 :         ap++;
                               1424                 :     }
                               1425                 : 
                               1426            5934 :     Assert(ap == nargs);        /* processed all actual parameters */
                               1427                 : 
 4931 tgl                      1428 ECB             :     /* Check for default arguments */
 4931 tgl                      1429 GIC        5934 :     if (nargs < pronargs)
 4931 tgl                      1430 ECB             :     {
 4790 bruce                    1431 GIC        2780 :         int         first_arg_with_default = pronargs - procform->pronargdefaults;
 4931 tgl                      1432 ECB             : 
 4931 tgl                      1433 CBC       18470 :         for (pp = numposargs; pp < pronargs; pp++)
                               1434                 :         {
                               1435           15693 :             if (arggiven[pp])
                               1436           10232 :                 continue;
 4931 tgl                      1437 ECB             :             /* fail if arg not given and no default available */
 4931 tgl                      1438 GIC        5461 :             if (pp < first_arg_with_default)
                               1439               3 :                 return false;
                               1440            5458 :             (*argnumbers)[ap++] = pp;
 4931 tgl                      1441 ECB             :         }
                               1442                 :     }
                               1443                 : 
 4931 tgl                      1444 GIC        5931 :     Assert(ap == pronargs);     /* processed all function parameters */
                               1445                 : 
                               1446            5931 :     return true;
                               1447                 : }
                               1448                 : 
                               1449                 : /*
                               1450                 :  * FunctionIsVisible
                               1451                 :  *      Determine whether a function (identified by OID) is visible in the
                               1452                 :  *      current search path.  Visible means "would be found by searching
 7648 tgl                      1453 ECB             :  *      for the unqualified function name with exact argument matches".
                               1454                 :  */
                               1455                 : bool
 7648 tgl                      1456 GIC       10279 : FunctionIsVisible(Oid funcid)
                               1457                 : {
                               1458                 :     HeapTuple   proctup;
                               1459                 :     Form_pg_proc procform;
 7648 tgl                      1460 ECB             :     Oid         pronamespace;
                               1461                 :     bool        visible;
 7648 tgl                      1462 EUB             : 
 4802 rhaas                    1463 CBC       10279 :     proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
 7648 tgl                      1464 GIC       10279 :     if (!HeapTupleIsValid(proctup))
 7202 tgl                      1465 LBC           0 :         elog(ERROR, "cache lookup failed for function %u", funcid);
 7648 tgl                      1466 GIC       10279 :     procform = (Form_pg_proc) GETSTRUCT(proctup);
                               1467                 : 
 7632                          1468           10279 :     recomputeNamespacePath();
                               1469                 : 
                               1470                 :     /*
                               1471                 :      * Quick check: if it ain't in the path at all, it ain't visible. Items in
 6385 bruce                    1472 ECB             :      * the system namespace are surely in the path and so we needn't even do
                               1473                 :      * list_member_oid() for them.
 7648 tgl                      1474                 :      */
 7648 tgl                      1475 CBC       10279 :     pronamespace = procform->pronamespace;
 7648 tgl                      1476 GIC       10279 :     if (pronamespace != PG_CATALOG_NAMESPACE &&
 5861                          1477            5233 :         !list_member_oid(activeSearchPath, pronamespace))
 7648                          1478             297 :         visible = false;
                               1479                 :     else
                               1480                 :     {
                               1481                 :         /*
                               1482                 :          * If it is in the path, it might still not be visible; it could be
                               1483                 :          * hidden by another proc of the same name and arguments earlier in
 6385 bruce                    1484 ECB             :          * the path.  So we must do a slow check to see if this is the same
                               1485                 :          * proc that would be found by FuncnameGetCandidates.
                               1486                 :          */
 7648 tgl                      1487 GIC        9982 :         char       *proname = NameStr(procform->proname);
 7648 tgl                      1488 CBC        9982 :         int         nargs = procform->pronargs;
                               1489                 :         FuncCandidateList clist;
 7648 tgl                      1490 ECB             : 
 7648 tgl                      1491 GIC        9982 :         visible = false;
                               1492                 : 
 5380 tgl                      1493 CBC        9982 :         clist = FuncnameGetCandidates(list_make1(makeString(proname)),
                               1494                 :                                       nargs, NIL, false, false, false, false);
 7648 tgl                      1495 ECB             : 
 7648 tgl                      1496 GIC       14384 :         for (; clist; clist = clist->next)
                               1497                 :         {
 6585                          1498           14378 :             if (memcmp(clist->args, procform->proargtypes.values,
 7648 tgl                      1499 ECB             :                        nargs * sizeof(Oid)) == 0)
                               1500                 :             {
                               1501                 :                 /* Found the expected entry; is it the right proc? */
 7648 tgl                      1502 GIC        9976 :                 visible = (clist->oid == funcid);
                               1503            9976 :                 break;
                               1504                 :             }
 7648 tgl                      1505 ECB             :         }
                               1506                 :     }
                               1507                 : 
 7648 tgl                      1508 GIC       10279 :     ReleaseSysCache(proctup);
                               1509                 : 
                               1510           10279 :     return visible;
                               1511                 : }
                               1512                 : 
                               1513                 : 
                               1514                 : /*
                               1515                 :  * OpernameGetOprid
                               1516                 :  *      Given a possibly-qualified operator name and exact input datatypes,
                               1517                 :  *      look up the operator.  Returns InvalidOid if not found.
                               1518                 :  *
                               1519                 :  * Pass oprleft = InvalidOid for a prefix op.
                               1520                 :  *
                               1521                 :  * If the operator name is not schema-qualified, it is sought in the current
                               1522                 :  * namespace search path.  If the name is schema-qualified and the given
 3363 alvherre                 1523 ECB             :  * schema does not exist, InvalidOid is returned.
                               1524                 :  */
                               1525                 : Oid
 6187 tgl                      1526 GIC       59253 : OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
                               1527                 : {
                               1528                 :     char       *schemaname;
                               1529                 :     char       *opername;
                               1530                 :     CatCList   *catlist;
 6187 tgl                      1531 ECB             :     ListCell   *l;
                               1532                 : 
                               1533                 :     /* deconstruct the name list */
 6187 tgl                      1534 GIC       59253 :     DeconstructQualifiedName(names, &schemaname, &opername);
                               1535                 : 
                               1536           59253 :     if (schemaname)
                               1537                 :     {
 6187 tgl                      1538 ECB             :         /* search only in exact schema given */
                               1539                 :         Oid         namespaceId;
                               1540                 : 
 3363 alvherre                 1541 GIC         992 :         namespaceId = LookupExplicitNamespace(schemaname, true);
                               1542             992 :         if (OidIsValid(namespaceId))
 6187 tgl                      1543 ECB             :         {
                               1544                 :             HeapTuple   opertup;
                               1545                 : 
 3363 alvherre                 1546 GIC         980 :             opertup = SearchSysCache4(OPERNAMENSP,
                               1547                 :                                       CStringGetDatum(opername),
 3363 alvherre                 1548 ECB             :                                       ObjectIdGetDatum(oprleft),
                               1549                 :                                       ObjectIdGetDatum(oprright),
                               1550                 :                                       ObjectIdGetDatum(namespaceId));
 3363 alvherre                 1551 CBC         980 :             if (HeapTupleIsValid(opertup))
                               1552                 :             {
 1601 andres                   1553             570 :                 Form_pg_operator operclass = (Form_pg_operator) GETSTRUCT(opertup);
                               1554             570 :                 Oid         result = operclass->oid;
                               1555                 : 
 3363 alvherre                 1556 GIC         570 :                 ReleaseSysCache(opertup);
                               1557             570 :                 return result;
 3363 alvherre                 1558 ECB             :             }
                               1559                 :         }
                               1560                 : 
 6187 tgl                      1561 GIC         422 :         return InvalidOid;
 6187 tgl                      1562 ECB             :     }
                               1563                 : 
                               1564                 :     /* Search syscache by name and argument types */
 4802 rhaas                    1565 GIC       58261 :     catlist = SearchSysCacheList3(OPERNAMENSP,
                               1566                 :                                   CStringGetDatum(opername),
 4802 rhaas                    1567 ECB             :                                   ObjectIdGetDatum(oprleft),
                               1568                 :                                   ObjectIdGetDatum(oprright));
                               1569                 : 
 6187 tgl                      1570 CBC       58261 :     if (catlist->n_members == 0)
 6187 tgl                      1571 ECB             :     {
                               1572                 :         /* no hope, fall out early */
 6187 tgl                      1573 GIC       14408 :         ReleaseSysCacheList(catlist);
                               1574           14408 :         return InvalidOid;
                               1575                 :     }
                               1576                 : 
                               1577                 :     /*
                               1578                 :      * We have to find the list member that is first in the search path, if
 6031 bruce                    1579 ECB             :      * there's more than one.  This doubly-nested loop looks ugly, but in
                               1580                 :      * practice there should usually be few catlist members.
 6187 tgl                      1581                 :      */
 6187 tgl                      1582 GIC       43853 :     recomputeNamespacePath();
 6187 tgl                      1583 ECB             : 
 5861 tgl                      1584 GIC       49171 :     foreach(l, activeSearchPath)
                               1585                 :     {
 6187 tgl                      1586 CBC       49166 :         Oid         namespaceId = lfirst_oid(l);
 6187 tgl                      1587 ECB             :         int         i;
                               1588                 : 
 5833 tgl                      1589 CBC       49166 :         if (namespaceId == myTempNamespace)
 5833 tgl                      1590 GIC        3306 :             continue;           /* do not look in temp namespace */
 5833 tgl                      1591 ECB             : 
 6187 tgl                      1592 CBC       47890 :         for (i = 0; i < catlist->n_members; i++)
                               1593                 :         {
                               1594           45878 :             HeapTuple   opertup = &catlist->members[i]->tuple;
 6187 tgl                      1595 GIC       45878 :             Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
 6187 tgl                      1596 ECB             : 
 6187 tgl                      1597 GIC       45878 :             if (operform->oprnamespace == namespaceId)
 6187 tgl                      1598 ECB             :             {
 1601 andres                   1599 CBC       43848 :                 Oid         result = operform->oid;
                               1600                 : 
 6187 tgl                      1601 GIC       43848 :                 ReleaseSysCacheList(catlist);
                               1602           43848 :                 return result;
                               1603                 :             }
 6187 tgl                      1604 ECB             :         }
                               1605                 :     }
                               1606                 : 
 6187 tgl                      1607 GIC           5 :     ReleaseSysCacheList(catlist);
                               1608               5 :     return InvalidOid;
                               1609                 : }
                               1610                 : 
                               1611                 : /*
                               1612                 :  * OpernameGetCandidates
                               1613                 :  *      Given a possibly-qualified operator name and operator kind,
                               1614                 :  *      retrieve a list of the possible matches.
                               1615                 :  *
                               1616                 :  * If oprkind is '\0', we return all operators matching the given name,
                               1617                 :  * regardless of arguments.
                               1618                 :  *
                               1619                 :  * We search a single namespace if the operator name is qualified, else
                               1620                 :  * all namespaces in the search path.  The return list will never contain
                               1621                 :  * multiple entries with identical argument lists --- in the multiple-
                               1622                 :  * namespace case, we arrange for entries in earlier namespaces to mask
                               1623                 :  * identical entries in later namespaces.
                               1624                 :  *
                               1625                 :  * The returned items always have two args[] entries --- the first will be
  934 tgl                      1626 ECB             :  * InvalidOid for a prefix oprkind.  nargs is always 2, too.
                               1627                 :  */
 7663                          1628                 : FuncCandidateList
 3288 rhaas                    1629 CBC       13811 : OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok)
 7663 tgl                      1630 ECB             : {
 7663 tgl                      1631 GIC       13811 :     FuncCandidateList resultList = NULL;
 7041                          1632           13811 :     char       *resultSpace = NULL;
                               1633           13811 :     int         nextResult = 0;
                               1634                 :     char       *schemaname;
                               1635                 :     char       *opername;
                               1636                 :     Oid         namespaceId;
                               1637                 :     CatCList   *catlist;
 7663 tgl                      1638 ECB             :     int         i;
                               1639                 : 
                               1640                 :     /* deconstruct the name list */
 7559 tgl                      1641 GIC       13811 :     DeconstructQualifiedName(names, &schemaname, &opername);
                               1642                 : 
 7663 tgl                      1643 CBC       13811 :     if (schemaname)
 7663 tgl                      1644 ECB             :     {
                               1645                 :         /* use exact schema given */
 3288 rhaas                    1646 GIC         420 :         namespaceId = LookupExplicitNamespace(schemaname, missing_schema_ok);
                               1647             420 :         if (missing_schema_ok && !OidIsValid(namespaceId))
                               1648               9 :             return NULL;
                               1649                 :     }
 7663 tgl                      1650 ECB             :     else
                               1651                 :     {
                               1652                 :         /* flag to indicate we need namespace search */
 7663 tgl                      1653 GIC       13391 :         namespaceId = InvalidOid;
 7650                          1654           13391 :         recomputeNamespacePath();
 7663 tgl                      1655 ECB             :     }
                               1656                 : 
                               1657                 :     /* Search syscache by name only */
 4802 rhaas                    1658 GIC       13802 :     catlist = SearchSysCacheList1(OPERNAMENSP, CStringGetDatum(opername));
                               1659                 : 
                               1660                 :     /*
                               1661                 :      * In typical scenarios, most if not all of the operators found by the
                               1662                 :      * catcache search will end up getting returned; and there can be quite a
                               1663                 :      * few, for common operator names such as '=' or '+'.  To reduce the time
                               1664                 :      * spent in palloc, we allocate the result space as an array large enough
                               1665                 :      * to hold all the operators.  The original coding of this routine did a
                               1666                 :      * separate palloc for each operator, but profiling revealed that the
                               1667                 :      * pallocs used an unreasonably large fraction of parsing time.
                               1668                 :      */
 2970 tgl                      1669 ECB             : #define SPACE_PER_OP MAXALIGN(offsetof(struct _FuncCandidateList, args) + \
                               1670                 :                               2 * sizeof(Oid))
                               1671                 : 
 7041 tgl                      1672 CBC       13802 :     if (catlist->n_members > 0)
 7041 tgl                      1673 GIC       13796 :         resultSpace = palloc(catlist->n_members * SPACE_PER_OP);
 7041 tgl                      1674 ECB             : 
 7663 tgl                      1675 CBC      647194 :     for (i = 0; i < catlist->n_members; i++)
 7663 tgl                      1676 ECB             :     {
 7663 tgl                      1677 GIC      633392 :         HeapTuple   opertup = &catlist->members[i]->tuple;
                               1678          633392 :         Form_pg_operator operform = (Form_pg_operator) GETSTRUCT(opertup);
                               1679          633392 :         int         pathpos = 0;
 7663 tgl                      1680 ECB             :         FuncCandidateList newResult;
                               1681                 : 
                               1682                 :         /* Ignore operators of wrong kind, if specific kind requested */
 7654 tgl                      1683 CBC      633392 :         if (oprkind && operform->oprkind != oprkind)
 7663 tgl                      1684 GIC        5870 :             continue;
                               1685                 : 
 7663 tgl                      1686 CBC      627522 :         if (OidIsValid(namespaceId))
 7663 tgl                      1687 EUB             :         {
                               1688                 :             /* Consider only opers in specified namespace */
 7663 tgl                      1689 GIC        5771 :             if (operform->oprnamespace != namespaceId)
 7663 tgl                      1690 UIC           0 :                 continue;
                               1691                 :             /* No need to check args, they must all be different */
                               1692                 :         }
                               1693                 :         else
                               1694                 :         {
                               1695                 :             /*
                               1696                 :              * Consider only opers that are in the search path and are not in
                               1697                 :              * the temp namespace.
 5833 tgl                      1698 ECB             :              */
                               1699                 :             ListCell   *nsp;
 7663                          1700                 : 
 5861 tgl                      1701 CBC      660549 :             foreach(nsp, activeSearchPath)
 7632 tgl                      1702 ECB             :             {
 5833 tgl                      1703 CBC      660287 :                 if (operform->oprnamespace == lfirst_oid(nsp) &&
 5833 tgl                      1704 GIC      621489 :                     operform->oprnamespace != myTempNamespace)
 7632 tgl                      1705 CBC      621489 :                     break;
                               1706           38798 :                 pathpos++;
                               1707                 :             }
 6892 neilc                    1708 GIC      621751 :             if (nsp == NULL)
 7632 tgl                      1709             262 :                 continue;       /* oper is not in search path */
                               1710                 : 
                               1711                 :             /*
                               1712                 :              * Okay, it's in the search path, but does it have the same
                               1713                 :              * arguments as something we already accepted?  If so, keep only
                               1714                 :              * the one that appears earlier in the search path.
                               1715                 :              *
                               1716                 :              * If we have an ordered list from SearchSysCacheList (the normal
                               1717                 :              * case), then any conflicting oper must immediately adjoin this
                               1718                 :              * one in the list, so we only need to look at the newest result
 6385 bruce                    1719 ECB             :              * item.  If we have an unordered list, we have to scan the whole
                               1720                 :              * result list.
                               1721                 :              */
 7663 tgl                      1722 GIC      621489 :             if (resultList)
 7663 tgl                      1723 ECB             :             {
                               1724                 :                 FuncCandidateList prevResult;
                               1725                 : 
 7663 tgl                      1726 CBC      608104 :                 if (catlist->ordered)
 7663 tgl                      1727 EUB             :                 {
 7663 tgl                      1728 GIC      608104 :                     if (operform->oprleft == resultList->args[0] &&
 7663 tgl                      1729 CBC      170353 :                         operform->oprright == resultList->args[1])
 7663 tgl                      1730 UIC           0 :                         prevResult = resultList;
                               1731                 :                     else
 7663 tgl                      1732 GIC      608104 :                         prevResult = NULL;
 7663 tgl                      1733 EUB             :                 }
                               1734                 :                 else
                               1735                 :                 {
 7663 tgl                      1736 UIC           0 :                     for (prevResult = resultList;
 7663 tgl                      1737 UBC           0 :                          prevResult;
                               1738               0 :                          prevResult = prevResult->next)
 7663 tgl                      1739 EUB             :                     {
 7663 tgl                      1740 UIC           0 :                         if (operform->oprleft == prevResult->args[0] &&
                               1741               0 :                             operform->oprright == prevResult->args[1])
 7663 tgl                      1742 LBC           0 :                             break;
                               1743                 :                     }
                               1744                 :                 }
 7663 tgl                      1745 GBC      608104 :                 if (prevResult)
 7663 tgl                      1746 EUB             :                 {
                               1747                 :                     /* We have a match with a previous result */
 7663 tgl                      1748 UIC           0 :                     Assert(pathpos != prevResult->pathpos);
 7663 tgl                      1749 UBC           0 :                     if (pathpos > prevResult->pathpos)
 2118                          1750               0 :                         continue;   /* keep previous result */
 7663 tgl                      1751 EUB             :                     /* replace previous result */
 7663 tgl                      1752 UIC           0 :                     prevResult->pathpos = pathpos;
 1601 andres                   1753               0 :                     prevResult->oid = operform->oid;
 7663 tgl                      1754               0 :                     continue;   /* args are same, of course */
                               1755                 :                 }
                               1756                 :             }
                               1757                 :         }
                               1758                 : 
 7663 tgl                      1759 ECB             :         /*
                               1760                 :          * Okay to add it to result list
                               1761                 :          */
 7041 tgl                      1762 CBC      627260 :         newResult = (FuncCandidateList) (resultSpace + nextResult);
                               1763          627260 :         nextResult += SPACE_PER_OP;
 7041 tgl                      1764 ECB             : 
 7663 tgl                      1765 CBC      627260 :         newResult->pathpos = pathpos;
 1601 andres                   1766          627260 :         newResult->oid = operform->oid;
  668 tgl                      1767          627260 :         newResult->nominalnargs = 2;
 7654                          1768          627260 :         newResult->nargs = 2;
 5380                          1769          627260 :         newResult->nvargs = 0;
 5225                          1770          627260 :         newResult->ndargs = 0;
 4931                          1771          627260 :         newResult->argnumbers = NULL;
 7663                          1772          627260 :         newResult->args[0] = operform->oprleft;
 7663 tgl                      1773 GIC      627260 :         newResult->args[1] = operform->oprright;
                               1774          627260 :         newResult->next = resultList;
 7663 tgl                      1775 CBC      627260 :         resultList = newResult;
                               1776                 :     }
 7663 tgl                      1777 ECB             : 
 7663 tgl                      1778 GIC       13802 :     ReleaseSysCacheList(catlist);
                               1779                 : 
 7673                          1780           13802 :     return resultList;
                               1781                 : }
                               1782                 : 
                               1783                 : /*
                               1784                 :  * OperatorIsVisible
                               1785                 :  *      Determine whether an operator (identified by OID) is visible in the
                               1786                 :  *      current search path.  Visible means "would be found by searching
 7648 tgl                      1787 ECB             :  *      for the unqualified operator name with exact argument matches".
                               1788                 :  */
                               1789                 : bool
 7648 tgl                      1790 GIC        2128 : OperatorIsVisible(Oid oprid)
                               1791                 : {
                               1792                 :     HeapTuple   oprtup;
                               1793                 :     Form_pg_operator oprform;
 7648 tgl                      1794 ECB             :     Oid         oprnamespace;
                               1795                 :     bool        visible;
 7648 tgl                      1796 EUB             : 
 4802 rhaas                    1797 CBC        2128 :     oprtup = SearchSysCache1(OPEROID, ObjectIdGetDatum(oprid));
 7648 tgl                      1798 GIC        2128 :     if (!HeapTupleIsValid(oprtup))
 7202 tgl                      1799 LBC           0 :         elog(ERROR, "cache lookup failed for operator %u", oprid);
 7648 tgl                      1800 GIC        2128 :     oprform = (Form_pg_operator) GETSTRUCT(oprtup);
                               1801                 : 
 7632                          1802            2128 :     recomputeNamespacePath();
                               1803                 : 
                               1804                 :     /*
                               1805                 :      * Quick check: if it ain't in the path at all, it ain't visible. Items in
 6385 bruce                    1806 ECB             :      * the system namespace are surely in the path and so we needn't even do
                               1807                 :      * list_member_oid() for them.
 7648 tgl                      1808                 :      */
 7648 tgl                      1809 CBC        2128 :     oprnamespace = oprform->oprnamespace;
 7648 tgl                      1810 GIC        2128 :     if (oprnamespace != PG_CATALOG_NAMESPACE &&
 5861                          1811             683 :         !list_member_oid(activeSearchPath, oprnamespace))
 7648                          1812             126 :         visible = false;
                               1813                 :     else
                               1814                 :     {
                               1815                 :         /*
                               1816                 :          * If it is in the path, it might still not be visible; it could be
                               1817                 :          * hidden by another operator of the same name and arguments earlier
 6385 bruce                    1818 ECB             :          * in the path.  So we must do a slow check to see if this is the same
                               1819                 :          * operator that would be found by OpernameGetOprid.
 7648 tgl                      1820                 :          */
 7648 tgl                      1821 GIC        2002 :         char       *oprname = NameStr(oprform->oprname);
                               1822                 : 
 6187                          1823            2002 :         visible = (OpernameGetOprid(list_make1(makeString(oprname)),
                               1824                 :                                     oprform->oprleft, oprform->oprright)
 6187 tgl                      1825 ECB             :                    == oprid);
                               1826                 :     }
 7648                          1827                 : 
 7648 tgl                      1828 GIC        2128 :     ReleaseSysCache(oprtup);
                               1829                 : 
                               1830            2128 :     return visible;
                               1831                 : }
                               1832                 : 
                               1833                 : 
                               1834                 : /*
                               1835                 :  * OpclassnameGetOpcid
                               1836                 :  *      Try to resolve an unqualified index opclass name.
                               1837                 :  *      Returns OID if opclass found in search path, else InvalidOid.
                               1838                 :  *
                               1839                 :  * This is essentially the same as TypenameGetTypid, but we have to have
 7648 tgl                      1840 ECB             :  * an extra argument for the index AM OID.
                               1841                 :  */
                               1842                 : Oid
 7648 tgl                      1843 GIC       63537 : OpclassnameGetOpcid(Oid amid, const char *opcname)
                               1844                 : {
 7648 tgl                      1845 ECB             :     Oid         opcid;
                               1846                 :     ListCell   *l;
                               1847                 : 
 7648 tgl                      1848 GIC       63537 :     recomputeNamespacePath();
 7648 tgl                      1849 ECB             : 
 5861 tgl                      1850 GIC       63916 :     foreach(l, activeSearchPath)
 7648 tgl                      1851 ECB             :     {
 6892 neilc                    1852 CBC       63904 :         Oid         namespaceId = lfirst_oid(l);
                               1853                 : 
 5833 tgl                      1854           63904 :         if (namespaceId == myTempNamespace)
 5833 tgl                      1855 GIC         151 :             continue;           /* do not look in temp namespace */
                               1856                 : 
 1601 andres                   1857           63753 :         opcid = GetSysCacheOid3(CLAAMNAMENSP, Anum_pg_opclass_oid,
 4802 rhaas                    1858 ECB             :                                 ObjectIdGetDatum(amid),
                               1859                 :                                 PointerGetDatum(opcname),
                               1860                 :                                 ObjectIdGetDatum(namespaceId));
 7648 tgl                      1861 GIC       63753 :         if (OidIsValid(opcid))
                               1862           63525 :             return opcid;
 7648 tgl                      1863 ECB             :     }
                               1864                 : 
                               1865                 :     /* Not found in path */
 7648 tgl                      1866 GIC          12 :     return InvalidOid;
                               1867                 : }
                               1868                 : 
                               1869                 : /*
                               1870                 :  * OpclassIsVisible
                               1871                 :  *      Determine whether an opclass (identified by OID) is visible in the
                               1872                 :  *      current search path.  Visible means "would be found by searching
 7648 tgl                      1873 ECB             :  *      for the unqualified opclass name".
                               1874                 :  */
                               1875                 : bool
 7648 tgl                      1876 GIC         350 : OpclassIsVisible(Oid opcid)
                               1877                 : {
                               1878                 :     HeapTuple   opctup;
                               1879                 :     Form_pg_opclass opcform;
 7648 tgl                      1880 ECB             :     Oid         opcnamespace;
                               1881                 :     bool        visible;
 7648 tgl                      1882 EUB             : 
 4802 rhaas                    1883 CBC         350 :     opctup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcid));
 7648 tgl                      1884 GIC         350 :     if (!HeapTupleIsValid(opctup))
 7202 tgl                      1885 LBC           0 :         elog(ERROR, "cache lookup failed for opclass %u", opcid);
 7648 tgl                      1886 GIC         350 :     opcform = (Form_pg_opclass) GETSTRUCT(opctup);
                               1887                 : 
 7632                          1888             350 :     recomputeNamespacePath();
                               1889                 : 
                               1890                 :     /*
                               1891                 :      * Quick check: if it ain't in the path at all, it ain't visible. Items in
 6385 bruce                    1892 ECB             :      * the system namespace are surely in the path and so we needn't even do
                               1893                 :      * list_member_oid() for them.
 7648 tgl                      1894                 :      */
 7648 tgl                      1895 CBC         350 :     opcnamespace = opcform->opcnamespace;
 7648 tgl                      1896 GIC         350 :     if (opcnamespace != PG_CATALOG_NAMESPACE &&
 5861                          1897              64 :         !list_member_oid(activeSearchPath, opcnamespace))
 7648                          1898              12 :         visible = false;
                               1899                 :     else
                               1900                 :     {
                               1901                 :         /*
                               1902                 :          * If it is in the path, it might still not be visible; it could be
                               1903                 :          * hidden by another opclass of the same name earlier in the path. So
 6385 bruce                    1904 ECB             :          * we must do a slow check to see if this opclass would be found by
                               1905                 :          * OpclassnameGetOpcid.
 7648 tgl                      1906                 :          */
 7648 tgl                      1907 GIC         338 :         char       *opcname = NameStr(opcform->opcname);
                               1908                 : 
 5951 tgl                      1909 CBC         338 :         visible = (OpclassnameGetOpcid(opcform->opcmethod, opcname) == opcid);
                               1910                 :     }
 7648 tgl                      1911 ECB             : 
 7648 tgl                      1912 GIC         350 :     ReleaseSysCache(opctup);
                               1913                 : 
                               1914             350 :     return visible;
                               1915                 : }
                               1916                 : 
                               1917                 : /*
                               1918                 :  * OpfamilynameGetOpfid
                               1919                 :  *      Try to resolve an unqualified index opfamily name.
                               1920                 :  *      Returns OID if opfamily found in search path, else InvalidOid.
                               1921                 :  *
                               1922                 :  * This is essentially the same as TypenameGetTypid, but we have to have
 5951 tgl                      1923 ECB             :  * an extra argument for the index AM OID.
                               1924                 :  */
                               1925                 : Oid
 5951 tgl                      1926 GIC        1115 : OpfamilynameGetOpfid(Oid amid, const char *opfname)
                               1927                 : {
 5951 tgl                      1928 ECB             :     Oid         opfid;
                               1929                 :     ListCell   *l;
                               1930                 : 
 5951 tgl                      1931 GIC        1115 :     recomputeNamespacePath();
 5951 tgl                      1932 ECB             : 
 5861 tgl                      1933 GIC        2202 :     foreach(l, activeSearchPath)
 5951 tgl                      1934 ECB             :     {
 5951 tgl                      1935 CBC        2196 :         Oid         namespaceId = lfirst_oid(l);
                               1936                 : 
 5833                          1937            2196 :         if (namespaceId == myTempNamespace)
 5833 tgl                      1938 GIC         171 :             continue;           /* do not look in temp namespace */
                               1939                 : 
 1601 andres                   1940            2025 :         opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid,
 4802 rhaas                    1941 ECB             :                                 ObjectIdGetDatum(amid),
                               1942                 :                                 PointerGetDatum(opfname),
                               1943                 :                                 ObjectIdGetDatum(namespaceId));
 5951 tgl                      1944 GIC        2025 :         if (OidIsValid(opfid))
                               1945            1109 :             return opfid;
 5951 tgl                      1946 ECB             :     }
                               1947                 : 
                               1948                 :     /* Not found in path */
 5951 tgl                      1949 GIC           6 :     return InvalidOid;
                               1950                 : }
                               1951                 : 
                               1952                 : /*
                               1953                 :  * OpfamilyIsVisible
                               1954                 :  *      Determine whether an opfamily (identified by OID) is visible in the
                               1955                 :  *      current search path.  Visible means "would be found by searching
 5951 tgl                      1956 ECB             :  *      for the unqualified opfamily name".
                               1957                 :  */
                               1958                 : bool
 5951 tgl                      1959 GIC         829 : OpfamilyIsVisible(Oid opfid)
                               1960                 : {
                               1961                 :     HeapTuple   opftup;
                               1962                 :     Form_pg_opfamily opfform;
 5951 tgl                      1963 ECB             :     Oid         opfnamespace;
                               1964                 :     bool        visible;
 5951 tgl                      1965 EUB             : 
 4802 rhaas                    1966 CBC         829 :     opftup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
 5951 tgl                      1967 GIC         829 :     if (!HeapTupleIsValid(opftup))
 5951 tgl                      1968 LBC           0 :         elog(ERROR, "cache lookup failed for opfamily %u", opfid);
 5951 tgl                      1969 GIC         829 :     opfform = (Form_pg_opfamily) GETSTRUCT(opftup);
                               1970                 : 
                               1971             829 :     recomputeNamespacePath();
                               1972                 : 
                               1973                 :     /*
                               1974                 :      * Quick check: if it ain't in the path at all, it ain't visible. Items in
 5951 tgl                      1975 ECB             :      * the system namespace are surely in the path and so we needn't even do
                               1976                 :      * list_member_oid() for them.
                               1977                 :      */
 5951 tgl                      1978 CBC         829 :     opfnamespace = opfform->opfnamespace;
 5951 tgl                      1979 GIC         829 :     if (opfnamespace != PG_CATALOG_NAMESPACE &&
 5861                          1980             685 :         !list_member_oid(activeSearchPath, opfnamespace))
 5951                          1981              75 :         visible = false;
                               1982                 :     else
                               1983                 :     {
                               1984                 :         /*
                               1985                 :          * If it is in the path, it might still not be visible; it could be
                               1986                 :          * hidden by another opfamily of the same name earlier in the path. So
 5951 tgl                      1987 ECB             :          * we must do a slow check to see if this opfamily would be found by
                               1988                 :          * OpfamilynameGetOpfid.
                               1989                 :          */
 5951 tgl                      1990 GIC         754 :         char       *opfname = NameStr(opfform->opfname);
                               1991                 : 
 5951 tgl                      1992 CBC         754 :         visible = (OpfamilynameGetOpfid(opfform->opfmethod, opfname) == opfid);
                               1993                 :     }
 5951 tgl                      1994 ECB             : 
 5951 tgl                      1995 GIC         829 :     ReleaseSysCache(opftup);
                               1996                 : 
                               1997             829 :     return visible;
                               1998                 : }
                               1999                 : 
                               2000                 : /*
                               2001                 :  * lookup_collation
                               2002                 :  *      If there's a collation of the given name/namespace, and it works
 2115 tgl                      2003 ECB             :  *      with the given encoding, return its OID.  Else return InvalidOid.
                               2004                 :  */
                               2005                 : static Oid
 2115 tgl                      2006 GIC        5751 : lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
                               2007                 : {
                               2008                 :     Oid         collid;
                               2009                 :     HeapTuple   colltup;
 2115 tgl                      2010 ECB             :     Form_pg_collation collform;
                               2011                 : 
                               2012                 :     /* Check for encoding-specific entry (exact match) */
 1601 andres                   2013 GIC        5751 :     collid = GetSysCacheOid3(COLLNAMEENCNSP, Anum_pg_collation_oid,
 2115 tgl                      2014 ECB             :                              PointerGetDatum(collname),
                               2015                 :                              Int32GetDatum(encoding),
                               2016                 :                              ObjectIdGetDatum(collnamespace));
 2115 tgl                      2017 GIC        5751 :     if (OidIsValid(collid))
                               2018             164 :         return collid;
                               2019                 : 
                               2020                 :     /*
                               2021                 :      * Check for any-encoding entry.  This takes a bit more work: while libc
                               2022                 :      * collations with collencoding = -1 do work with all encodings, ICU
 2115 tgl                      2023 ECB             :      * collations only work with certain encodings, so we have to check that
                               2024                 :      * aspect before deciding it's a match.
                               2025                 :      */
 2115 tgl                      2026 GIC        5587 :     colltup = SearchSysCache3(COLLNAMEENCNSP,
 2115 tgl                      2027 ECB             :                               PointerGetDatum(collname),
                               2028                 :                               Int32GetDatum(-1),
                               2029                 :                               ObjectIdGetDatum(collnamespace));
 2115 tgl                      2030 CBC        5587 :     if (!HeapTupleIsValid(colltup))
 2115 tgl                      2031 GIC         530 :         return InvalidOid;
 2115 tgl                      2032 CBC        5057 :     collform = (Form_pg_collation) GETSTRUCT(colltup);
                               2033            5057 :     if (collform->collprovider == COLLPROVIDER_ICU)
                               2034                 :     {
 2115 tgl                      2035 GBC         439 :         if (is_encoding_supported_by_icu(encoding))
 1601 andres                   2036 GIC         439 :             collid = collform->oid;
                               2037                 :         else
 2115 tgl                      2038 UIC           0 :             collid = InvalidOid;
 2115 tgl                      2039 ECB             :     }
                               2040                 :     else
                               2041                 :     {
 1601 andres                   2042 CBC        4618 :         collid = collform->oid;
                               2043                 :     }
 2115 tgl                      2044 GIC        5057 :     ReleaseSysCache(colltup);
                               2045            5057 :     return collid;
                               2046                 : }
                               2047                 : 
                               2048                 : /*
                               2049                 :  * CollationGetCollid
                               2050                 :  *      Try to resolve an unqualified collation name.
                               2051                 :  *      Returns OID if collation found in search path, else InvalidOid.
                               2052                 :  *
                               2053                 :  * Note that this will only find collations that work with the current
 2115 tgl                      2054 ECB             :  * database's encoding.
                               2055                 :  */
 4443 peter_e                  2056                 : Oid
 4443 peter_e                  2057 GIC         215 : CollationGetCollid(const char *collname)
                               2058                 : {
 4412 tgl                      2059 CBC         215 :     int32       dbencoding = GetDatabaseEncoding();
                               2060                 :     ListCell   *l;
 4443 peter_e                  2061 ECB             : 
 4443 peter_e                  2062 GIC         215 :     recomputeNamespacePath();
 4443 peter_e                  2063 ECB             : 
 4443 peter_e                  2064 GIC         334 :     foreach(l, activeSearchPath)
                               2065                 :     {
 4443 peter_e                  2066 CBC         334 :         Oid         namespaceId = lfirst_oid(l);
 4412 tgl                      2067 ECB             :         Oid         collid;
                               2068                 : 
 4443 peter_e                  2069 CBC         334 :         if (namespaceId == myTempNamespace)
                               2070              71 :             continue;           /* do not look in temp namespace */
 4443 peter_e                  2071 ECB             : 
 2115 tgl                      2072 GIC         263 :         collid = lookup_collation(collname, namespaceId, dbencoding);
 4443 peter_e                  2073             263 :         if (OidIsValid(collid))
                               2074             215 :             return collid;
 4443 peter_e                  2075 EUB             :     }
                               2076                 : 
                               2077                 :     /* Not found in path */
 4443 peter_e                  2078 UIC           0 :     return InvalidOid;
                               2079                 : }
                               2080                 : 
                               2081                 : /*
                               2082                 :  * CollationIsVisible
                               2083                 :  *      Determine whether a collation (identified by OID) is visible in the
                               2084                 :  *      current search path.  Visible means "would be found by searching
                               2085                 :  *      for the unqualified collation name".
                               2086                 :  *
                               2087                 :  * Note that only collations that work with the current database's encoding
 2115 tgl                      2088 ECB             :  * will be considered visible.
                               2089                 :  */
                               2090                 : bool
 4443 peter_e                  2091 GIC         215 : CollationIsVisible(Oid collid)
                               2092                 : {
                               2093                 :     HeapTuple   colltup;
                               2094                 :     Form_pg_collation collform;
 4443 peter_e                  2095 ECB             :     Oid         collnamespace;
                               2096                 :     bool        visible;
 4443 peter_e                  2097 EUB             : 
 4443 peter_e                  2098 CBC         215 :     colltup = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
 4443 peter_e                  2099 GIC         215 :     if (!HeapTupleIsValid(colltup))
 4443 peter_e                  2100 LBC           0 :         elog(ERROR, "cache lookup failed for collation %u", collid);
 4443 peter_e                  2101 GIC         215 :     collform = (Form_pg_collation) GETSTRUCT(colltup);
                               2102                 : 
                               2103             215 :     recomputeNamespacePath();
                               2104                 : 
                               2105                 :     /*
                               2106                 :      * Quick check: if it ain't in the path at all, it ain't visible. Items in
 4443 peter_e                  2107 ECB             :      * the system namespace are surely in the path and so we needn't even do
                               2108                 :      * list_member_oid() for them.
                               2109                 :      */
 4443 peter_e                  2110 GBC         215 :     collnamespace = collform->collnamespace;
 4443 peter_e                  2111 GIC         215 :     if (collnamespace != PG_CATALOG_NAMESPACE &&
                               2112              48 :         !list_member_oid(activeSearchPath, collnamespace))
 4443 peter_e                  2113 UIC           0 :         visible = false;
                               2114                 :     else
                               2115                 :     {
                               2116                 :         /*
                               2117                 :          * If it is in the path, it might still not be visible; it could be
                               2118                 :          * hidden by another collation of the same name earlier in the path,
                               2119                 :          * or it might not work with the current DB encoding.  So we must do a
 2115 tgl                      2120 ECB             :          * slow check to see if this collation would be found by
                               2121                 :          * CollationGetCollid.
 4443 peter_e                  2122                 :          */
 4443 peter_e                  2123 GIC         215 :         char       *collname = NameStr(collform->collname);
                               2124                 : 
 4443 peter_e                  2125 CBC         215 :         visible = (CollationGetCollid(collname) == collid);
                               2126                 :     }
 4443 peter_e                  2127 ECB             : 
 4443 peter_e                  2128 GIC         215 :     ReleaseSysCache(colltup);
                               2129                 : 
                               2130             215 :     return visible;
                               2131                 : }
                               2132                 : 
                               2133                 : 
                               2134                 : /*
                               2135                 :  * ConversionGetConid
                               2136                 :  *      Try to resolve an unqualified conversion name.
                               2137                 :  *      Returns OID if conversion found in search path, else InvalidOid.
                               2138                 :  *
 7423 bruce                    2139 ECB             :  * This is essentially the same as RelnameGetRelid.
                               2140                 :  */
                               2141                 : Oid
 7423 bruce                    2142 GIC           9 : ConversionGetConid(const char *conname)
                               2143                 : {
 7188 bruce                    2144 ECB             :     Oid         conid;
                               2145                 :     ListCell   *l;
 7423                          2146                 : 
 7423 bruce                    2147 GIC           9 :     recomputeNamespacePath();
 7423 bruce                    2148 ECB             : 
 5861 tgl                      2149 GIC          18 :     foreach(l, activeSearchPath)
 7423 bruce                    2150 ECB             :     {
 6892 neilc                    2151 GBC          18 :         Oid         namespaceId = lfirst_oid(l);
                               2152                 : 
 5833 tgl                      2153 CBC          18 :         if (namespaceId == myTempNamespace)
 5833 tgl                      2154 UIC           0 :             continue;           /* do not look in temp namespace */
                               2155                 : 
 1601 andres                   2156 CBC          18 :         conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
 4802 rhaas                    2157 ECB             :                                 PointerGetDatum(conname),
                               2158                 :                                 ObjectIdGetDatum(namespaceId));
 7423 bruce                    2159 GIC          18 :         if (OidIsValid(conid))
                               2160               9 :             return conid;
 7423 bruce                    2161 EUB             :     }
                               2162                 : 
                               2163                 :     /* Not found in path */
 7423 bruce                    2164 UIC           0 :     return InvalidOid;
                               2165                 : }
                               2166                 : 
                               2167                 : /*
                               2168                 :  * ConversionIsVisible
                               2169                 :  *      Determine whether a conversion (identified by OID) is visible in the
                               2170                 :  *      current search path.  Visible means "would be found by searching
 7423 bruce                    2171 ECB             :  *      for the unqualified conversion name".
                               2172                 :  */
                               2173                 : bool
 7423 bruce                    2174 GIC          15 : ConversionIsVisible(Oid conid)
                               2175                 : {
                               2176                 :     HeapTuple   contup;
                               2177                 :     Form_pg_conversion conform;
 7423 bruce                    2178 ECB             :     Oid         connamespace;
                               2179                 :     bool        visible;
 7423 bruce                    2180 EUB             : 
 4802 rhaas                    2181 CBC          15 :     contup = SearchSysCache1(CONVOID, ObjectIdGetDatum(conid));
 7423 bruce                    2182 GIC          15 :     if (!HeapTupleIsValid(contup))
 7202 tgl                      2183 LBC           0 :         elog(ERROR, "cache lookup failed for conversion %u", conid);
 7423 bruce                    2184 GIC          15 :     conform = (Form_pg_conversion) GETSTRUCT(contup);
                               2185                 : 
                               2186              15 :     recomputeNamespacePath();
                               2187                 : 
                               2188                 :     /*
                               2189                 :      * Quick check: if it ain't in the path at all, it ain't visible. Items in
 6385 bruce                    2190 ECB             :      * the system namespace are surely in the path and so we needn't even do
                               2191                 :      * list_member_oid() for them.
 7423                          2192                 :      */
 7423 bruce                    2193 CBC          15 :     connamespace = conform->connamespace;
 7423 bruce                    2194 GIC          15 :     if (connamespace != PG_CATALOG_NAMESPACE &&
 5861 tgl                      2195              15 :         !list_member_oid(activeSearchPath, connamespace))
 7423 bruce                    2196               6 :         visible = false;
                               2197                 :     else
                               2198                 :     {
                               2199                 :         /*
                               2200                 :          * If it is in the path, it might still not be visible; it could be
                               2201                 :          * hidden by another conversion of the same name earlier in the path.
 6385 bruce                    2202 ECB             :          * So we must do a slow check to see if this conversion would be found
                               2203                 :          * by ConversionGetConid.
 7423                          2204                 :          */
 7423 bruce                    2205 GIC           9 :         char       *conname = NameStr(conform->conname);
                               2206                 : 
 7423 bruce                    2207 CBC           9 :         visible = (ConversionGetConid(conname) == conid);
                               2208                 :     }
 7423 bruce                    2209 ECB             : 
 7423 bruce                    2210 GIC          15 :     ReleaseSysCache(contup);
                               2211                 : 
                               2212              15 :     return visible;
                               2213                 : }
                               2214                 : 
                               2215                 : /*
                               2216                 :  * get_statistics_object_oid - find a statistics object by possibly qualified name
                               2217                 :  *
 2207 alvherre                 2218 ECB             :  * If not found, returns InvalidOid if missing_ok, else throws error
                               2219                 :  */
                               2220                 : Oid
 2156 tgl                      2221 GIC         158 : get_statistics_object_oid(List *names, bool missing_ok)
                               2222                 : {
 2207 alvherre                 2223 ECB             :     char       *schemaname;
                               2224                 :     char       *stats_name;
                               2225                 :     Oid         namespaceId;
 2207 alvherre                 2226 GIC         158 :     Oid         stats_oid = InvalidOid;
 2207 alvherre                 2227 ECB             :     ListCell   *l;
                               2228                 : 
                               2229                 :     /* deconstruct the name list */
 2207 alvherre                 2230 GIC         158 :     DeconstructQualifiedName(names, &schemaname, &stats_name);
                               2231                 : 
 2207 alvherre                 2232 CBC         158 :     if (schemaname)
 2207 alvherre                 2233 ECB             :     {
 2207 alvherre                 2234 EUB             :         /* use exact schema given */
 2207 alvherre                 2235 GIC          14 :         namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
 2207 alvherre                 2236 CBC          14 :         if (missing_ok && !OidIsValid(namespaceId))
 2207 alvherre                 2237 UIC           0 :             stats_oid = InvalidOid;
                               2238                 :         else
 1601 andres                   2239 GIC          14 :             stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
                               2240                 :                                         PointerGetDatum(stats_name),
                               2241                 :                                         ObjectIdGetDatum(namespaceId));
                               2242                 :     }
 2207 alvherre                 2243 ECB             :     else
                               2244                 :     {
                               2245                 :         /* search for it in search path */
 2207 alvherre                 2246 GIC         144 :         recomputeNamespacePath();
 2207 alvherre                 2247 ECB             : 
 2207 alvherre                 2248 GIC         294 :         foreach(l, activeSearchPath)
 2207 alvherre                 2249 ECB             :         {
 2207 alvherre                 2250 GBC         288 :             namespaceId = lfirst_oid(l);
 2207 alvherre                 2251 ECB             : 
 2207 alvherre                 2252 GIC         288 :             if (namespaceId == myTempNamespace)
 2207 alvherre                 2253 UIC           0 :                 continue;       /* do not look in temp namespace */
 1601 andres                   2254 CBC         288 :             stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid,
 2207 alvherre                 2255 ECB             :                                         PointerGetDatum(stats_name),
                               2256                 :                                         ObjectIdGetDatum(namespaceId));
 2207 alvherre                 2257 GIC         288 :             if (OidIsValid(stats_oid))
                               2258             138 :                 break;
 2207 alvherre                 2259 ECB             :         }
                               2260                 :     }
                               2261                 : 
 2207 alvherre                 2262 GIC         158 :     if (!OidIsValid(stats_oid) && !missing_ok)
                               2263               3 :         ereport(ERROR,
                               2264                 :                 (errcode(ERRCODE_UNDEFINED_OBJECT),
 2156 tgl                      2265 ECB             :                  errmsg("statistics object \"%s\" does not exist",
                               2266                 :                         NameListToString(names))));
                               2267                 : 
 2207 alvherre                 2268 GIC         155 :     return stats_oid;
                               2269                 : }
                               2270                 : 
                               2271                 : /*
                               2272                 :  * StatisticsObjIsVisible
                               2273                 :  *      Determine whether a statistics object (identified by OID) is visible in
                               2274                 :  *      the current search path.  Visible means "would be found by searching
 2157 alvherre                 2275 ECB             :  *      for the unqualified statistics object name".
                               2276                 :  */
                               2277                 : bool
 2157 alvherre                 2278 GIC         323 : StatisticsObjIsVisible(Oid relid)
                               2279                 : {
                               2280                 :     HeapTuple   stxtup;
                               2281                 :     Form_pg_statistic_ext stxform;
 2157 alvherre                 2282 ECB             :     Oid         stxnamespace;
                               2283                 :     bool        visible;
 2157 alvherre                 2284 EUB             : 
 2157 alvherre                 2285 CBC         323 :     stxtup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(relid));
 2157 alvherre                 2286 GIC         323 :     if (!HeapTupleIsValid(stxtup))
 2157 alvherre                 2287 LBC           0 :         elog(ERROR, "cache lookup failed for statistics object %u", relid);
 2157 alvherre                 2288 GIC         323 :     stxform = (Form_pg_statistic_ext) GETSTRUCT(stxtup);
                               2289                 : 
                               2290             323 :     recomputeNamespacePath();
                               2291                 : 
                               2292                 :     /*
                               2293                 :      * Quick check: if it ain't in the path at all, it ain't visible. Items in
 2157 alvherre                 2294 ECB             :      * the system namespace are surely in the path and so we needn't even do
                               2295                 :      * list_member_oid() for them.
                               2296                 :      */
 2157 alvherre                 2297 CBC         323 :     stxnamespace = stxform->stxnamespace;
 2157 alvherre                 2298 GIC         323 :     if (stxnamespace != PG_CATALOG_NAMESPACE &&
                               2299             323 :         !list_member_oid(activeSearchPath, stxnamespace))
                               2300              39 :         visible = false;
                               2301                 :     else
                               2302                 :     {
                               2303                 :         /*
                               2304                 :          * If it is in the path, it might still not be visible; it could be
 2157 alvherre                 2305 ECB             :          * hidden by another statistics object of the same name earlier in the
                               2306                 :          * path. So we must do a slow check for conflicting objects.
                               2307                 :          */
 2157 alvherre                 2308 CBC         284 :         char       *stxname = NameStr(stxform->stxname);
 2157 alvherre                 2309 ECB             :         ListCell   *l;
                               2310                 : 
 2157 alvherre                 2311 CBC         284 :         visible = false;
 2157 alvherre                 2312 GIC         611 :         foreach(l, activeSearchPath)
 2157 alvherre                 2313 ECB             :         {
 2157 alvherre                 2314 GIC         611 :             Oid         namespaceId = lfirst_oid(l);
                               2315                 : 
 2157 alvherre                 2316 CBC         611 :             if (namespaceId == stxnamespace)
 2157 alvherre                 2317 ECB             :             {
                               2318                 :                 /* Found it first in path */
 2157 alvherre                 2319 CBC         284 :                 visible = true;
 2157 alvherre                 2320 GIC         284 :                 break;
                               2321                 :             }
                               2322             327 :             if (SearchSysCacheExists2(STATEXTNAMENSP,
                               2323                 :                                       PointerGetDatum(stxname),
 2157 alvherre                 2324 EUB             :                                       ObjectIdGetDatum(namespaceId)))
                               2325                 :             {
                               2326                 :                 /* Found something else first in path */
 2157 alvherre                 2327 UIC           0 :                 break;
                               2328                 :             }
 2157 alvherre                 2329 ECB             :         }
                               2330                 :     }
                               2331                 : 
 2157 alvherre                 2332 GIC         323 :     ReleaseSysCache(stxtup);
                               2333                 : 
                               2334             323 :     return visible;
                               2335                 : }
                               2336                 : 
                               2337                 : /*
                               2338                 :  * get_ts_parser_oid - find a TS parser by possibly qualified name
                               2339                 :  *
 4630 rhaas                    2340 ECB             :  * If not found, returns InvalidOid if missing_ok, else throws error
                               2341                 :  */
                               2342                 : Oid
 4630 rhaas                    2343 GIC        8549 : get_ts_parser_oid(List *names, bool missing_ok)
                               2344                 : {
 5710 tgl                      2345 ECB             :     char       *schemaname;
                               2346                 :     char       *parser_name;
                               2347                 :     Oid         namespaceId;
 5710 tgl                      2348 GIC        8549 :     Oid         prsoid = InvalidOid;
 5710 tgl                      2349 ECB             :     ListCell   *l;
                               2350                 : 
                               2351                 :     /* deconstruct the name list */
 5710 tgl                      2352 GIC        8549 :     DeconstructQualifiedName(names, &schemaname, &parser_name);
                               2353                 : 
 5710 tgl                      2354 CBC        8543 :     if (schemaname)
 5710 tgl                      2355 ECB             :     {
                               2356                 :         /* use exact schema given */
 3725 bruce                    2357 GIC          23 :         namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
 3725 bruce                    2358 CBC          23 :         if (missing_ok && !OidIsValid(namespaceId))
 3725 bruce                    2359 GIC           3 :             prsoid = InvalidOid;
                               2360                 :         else
 1601 andres                   2361              20 :             prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
                               2362                 :                                      PointerGetDatum(parser_name),
                               2363                 :                                      ObjectIdGetDatum(namespaceId));
                               2364                 :     }
 5710 tgl                      2365 ECB             :     else
                               2366                 :     {
                               2367                 :         /* search for it in search path */
 5710 tgl                      2368 GIC        8520 :         recomputeNamespacePath();
 5710 tgl                      2369 ECB             : 
 5710 tgl                      2370 GIC        8562 :         foreach(l, activeSearchPath)
 5710 tgl                      2371 ECB             :         {
 5710 tgl                      2372 GBC        8550 :             namespaceId = lfirst_oid(l);
                               2373                 : 
 5710 tgl                      2374 CBC        8550 :             if (namespaceId == myTempNamespace)
 5624 bruce                    2375 UIC           0 :                 continue;       /* do not look in temp namespace */
                               2376                 : 
 1601 andres                   2377 CBC        8550 :             prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid,
 4802 rhaas                    2378 ECB             :                                      PointerGetDatum(parser_name),
                               2379                 :                                      ObjectIdGetDatum(namespaceId));
 5710 tgl                      2380 GIC        8550 :             if (OidIsValid(prsoid))
                               2381            8508 :                 break;
 5710 tgl                      2382 ECB             :         }
                               2383                 :     }
                               2384                 : 
 4630 rhaas                    2385 GIC        8543 :     if (!OidIsValid(prsoid) && !missing_ok)
 5710 tgl                      2386              15 :         ereport(ERROR,
                               2387                 :                 (errcode(ERRCODE_UNDEFINED_OBJECT),
 5710 tgl                      2388 ECB             :                  errmsg("text search parser \"%s\" does not exist",
                               2389                 :                         NameListToString(names))));
                               2390                 : 
 5710 tgl                      2391 GIC        8528 :     return prsoid;
                               2392                 : }
                               2393                 : 
                               2394                 : /*
                               2395                 :  * TSParserIsVisible
                               2396                 :  *      Determine whether a parser (identified by OID) is visible in the
                               2397                 :  *      current search path.  Visible means "would be found by searching
 5710 tgl                      2398 ECB             :  *      for the unqualified parser name".
                               2399                 :  */
                               2400                 : bool
 5710 tgl                      2401 GIC          15 : TSParserIsVisible(Oid prsId)
                               2402                 : {
                               2403                 :     HeapTuple   tup;
                               2404                 :     Form_pg_ts_parser form;
 5710 tgl                      2405 ECB             :     Oid         namespace;
                               2406                 :     bool        visible;
 5710 tgl                      2407 EUB             : 
 4802 rhaas                    2408 CBC          15 :     tup = SearchSysCache1(TSPARSEROID, ObjectIdGetDatum(prsId));
 5710 tgl                      2409 GIC          15 :     if (!HeapTupleIsValid(tup))
 5710 tgl                      2410 LBC           0 :         elog(ERROR, "cache lookup failed for text search parser %u", prsId);
 5710 tgl                      2411 GIC          15 :     form = (Form_pg_ts_parser) GETSTRUCT(tup);
                               2412                 : 
                               2413              15 :     recomputeNamespacePath();
                               2414                 : 
                               2415                 :     /*
                               2416                 :      * Quick check: if it ain't in the path at all, it ain't visible. Items in
 5710 tgl                      2417 ECB             :      * the system namespace are surely in the path and so we needn't even do
                               2418                 :      * list_member_oid() for them.
                               2419                 :      */
 5710 tgl                      2420 CBC          15 :     namespace = form->prsnamespace;
 5710 tgl                      2421 GIC          15 :     if (namespace != PG_CATALOG_NAMESPACE &&
                               2422              15 :         !list_member_oid(activeSearchPath, namespace))
                               2423               6 :         visible = false;
                               2424                 :     else
                               2425                 :     {
                               2426                 :         /*
                               2427                 :          * If it is in the path, it might still not be visible; it could be
 5624 bruce                    2428 ECB             :          * hidden by another parser of the same name earlier in the path. So
                               2429                 :          * we must do a slow check for conflicting parsers.
                               2430                 :          */
 5710 tgl                      2431 CBC           9 :         char       *name = NameStr(form->prsname);
 5710 tgl                      2432 ECB             :         ListCell   *l;
                               2433                 : 
 5710 tgl                      2434 CBC           9 :         visible = false;
 5710 tgl                      2435 GIC          18 :         foreach(l, activeSearchPath)
 5710 tgl                      2436 ECB             :         {
 5710 tgl                      2437 GBC          18 :             Oid         namespaceId = lfirst_oid(l);
                               2438                 : 
 5710 tgl                      2439 CBC          18 :             if (namespaceId == myTempNamespace)
 5624 bruce                    2440 UIC           0 :                 continue;       /* do not look in temp namespace */
                               2441                 : 
 5710 tgl                      2442 CBC          18 :             if (namespaceId == namespace)
 5710 tgl                      2443 ECB             :             {
                               2444                 :                 /* Found it first in path */
 5710 tgl                      2445 CBC           9 :                 visible = true;
 5710 tgl                      2446 GIC           9 :                 break;
                               2447                 :             }
 4802 rhaas                    2448               9 :             if (SearchSysCacheExists2(TSPARSERNAMENSP,
                               2449                 :                                       PointerGetDatum(name),
 4802 rhaas                    2450 EUB             :                                       ObjectIdGetDatum(namespaceId)))
                               2451                 :             {
                               2452                 :                 /* Found something else first in path */
 5710 tgl                      2453 UIC           0 :                 break;
                               2454                 :             }
 5710 tgl                      2455 ECB             :         }
                               2456                 :     }
                               2457                 : 
 5710 tgl                      2458 GIC          15 :     ReleaseSysCache(tup);
                               2459                 : 
                               2460              15 :     return visible;
                               2461                 : }
                               2462                 : 
                               2463                 : /*
                               2464                 :  * get_ts_dict_oid - find a TS dictionary by possibly qualified name
                               2465                 :  *
 1363 michael                  2466 ECB             :  * If not found, returns InvalidOid if missing_ok, else throws error
                               2467                 :  */
                               2468                 : Oid
 4630 rhaas                    2469 GIC       34507 : get_ts_dict_oid(List *names, bool missing_ok)
                               2470                 : {
 5710 tgl                      2471 ECB             :     char       *schemaname;
                               2472                 :     char       *dict_name;
                               2473                 :     Oid         namespaceId;
 5710 tgl                      2474 GIC       34507 :     Oid         dictoid = InvalidOid;
 5710 tgl                      2475 ECB             :     ListCell   *l;
                               2476                 : 
                               2477                 :     /* deconstruct the name list */
 5710 tgl                      2478 GIC       34507 :     DeconstructQualifiedName(names, &schemaname, &dict_name);
                               2479                 : 
 5710 tgl                      2480 CBC       34501 :     if (schemaname)
 5710 tgl                      2481 ECB             :     {
                               2482                 :         /* use exact schema given */
 3725 bruce                    2483 GIC          52 :         namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
 3725 bruce                    2484 CBC          52 :         if (missing_ok && !OidIsValid(namespaceId))
 3725 bruce                    2485 GIC           3 :             dictoid = InvalidOid;
                               2486                 :         else
 1601 andres                   2487              49 :             dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
                               2488                 :                                       PointerGetDatum(dict_name),
                               2489                 :                                       ObjectIdGetDatum(namespaceId));
                               2490                 :     }
 5710 tgl                      2491 ECB             :     else
                               2492                 :     {
                               2493                 :         /* search for it in search path */
 5710 tgl                      2494 GIC       34449 :         recomputeNamespacePath();
 5710 tgl                      2495 ECB             : 
 5710 tgl                      2496 GIC       34877 :         foreach(l, activeSearchPath)
 5710 tgl                      2497 ECB             :         {
 5710 tgl                      2498 GBC       34862 :             namespaceId = lfirst_oid(l);
                               2499                 : 
 5710 tgl                      2500 CBC       34862 :             if (namespaceId == myTempNamespace)
 5624 bruce                    2501 UIC           0 :                 continue;       /* do not look in temp namespace */
                               2502                 : 
 1601 andres                   2503 CBC       34862 :             dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid,
 4802 rhaas                    2504 ECB             :                                       PointerGetDatum(dict_name),
                               2505                 :                                       ObjectIdGetDatum(namespaceId));
 5710 tgl                      2506 GIC       34862 :             if (OidIsValid(dictoid))
                               2507           34434 :                 break;
 5710 tgl                      2508 ECB             :         }
                               2509                 :     }
                               2510                 : 
 4630 rhaas                    2511 GIC       34501 :     if (!OidIsValid(dictoid) && !missing_ok)
 5710 tgl                      2512              15 :         ereport(ERROR,
                               2513                 :                 (errcode(ERRCODE_UNDEFINED_OBJECT),
 5710 tgl                      2514 ECB             :                  errmsg("text search dictionary \"%s\" does not exist",
                               2515                 :                         NameListToString(names))));
                               2516                 : 
 5710 tgl                      2517 GIC       34486 :     return dictoid;
                               2518                 : }
                               2519                 : 
                               2520                 : /*
                               2521                 :  * TSDictionaryIsVisible
                               2522                 :  *      Determine whether a dictionary (identified by OID) is visible in the
                               2523                 :  *      current search path.  Visible means "would be found by searching
 5710 tgl                      2524 ECB             :  *      for the unqualified dictionary name".
                               2525                 :  */
                               2526                 : bool
 5710 tgl                      2527 GIC        1319 : TSDictionaryIsVisible(Oid dictId)
                               2528                 : {
                               2529                 :     HeapTuple   tup;
                               2530                 :     Form_pg_ts_dict form;
 5710 tgl                      2531 ECB             :     Oid         namespace;
                               2532                 :     bool        visible;
 5710 tgl                      2533 EUB             : 
 4802 rhaas                    2534 GIC        1319 :     tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId));
 5710 tgl                      2535 CBC        1319 :     if (!HeapTupleIsValid(tup))
 5710 tgl                      2536 UIC           0 :         elog(ERROR, "cache lookup failed for text search dictionary %u",
 5710 tgl                      2537 ECB             :              dictId);
 5710 tgl                      2538 GIC        1319 :     form = (Form_pg_ts_dict) GETSTRUCT(tup);
                               2539                 : 
                               2540            1319 :     recomputeNamespacePath();
                               2541                 : 
                               2542                 :     /*
                               2543                 :      * Quick check: if it ain't in the path at all, it ain't visible. Items in
 5710 tgl                      2544 ECB             :      * the system namespace are surely in the path and so we needn't even do
                               2545                 :      * list_member_oid() for them.
                               2546                 :      */
 5710 tgl                      2547 CBC        1319 :     namespace = form->dictnamespace;
 5710 tgl                      2548 GIC        1319 :     if (namespace != PG_CATALOG_NAMESPACE &&
                               2549             153 :         !list_member_oid(activeSearchPath, namespace))
                               2550             141 :         visible = false;
                               2551                 :     else
                               2552                 :     {
                               2553                 :         /*
                               2554                 :          * If it is in the path, it might still not be visible; it could be
 5624 bruce                    2555 ECB             :          * hidden by another dictionary of the same name earlier in the path.
                               2556                 :          * So we must do a slow check for conflicting dictionaries.
                               2557                 :          */
 5710 tgl                      2558 CBC        1178 :         char       *name = NameStr(form->dictname);
 5710 tgl                      2559 ECB             :         ListCell   *l;
                               2560                 : 
 5710 tgl                      2561 CBC        1178 :         visible = false;
 5710 tgl                      2562 GIC        1190 :         foreach(l, activeSearchPath)
 5710 tgl                      2563 ECB             :         {
 5710 tgl                      2564 GBC        1190 :             Oid         namespaceId = lfirst_oid(l);
                               2565                 : 
 5710 tgl                      2566 CBC        1190 :             if (namespaceId == myTempNamespace)
 5624 bruce                    2567 UIC           0 :                 continue;       /* do not look in temp namespace */
                               2568                 : 
 5710 tgl                      2569 CBC        1190 :             if (namespaceId == namespace)
 5710 tgl                      2570 ECB             :             {
                               2571                 :                 /* Found it first in path */
 5710 tgl                      2572 CBC        1178 :                 visible = true;
 5710 tgl                      2573 GIC        1178 :                 break;
                               2574                 :             }
 4802 rhaas                    2575              12 :             if (SearchSysCacheExists2(TSDICTNAMENSP,
                               2576                 :                                       PointerGetDatum(name),
 4802 rhaas                    2577 EUB             :                                       ObjectIdGetDatum(namespaceId)))
                               2578                 :             {
                               2579                 :                 /* Found something else first in path */
 5710 tgl                      2580 UIC           0 :                 break;
                               2581                 :             }
 5710 tgl                      2582 ECB             :         }
                               2583                 :     }
                               2584                 : 
 5710 tgl                      2585 GIC        1319 :     ReleaseSysCache(tup);
                               2586                 : 
                               2587            1319 :     return visible;
                               2588                 : }
                               2589                 : 
                               2590                 : /*
                               2591                 :  * get_ts_template_oid - find a TS template by possibly qualified name
                               2592                 :  *
 4630 rhaas                    2593 ECB             :  * If not found, returns InvalidOid if missing_ok, else throws error
                               2594                 :  */
                               2595                 : Oid
 4630 rhaas                    2596 GIC        8910 : get_ts_template_oid(List *names, bool missing_ok)
                               2597                 : {
 5710 tgl                      2598 ECB             :     char       *schemaname;
                               2599                 :     char       *template_name;
                               2600                 :     Oid         namespaceId;
 5710 tgl                      2601 GIC        8910 :     Oid         tmploid = InvalidOid;
 5710 tgl                      2602 ECB             :     ListCell   *l;
                               2603                 : 
                               2604                 :     /* deconstruct the name list */
 5710 tgl                      2605 GIC        8910 :     DeconstructQualifiedName(names, &schemaname, &template_name);
                               2606                 : 
 5710 tgl                      2607 CBC        8904 :     if (schemaname)
 5710 tgl                      2608 ECB             :     {
                               2609                 :         /* use exact schema given */
 3725 bruce                    2610 GIC          28 :         namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
 3725 bruce                    2611 CBC          28 :         if (missing_ok && !OidIsValid(namespaceId))
 3725 bruce                    2612 GIC           3 :             tmploid = InvalidOid;
                               2613                 :         else
 1601 andres                   2614              25 :             tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
                               2615                 :                                       PointerGetDatum(template_name),
                               2616                 :                                       ObjectIdGetDatum(namespaceId));
                               2617                 :     }
 5710 tgl                      2618 ECB             :     else
                               2619                 :     {
                               2620                 :         /* search for it in search path */
 5710 tgl                      2621 GIC        8876 :         recomputeNamespacePath();
 5710 tgl                      2622 ECB             : 
 5710 tgl                      2623 GIC        8919 :         foreach(l, activeSearchPath)
 5710 tgl                      2624 ECB             :         {
 5710 tgl                      2625 GBC        8907 :             namespaceId = lfirst_oid(l);
                               2626                 : 
 5710 tgl                      2627 CBC        8907 :             if (namespaceId == myTempNamespace)
 5624 bruce                    2628 UIC           0 :                 continue;       /* do not look in temp namespace */
                               2629                 : 
 1601 andres                   2630 CBC        8907 :             tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid,
 4802 rhaas                    2631 ECB             :                                       PointerGetDatum(template_name),
                               2632                 :                                       ObjectIdGetDatum(namespaceId));
 5710 tgl                      2633 GIC        8907 :             if (OidIsValid(tmploid))
                               2634            8864 :                 break;
 5710 tgl                      2635 ECB             :         }
                               2636                 :     }
                               2637                 : 
 4630 rhaas                    2638 GIC        8904 :     if (!OidIsValid(tmploid) && !missing_ok)
 5710 tgl                      2639              15 :         ereport(ERROR,
                               2640                 :                 (errcode(ERRCODE_UNDEFINED_OBJECT),
 5710 tgl                      2641 ECB             :                  errmsg("text search template \"%s\" does not exist",
                               2642                 :                         NameListToString(names))));
                               2643                 : 
 5710 tgl                      2644 GIC        8889 :     return tmploid;
                               2645                 : }
                               2646                 : 
                               2647                 : /*
                               2648                 :  * TSTemplateIsVisible
                               2649                 :  *      Determine whether a template (identified by OID) is visible in the
                               2650                 :  *      current search path.  Visible means "would be found by searching
 5710 tgl                      2651 ECB             :  *      for the unqualified template name".
                               2652                 :  */
                               2653                 : bool
 5710 tgl                      2654 GIC          15 : TSTemplateIsVisible(Oid tmplId)
                               2655                 : {
                               2656                 :     HeapTuple   tup;
                               2657                 :     Form_pg_ts_template form;
 5710 tgl                      2658 ECB             :     Oid         namespace;
                               2659                 :     bool        visible;
 5710 tgl                      2660 EUB             : 
 4802 rhaas                    2661 CBC          15 :     tup = SearchSysCache1(TSTEMPLATEOID, ObjectIdGetDatum(tmplId));
 5710 tgl                      2662 GIC          15 :     if (!HeapTupleIsValid(tup))
 5710 tgl                      2663 LBC           0 :         elog(ERROR, "cache lookup failed for text search template %u", tmplId);
 5710 tgl                      2664 GIC          15 :     form = (Form_pg_ts_template) GETSTRUCT(tup);
                               2665                 : 
                               2666              15 :     recomputeNamespacePath();
                               2667                 : 
                               2668                 :     /*
                               2669                 :      * Quick check: if it ain't in the path at all, it ain't visible. Items in
 5710 tgl                      2670 ECB             :      * the system namespace are surely in the path and so we needn't even do
                               2671                 :      * list_member_oid() for them.
                               2672                 :      */
 5710 tgl                      2673 CBC          15 :     namespace = form->tmplnamespace;
 5710 tgl                      2674 GIC          15 :     if (namespace != PG_CATALOG_NAMESPACE &&
                               2675              15 :         !list_member_oid(activeSearchPath, namespace))
                               2676               6 :         visible = false;
                               2677                 :     else
                               2678                 :     {
                               2679                 :         /*
                               2680                 :          * If it is in the path, it might still not be visible; it could be
 5624 bruce                    2681 ECB             :          * hidden by another template of the same name earlier in the path. So
                               2682                 :          * we must do a slow check for conflicting templates.
                               2683                 :          */
 5710 tgl                      2684 CBC           9 :         char       *name = NameStr(form->tmplname);
 5710 tgl                      2685 ECB             :         ListCell   *l;
                               2686                 : 
 5710 tgl                      2687 CBC           9 :         visible = false;
 5710 tgl                      2688 GIC          18 :         foreach(l, activeSearchPath)
 5710 tgl                      2689 ECB             :         {
 5710 tgl                      2690 GBC          18 :             Oid         namespaceId = lfirst_oid(l);
                               2691                 : 
 5710 tgl                      2692 CBC          18 :             if (namespaceId == myTempNamespace)
 5624 bruce                    2693 UIC           0 :                 continue;       /* do not look in temp namespace */
                               2694                 : 
 5710 tgl                      2695 CBC          18 :             if (namespaceId == namespace)
 5710 tgl                      2696 ECB             :             {
                               2697                 :                 /* Found it first in path */
 5710 tgl                      2698 CBC           9 :                 visible = true;
 5710 tgl                      2699 GIC           9 :                 break;
                               2700                 :             }
 4802 rhaas                    2701               9 :             if (SearchSysCacheExists2(TSTEMPLATENAMENSP,
                               2702                 :                                       PointerGetDatum(name),
 4802 rhaas                    2703 EUB             :                                       ObjectIdGetDatum(namespaceId)))
                               2704                 :             {
                               2705                 :                 /* Found something else first in path */
 5710 tgl                      2706 UIC           0 :                 break;
                               2707                 :             }
 5710 tgl                      2708 ECB             :         }
                               2709                 :     }
                               2710                 : 
 5710 tgl                      2711 GIC          15 :     ReleaseSysCache(tup);
                               2712                 : 
                               2713              15 :     return visible;
                               2714                 : }
                               2715                 : 
                               2716                 : /*
                               2717                 :  * get_ts_config_oid - find a TS config by possibly qualified name
                               2718                 :  *
 4630 rhaas                    2719 ECB             :  * If not found, returns InvalidOid if missing_ok, else throws error
                               2720                 :  */
                               2721                 : Oid
 4630 rhaas                    2722 GIC       37749 : get_ts_config_oid(List *names, bool missing_ok)
                               2723                 : {
 5710 tgl                      2724 ECB             :     char       *schemaname;
                               2725                 :     char       *config_name;
                               2726                 :     Oid         namespaceId;
 5710 tgl                      2727 GIC       37749 :     Oid         cfgoid = InvalidOid;
 5710 tgl                      2728 ECB             :     ListCell   *l;
                               2729                 : 
                               2730                 :     /* deconstruct the name list */
 5710 tgl                      2731 GIC       37749 :     DeconstructQualifiedName(names, &schemaname, &config_name);
                               2732                 : 
 5710 tgl                      2733 CBC       37743 :     if (schemaname)
 5710 tgl                      2734 ECB             :     {
                               2735                 :         /* use exact schema given */
 3725 bruce                    2736 GIC        2722 :         namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
 3725 bruce                    2737 CBC        2722 :         if (missing_ok && !OidIsValid(namespaceId))
 3725 bruce                    2738 GIC           3 :             cfgoid = InvalidOid;
                               2739                 :         else
 1601 andres                   2740            2719 :             cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
                               2741                 :                                      PointerGetDatum(config_name),
                               2742                 :                                      ObjectIdGetDatum(namespaceId));
                               2743                 :     }
 5710 tgl                      2744 ECB             :     else
                               2745                 :     {
                               2746                 :         /* search for it in search path */
 5710 tgl                      2747 GIC       35021 :         recomputeNamespacePath();
 5710 tgl                      2748 ECB             : 
 5710 tgl                      2749 GIC       35564 :         foreach(l, activeSearchPath)
 5710 tgl                      2750 ECB             :         {
 5710 tgl                      2751 CBC       35536 :             namespaceId = lfirst_oid(l);
                               2752                 : 
                               2753           35536 :             if (namespaceId == myTempNamespace)
 5624 bruce                    2754 GIC         348 :                 continue;       /* do not look in temp namespace */
                               2755                 : 
 1601 andres                   2756 CBC       35188 :             cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid,
 4802 rhaas                    2757 ECB             :                                      PointerGetDatum(config_name),
                               2758                 :                                      ObjectIdGetDatum(namespaceId));
 5710 tgl                      2759 GIC       35188 :             if (OidIsValid(cfgoid))
                               2760           34993 :                 break;
 5710 tgl                      2761 ECB             :         }
                               2762                 :     }
                               2763                 : 
 4630 rhaas                    2764 GIC       37743 :     if (!OidIsValid(cfgoid) && !missing_ok)
 5710 tgl                      2765              15 :         ereport(ERROR,
                               2766                 :                 (errcode(ERRCODE_UNDEFINED_OBJECT),
 5710 tgl                      2767 ECB             :                  errmsg("text search configuration \"%s\" does not exist",
                               2768                 :                         NameListToString(names))));
                               2769                 : 
 5710 tgl                      2770 GIC       37728 :     return cfgoid;
                               2771                 : }
                               2772                 : 
                               2773                 : /*
                               2774                 :  * TSConfigIsVisible
                               2775                 :  *      Determine whether a text search configuration (identified by OID)
                               2776                 :  *      is visible in the current search path.  Visible means "would be found
 5710 tgl                      2777 ECB             :  *      by searching for the unqualified text search configuration name".
                               2778                 :  */
                               2779                 : bool
 5710 tgl                      2780 GIC          23 : TSConfigIsVisible(Oid cfgid)
                               2781                 : {
                               2782                 :     HeapTuple   tup;
                               2783                 :     Form_pg_ts_config form;
 5710 tgl                      2784 ECB             :     Oid         namespace;
                               2785                 :     bool        visible;
 5710 tgl                      2786 EUB             : 
 4802 rhaas                    2787 GIC          23 :     tup = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(cfgid));
 5710 tgl                      2788 CBC          23 :     if (!HeapTupleIsValid(tup))
 5710 tgl                      2789 UIC           0 :         elog(ERROR, "cache lookup failed for text search configuration %u",
 5710 tgl                      2790 ECB             :              cfgid);
 5710 tgl                      2791 GIC          23 :     form = (Form_pg_ts_config) GETSTRUCT(tup);
                               2792                 : 
                               2793              23 :     recomputeNamespacePath();
                               2794                 : 
                               2795                 :     /*
                               2796                 :      * Quick check: if it ain't in the path at all, it ain't visible. Items in
 5710 tgl                      2797 ECB             :      * the system namespace are surely in the path and so we needn't even do
                               2798                 :      * list_member_oid() for them.
                               2799                 :      */
 5710 tgl                      2800 CBC          23 :     namespace = form->cfgnamespace;
 5710 tgl                      2801 GIC          23 :     if (namespace != PG_CATALOG_NAMESPACE &&
                               2802              23 :         !list_member_oid(activeSearchPath, namespace))
                               2803               8 :         visible = false;
                               2804                 :     else
                               2805                 :     {
                               2806                 :         /*
                               2807                 :          * If it is in the path, it might still not be visible; it could be
 5710 tgl                      2808 ECB             :          * hidden by another configuration of the same name earlier in the
                               2809                 :          * path. So we must do a slow check for conflicting configurations.
                               2810                 :          */
 5710 tgl                      2811 CBC          15 :         char       *name = NameStr(form->cfgname);
 5710 tgl                      2812 ECB             :         ListCell   *l;
                               2813                 : 
 5710 tgl                      2814 CBC          15 :         visible = false;
 5710 tgl                      2815 GIC          30 :         foreach(l, activeSearchPath)
 5710 tgl                      2816 ECB             :         {
 5710 tgl                      2817 GBC          30 :             Oid         namespaceId = lfirst_oid(l);
                               2818                 : 
 5710 tgl                      2819 CBC          30 :             if (namespaceId == myTempNamespace)
 5624 bruce                    2820 UIC           0 :                 continue;       /* do not look in temp namespace */
                               2821                 : 
 5710 tgl                      2822 CBC          30 :             if (namespaceId == namespace)
 5710 tgl                      2823 ECB             :             {
                               2824                 :                 /* Found it first in path */
 5710 tgl                      2825 CBC          15 :                 visible = true;
 5710 tgl                      2826 GIC          15 :                 break;
                               2827                 :             }
 4802 rhaas                    2828              15 :             if (SearchSysCacheExists2(TSCONFIGNAMENSP,
                               2829                 :                                       PointerGetDatum(name),
 4802 rhaas                    2830 EUB             :                                       ObjectIdGetDatum(namespaceId)))
                               2831                 :             {
                               2832                 :                 /* Found something else first in path */
 5710 tgl                      2833 UIC           0 :                 break;
                               2834                 :             }
 5710 tgl                      2835 ECB             :         }
                               2836                 :     }
                               2837                 : 
 5710 tgl                      2838 GIC          23 :     ReleaseSysCache(tup);
                               2839                 : 
                               2840              23 :     return visible;
                               2841                 : }
                               2842                 : 
                               2843                 : 
                               2844                 : /*
                               2845                 :  * DeconstructQualifiedName
                               2846                 :  *      Given a possibly-qualified name expressed as a list of String nodes,
                               2847                 :  *      extract the schema name and object name.
                               2848                 :  *
 7559 tgl                      2849 ECB             :  * *nspname_p is set to NULL if there is no explicit schema name.
                               2850                 :  */
                               2851                 : void
 7559 tgl                      2852 GIC     1761688 : DeconstructQualifiedName(List *names,
                               2853                 :                          char **nspname_p,
 7559 tgl                      2854 ECB             :                          char **objname_p)
 7681                          2855                 : {
                               2856                 :     char       *catalogname;
 7681 tgl                      2857 CBC     1761688 :     char       *schemaname = NULL;
 7681 tgl                      2858 GIC     1761688 :     char       *objname = NULL;
 7681 tgl                      2859 ECB             : 
 6892 neilc                    2860 CBC     1761688 :     switch (list_length(names))
 7681 tgl                      2861 ECB             :     {
 7681 tgl                      2862 CBC     1549357 :         case 1:
 6892 neilc                    2863         1549357 :             objname = strVal(linitial(names));
 7681 tgl                      2864         1549357 :             break;
                               2865          212277 :         case 2:
 6892 neilc                    2866          212277 :             schemaname = strVal(linitial(names));
 7681 tgl                      2867          212277 :             objname = strVal(lsecond(names));
                               2868          212277 :             break;
                               2869              51 :         case 3:
 6892 neilc                    2870 GIC          51 :             catalogname = strVal(linitial(names));
 7681 tgl                      2871              51 :             schemaname = strVal(lsecond(names));
 7364                          2872              51 :             objname = strVal(lthird(names));
                               2873                 : 
 7681 tgl                      2874 ECB             :             /*
                               2875                 :              * We check the catalog name and then ignore it.
                               2876                 :              */
 7226 peter_e                  2877 GIC          51 :             if (strcmp(catalogname, get_database_name(MyDatabaseId)) != 0)
 7202 tgl                      2878              51 :                 ereport(ERROR,
 7202 tgl                      2879 EUB             :                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 2118 tgl                      2880 ECB             :                          errmsg("cross-database references are not implemented: %s",
                               2881                 :                                 NameListToString(names))));
 7681 tgl                      2882 UIC           0 :             break;
 7681 tgl                      2883 GIC           3 :         default:
 7202                          2884               3 :             ereport(ERROR,
                               2885                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
                               2886                 :                      errmsg("improper qualified name (too many dotted names): %s",
                               2887                 :                             NameListToString(names))));
 7681 tgl                      2888 ECB             :             break;
                               2889                 :     }
                               2890                 : 
 7559 tgl                      2891 GIC     1761634 :     *nspname_p = schemaname;
                               2892         1761634 :     *objname_p = objname;
                               2893         1761634 : }
                               2894                 : 
                               2895                 : /*
                               2896                 :  * LookupNamespaceNoError
                               2897                 :  *      Look up a schema name.
                               2898                 :  *
                               2899                 :  * Returns the namespace OID, or InvalidOid if not found.
                               2900                 :  *
                               2901                 :  * Note this does NOT perform any permissions check --- callers are
                               2902                 :  * responsible for being sure that an appropriate check is made.
 4908 tgl                      2903 ECB             :  * In the majority of cases LookupExplicitNamespace is preferable.
                               2904                 :  */
                               2905                 : Oid
 4908 tgl                      2906 CBC         165 : LookupNamespaceNoError(const char *nspname)
                               2907                 : {
 4908 tgl                      2908 EUB             :     /* check for pg_temp alias */
 4908 tgl                      2909 GIC         165 :     if (strcmp(nspname, "pg_temp") == 0)
 4908 tgl                      2910 EUB             :     {
 4908 tgl                      2911 UBC           0 :         if (OidIsValid(myTempNamespace))
                               2912                 :         {
 3656 rhaas                    2913 UIC           0 :             InvokeNamespaceSearchHook(myTempNamespace, true);
 4908 tgl                      2914               0 :             return myTempNamespace;
                               2915                 :         }
                               2916                 : 
                               2917                 :         /*
                               2918                 :          * Since this is used only for looking up existing objects, there is
 4908 tgl                      2919 EUB             :          * no point in trying to initialize the temp namespace here; and doing
                               2920                 :          * so might create problems for some callers. Just report "not found".
                               2921                 :          */
 4908 tgl                      2922 LBC           0 :         return InvalidOid;
                               2923                 :     }
                               2924                 : 
 4630 rhaas                    2925 GIC         165 :     return get_namespace_oid(nspname, true);
                               2926                 : }
                               2927                 : 
                               2928                 : /*
                               2929                 :  * LookupExplicitNamespace
                               2930                 :  *      Process an explicitly-specified schema name: look up the schema
                               2931                 :  *      and verify we have USAGE (lookup) rights in it.
                               2932                 :  *
 3725 bruce                    2933 ECB             :  * Returns the namespace OID
                               2934                 :  */
                               2935                 : Oid
 3725 bruce                    2936 GIC      320975 : LookupExplicitNamespace(const char *nspname, bool missing_ok)
                               2937                 : {
                               2938                 :     Oid         namespaceId;
 7559 tgl                      2939 ECB             :     AclResult   aclresult;
                               2940                 : 
 5833                          2941                 :     /* check for pg_temp alias */
 5833 tgl                      2942 CBC      320975 :     if (strcmp(nspname, "pg_temp") == 0)
                               2943                 :     {
 5833 tgl                      2944 GIC         168 :         if (OidIsValid(myTempNamespace))
                               2945             168 :             return myTempNamespace;
                               2946                 : 
                               2947                 :         /*
                               2948                 :          * Since this is used only for looking up existing objects, there is
                               2949                 :          * no point in trying to initialize the temp namespace here; and doing
                               2950                 :          * so might create problems for some callers --- just fall through.
 5833 tgl                      2951 ECB             :          */
                               2952                 :     }
                               2953                 : 
 3725 bruce                    2954 GIC      320807 :     namespaceId = get_namespace_oid(nspname, missing_ok);
 3725 bruce                    2955 CBC      320753 :     if (missing_ok && !OidIsValid(namespaceId))
                               2956             168 :         return InvalidOid;
 3602 bruce                    2957 ECB             : 
  147 peter                    2958 GNC      320585 :     aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_USAGE);
 7559 tgl                      2959 GIC      320585 :     if (aclresult != ACLCHECK_OK)
 1954 peter_e                  2960 CBC           4 :         aclcheck_error(aclresult, OBJECT_SCHEMA,
                               2961                 :                        nspname);
 3656 rhaas                    2962 ECB             :     /* Schema search hook for this lookup */
 3656 rhaas                    2963 GIC      320581 :     InvokeNamespaceSearchHook(namespaceId, true);
                               2964                 : 
 7559 tgl                      2965          320581 :     return namespaceId;
                               2966                 : }
                               2967                 : 
                               2968                 : /*
                               2969                 :  * LookupCreationNamespace
                               2970                 :  *      Look up the schema and verify we have CREATE rights on it.
                               2971                 :  *
                               2972                 :  * This is just like LookupExplicitNamespace except for the different
                               2973                 :  * permission check, and that we are willing to create pg_temp if needed.
                               2974                 :  *
                               2975                 :  * Note: calling this may result in a CommandCounterIncrement operation,
 5833 tgl                      2976 ECB             :  * if we have to create or clean out the temp namespace.
                               2977                 :  */
                               2978                 : Oid
 6460 tgl                      2979 GIC         233 : LookupCreationNamespace(const char *nspname)
                               2980                 : {
                               2981                 :     Oid         namespaceId;
 6460 tgl                      2982 ECB             :     AclResult   aclresult;
                               2983                 : 
                               2984                 :     /* check for pg_temp alias */
 5833 tgl                      2985 CBC         233 :     if (strcmp(nspname, "pg_temp") == 0)
 5833 tgl                      2986 ECB             :     {
                               2987                 :         /* Initialize temp namespace */
 1542 michael                  2988 GIC          70 :         AccessTempTableNamespace(false);
 5833 tgl                      2989 CBC          70 :         return myTempNamespace;
                               2990                 :     }
 5833 tgl                      2991 ECB             : 
 4630 rhaas                    2992 CBC         163 :     namespaceId = get_namespace_oid(nspname, false);
 6460 tgl                      2993 EUB             : 
  147 peter                    2994 GNC         162 :     aclresult = object_aclcheck(NamespaceRelationId, namespaceId, GetUserId(), ACL_CREATE);
 6460 tgl                      2995 GIC         162 :     if (aclresult != ACLCHECK_OK)
 1954 peter_e                  2996 LBC           0 :         aclcheck_error(aclresult, OBJECT_SCHEMA,
                               2997                 :                        nspname);
                               2998                 : 
 6460 tgl                      2999 GIC         162 :     return namespaceId;
                               3000                 : }
                               3001                 : 
                               3002                 : /*
                               3003                 :  * Common checks on switching namespaces.
                               3004                 :  *
                               3005                 :  * We complain if either the old or new namespaces is a temporary schema
                               3006                 :  * (or temporary toast schema), or if either the old or new namespaces is the
 2698 rhaas                    3007 ECB             :  * TOAST schema.
                               3008                 :  */
                               3009                 : void
 2698 rhaas                    3010 CBC         254 : CheckSetNamespace(Oid oldNspOid, Oid nspOid)
 4521 rhaas                    3011 EUB             : {
                               3012                 :     /* disallow renaming into or out of temp schemas */
 4521 rhaas                    3013 GIC         254 :     if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
 4521 rhaas                    3014 UIC           0 :         ereport(ERROR,
                               3015                 :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 2118 tgl                      3016 ECB             :                  errmsg("cannot move objects into or out of temporary schemas")));
 4521 rhaas                    3017 EUB             : 
                               3018                 :     /* same for TOAST schema */
 4521 rhaas                    3019 GIC         254 :     if (nspOid == PG_TOAST_NAMESPACE || oldNspOid == PG_TOAST_NAMESPACE)
 4521 rhaas                    3020 LBC           0 :         ereport(ERROR,
                               3021                 :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                               3022                 :                  errmsg("cannot move objects into or out of TOAST schema")));
 4521 rhaas                    3023 GIC         254 : }
                               3024                 : 
                               3025                 : /*
                               3026                 :  * QualifiedNameGetCreationNamespace
                               3027                 :  *      Given a possibly-qualified name for an object (in List-of-Strings
                               3028                 :  *      format), determine what namespace the object should be created in.
                               3029                 :  *      Also extract and return the object name (last component of list).
                               3030                 :  *
                               3031                 :  * Note: this does not apply any permissions check.  Callers must check
                               3032                 :  * for CREATE rights on the selected namespace when appropriate.
                               3033                 :  *
                               3034                 :  * Note: calling this may result in a CommandCounterIncrement operation,
 5833 tgl                      3035 ECB             :  * if we have to create or clean out the temp namespace.
                               3036                 :  */
                               3037                 : Oid
 7559 tgl                      3038 GIC       57491 : QualifiedNameGetCreationNamespace(List *names, char **objname_p)
                               3039                 : {
                               3040                 :     char       *schemaname;
 7559 tgl                      3041 ECB             :     Oid         namespaceId;
                               3042                 : 
                               3043                 :     /* deconstruct the name list */
 5833 tgl                      3044 GIC       57491 :     DeconstructQualifiedName(names, &schemaname, objname_p);
                               3045                 : 
 7681 tgl                      3046 CBC       57491 :     if (schemaname)
                               3047                 :     {
                               3048                 :         /* check for pg_temp alias */
 5833                          3049             769 :         if (strcmp(schemaname, "pg_temp") == 0)
 5833 tgl                      3050 ECB             :         {
                               3051                 :             /* Initialize temp namespace */
 1542 michael                  3052 GIC         150 :             AccessTempTableNamespace(false);
 5833 tgl                      3053 CBC         150 :             return myTempNamespace;
                               3054                 :         }
                               3055                 :         /* use exact schema given */
 4630 rhaas                    3056 GIC         619 :         namespaceId = get_namespace_oid(schemaname, false);
                               3057                 :         /* we do not check for USAGE rights here! */
                               3058                 :     }
 7681 tgl                      3059 ECB             :     else
                               3060                 :     {
                               3061                 :         /* use the default creation namespace */
 7650 tgl                      3062 GIC       56722 :         recomputeNamespacePath();
 5833 tgl                      3063 GBC       56722 :         if (activeTempCreationPending)
 5833 tgl                      3064 EUB             :         {
                               3065                 :             /* Need to initialize temp namespace */
 1542 michael                  3066 LBC           0 :             AccessTempTableNamespace(true);
 5833 tgl                      3067               0 :             return myTempNamespace;
 5833 tgl                      3068 EUB             :         }
 5861 tgl                      3069 GIC       56722 :         namespaceId = activeCreationNamespace;
 7664                          3070           56722 :         if (!OidIsValid(namespaceId))
 7202 tgl                      3071 UIC           0 :             ereport(ERROR,
                               3072                 :                     (errcode(ERRCODE_UNDEFINED_SCHEMA),
 7202 tgl                      3073 ECB             :                      errmsg("no schema has been selected to create in")));
                               3074                 :     }
                               3075                 : 
 7681 tgl                      3076 GIC       57341 :     return namespaceId;
                               3077                 : }
                               3078                 : 
                               3079                 : /*
                               3080                 :  * get_namespace_oid - given a namespace name, look up the OID
                               3081                 :  *
                               3082                 :  * If missing_ok is false, throw an error if namespace name not found.  If
 4630 rhaas                    3083 ECB             :  * true, just return InvalidOid.
                               3084                 :  */
                               3085                 : Oid
 4630 rhaas                    3086 GIC      368870 : get_namespace_oid(const char *nspname, bool missing_ok)
 4630 rhaas                    3087 ECB             : {
                               3088                 :     Oid         oid;
                               3089                 : 
 1601 andres                   3090 CBC      368870 :     oid = GetSysCacheOid1(NAMESPACENAME, Anum_pg_namespace_oid,
                               3091                 :                           CStringGetDatum(nspname));
 4630 rhaas                    3092 GIC      368870 :     if (!OidIsValid(oid) && !missing_ok)
 4382 bruce                    3093              87 :         ereport(ERROR,
 4382 bruce                    3094 ECB             :                 (errcode(ERRCODE_UNDEFINED_SCHEMA),
                               3095                 :                  errmsg("schema \"%s\" does not exist", nspname)));
                               3096                 : 
 4630 rhaas                    3097 GIC      368783 :     return oid;
                               3098                 : }
                               3099                 : 
                               3100                 : /*
                               3101                 :  * makeRangeVarFromNameList
 7681 tgl                      3102 ECB             :  *      Utility routine to convert a qualified-name list into RangeVar form.
                               3103                 :  */
                               3104                 : RangeVar *
 7681 tgl                      3105 GIC       31393 : makeRangeVarFromNameList(List *names)
 7681 tgl                      3106 ECB             : {
 5333 tgl                      3107 GIC       31393 :     RangeVar   *rel = makeRangeVar(NULL, NULL, -1);
 7681 tgl                      3108 ECB             : 
 6892 neilc                    3109 CBC       31393 :     switch (list_length(names))
 7681 tgl                      3110 ECB             :     {
 7681 tgl                      3111 CBC       18841 :         case 1:
 6892 neilc                    3112           18841 :             rel->relname = strVal(linitial(names));
 7681 tgl                      3113           18841 :             break;
                               3114           12513 :         case 2:
 6892 neilc                    3115           12513 :             rel->schemaname = strVal(linitial(names));
 7681 tgl                      3116           12513 :             rel->relname = strVal(lsecond(names));
                               3117           12513 :             break;
                               3118              39 :         case 3:
 6892 neilc                    3119              39 :             rel->catalogname = strVal(linitial(names));
 7681 tgl                      3120 GBC          39 :             rel->schemaname = strVal(lsecond(names));
 7364                          3121              39 :             rel->relname = strVal(lthird(names));
 7681 tgl                      3122 GIC          39 :             break;
 7681 tgl                      3123 UIC           0 :         default:
 7202                          3124               0 :             ereport(ERROR,
                               3125                 :                     (errcode(ERRCODE_SYNTAX_ERROR),
                               3126                 :                      errmsg("improper relation name (too many dotted names): %s",
                               3127                 :                             NameListToString(names))));
 7681 tgl                      3128 ECB             :             break;
                               3129                 :     }
                               3130                 : 
 7681 tgl                      3131 GIC       31393 :     return rel;
                               3132                 : }
                               3133                 : 
                               3134                 : /*
                               3135                 :  * NameListToString
                               3136                 :  *      Utility routine to convert a qualified-name list into a string.
                               3137                 :  *
                               3138                 :  * This is used primarily to form error messages, and so we do not quote
                               3139                 :  * the list elements, for the sake of legibility.
                               3140                 :  *
                               3141                 :  * In most scenarios the list elements should always be String values,
 5335 tgl                      3142 ECB             :  * but we also allow A_Star for the convenience of ColumnRef processing.
                               3143                 :  */
                               3144                 : char *
 7670 tgl                      3145 GIC         858 : NameListToString(List *names)
                               3146                 : {
 7670 tgl                      3147 ECB             :     StringInfoData string;
                               3148                 :     ListCell   *l;
                               3149                 : 
 7670 tgl                      3150 GIC         858 :     initStringInfo(&string);
 7670 tgl                      3151 ECB             : 
 7670 tgl                      3152 GIC        1911 :     foreach(l, names)
 7670 tgl                      3153 ECB             :     {
 5335 tgl                      3154 CBC        1053 :         Node       *name = (Node *) lfirst(l);
                               3155                 : 
 6892 neilc                    3156            1053 :         if (l != list_head(names))
 7670 tgl                      3157             195 :             appendStringInfoChar(&string, '.');
 5335 tgl                      3158 EUB             : 
 5335 tgl                      3159 GBC        1053 :         if (IsA(name, String))
 5335 tgl                      3160 GIC        1053 :             appendStringInfoString(&string, strVal(name));
 5335 tgl                      3161 UBC           0 :         else if (IsA(name, A_Star))
 2890 peter_e                  3162 UIC           0 :             appendStringInfoChar(&string, '*');
                               3163                 :         else
 5335 tgl                      3164               0 :             elog(ERROR, "unexpected node type in name list: %d",
 5335 tgl                      3165 ECB             :                  (int) nodeTag(name));
                               3166                 :     }
                               3167                 : 
 7670 tgl                      3168 GIC         858 :     return string.data;
                               3169                 : }
                               3170                 : 
                               3171                 : /*
                               3172                 :  * NameListToQuotedString
                               3173                 :  *      Utility routine to convert a qualified-name list into a string.
                               3174                 :  *
                               3175                 :  * Same as above except that names will be double-quoted where necessary,
 7463 tgl                      3176 EUB             :  * so the string could be re-parsed (eg, by textToQualifiedNameList).
                               3177                 :  */
                               3178                 : char *
 7463 tgl                      3179 UIC           0 : NameListToQuotedString(List *names)
                               3180                 : {
 7463 tgl                      3181 EUB             :     StringInfoData string;
                               3182                 :     ListCell   *l;
                               3183                 : 
 7463 tgl                      3184 UIC           0 :     initStringInfo(&string);
 7463 tgl                      3185 EUB             : 
 7463 tgl                      3186 UBC           0 :     foreach(l, names)
 7463 tgl                      3187 EUB             :     {
 6892 neilc                    3188 UIC           0 :         if (l != list_head(names))
 7463 tgl                      3189               0 :             appendStringInfoChar(&string, '.');
 7290 tgl                      3190 UBC           0 :         appendStringInfoString(&string, quote_identifier(strVal(lfirst(l))));
                               3191                 :     }
                               3192                 : 
 7463 tgl                      3193 UIC           0 :     return string.data;
                               3194                 : }
                               3195                 : 
                               3196                 : /*
 7679 tgl                      3197 ECB             :  * isTempNamespace - is the given namespace my temporary-table namespace?
                               3198                 :  */
                               3199                 : bool
 7679 tgl                      3200 CBC       24406 : isTempNamespace(Oid namespaceId)
 7679 tgl                      3201 ECB             : {
 7679 tgl                      3202 GIC       24406 :     if (OidIsValid(myTempNamespace) && myTempNamespace == namespaceId)
                               3203             317 :         return true;
                               3204           24089 :     return false;
                               3205                 : }
                               3206                 : 
                               3207                 : /*
                               3208                 :  * isTempToastNamespace - is the given namespace my temporary-toast-table
 5737 tgl                      3209 ECB             :  *      namespace?
                               3210                 :  */
                               3211                 : bool
 5737 tgl                      3212 CBC     5183703 : isTempToastNamespace(Oid namespaceId)
 5737 tgl                      3213 ECB             : {
 5737 tgl                      3214 GIC     5183703 :     if (OidIsValid(myTempToastNamespace) && myTempToastNamespace == namespaceId)
                               3215            1243 :         return true;
                               3216         5182460 :     return false;
                               3217                 : }
                               3218                 : 
                               3219                 : /*
                               3220                 :  * isTempOrTempToastNamespace - is the given namespace my temporary-table
 5737 tgl                      3221 ECB             :  *      namespace or my temporary-toast-table namespace?
                               3222                 :  */
                               3223                 : bool
 3149 bruce                    3224 CBC      160469 : isTempOrTempToastNamespace(Oid namespaceId)
 5737 tgl                      3225 ECB             : {
 5737 tgl                      3226 CBC      160469 :     if (OidIsValid(myTempNamespace) &&
 2118 tgl                      3227 GIC       30260 :         (myTempNamespace == namespaceId || myTempToastNamespace == namespaceId))
 5737                          3228           17771 :         return true;
                               3229          142698 :     return false;
                               3230                 : }
                               3231                 : 
                               3232                 : /*
                               3233                 :  * isAnyTempNamespace - is the given namespace a temporary-table namespace
                               3234                 :  * (either my own, or another backend's)?  Temporary-toast-table namespaces
 5737 tgl                      3235 ECB             :  * are included, too.
                               3236                 :  */
                               3237                 : bool
 6460 tgl                      3238 GIC      126856 : isAnyTempNamespace(Oid namespaceId)
                               3239                 : {
                               3240                 :     bool        result;
 7503 tgl                      3241 ECB             :     char       *nspname;
                               3242                 : 
 5737                          3243                 :     /* True if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
 7503 tgl                      3244 CBC      126856 :     nspname = get_namespace_name(namespaceId);
                               3245          126856 :     if (!nspname)
                               3246               1 :         return false;           /* no such namespace? */
 5737                          3247          253415 :     result = (strncmp(nspname, "pg_temp_", 8) == 0) ||
 5737 tgl                      3248 GIC      126560 :         (strncmp(nspname, "pg_toast_temp_", 14) == 0);
 7503                          3249          126855 :     pfree(nspname);
                               3250          126855 :     return result;
                               3251                 : }
                               3252                 : 
                               3253                 : /*
                               3254                 :  * isOtherTempNamespace - is the given namespace some other backend's
                               3255                 :  * temporary-table namespace (including temporary-toast-table namespaces)?
                               3256                 :  *
                               3257                 :  * Note: for most purposes in the C code, this function is obsolete.  Use
 5122 tgl                      3258 ECB             :  * RELATION_IS_OTHER_TEMP() instead to detect non-local temp relations.
                               3259                 :  */
                               3260                 : bool
 6460 tgl                      3261 CBC        2588 : isOtherTempNamespace(Oid namespaceId)
 6460 tgl                      3262 EUB             : {
                               3263                 :     /* If it's my own temp namespace, say "false" */
 3149 bruce                    3264 CBC        2588 :     if (isTempOrTempToastNamespace(namespaceId))
 6460 tgl                      3265 UIC           0 :         return false;
                               3266                 :     /* Else, if it's any temp namespace, say "true" */
 6460 tgl                      3267 GIC        2588 :     return isAnyTempNamespace(namespaceId);
                               3268                 : }
                               3269                 : 
                               3270                 : /*
                               3271                 :  * checkTempNamespaceStatus - is the given namespace owned and actively used
                               3272                 :  * by a backend?
                               3273                 :  *
                               3274                 :  * Note: this can be used while scanning relations in pg_class to detect
                               3275                 :  * orphaned temporary tables or namespaces with a backend connected to a
                               3276                 :  * given database.  The result may be out of date quickly, so the caller
 1700 michael                  3277 EUB             :  * must be careful how to handle this information.
                               3278                 :  */
                               3279                 : TempNamespaceStatus
 1136 tgl                      3280 UIC           0 : checkTempNamespaceStatus(Oid namespaceId)
                               3281                 : {
 1700 michael                  3282 EUB             :     PGPROC     *proc;
                               3283                 :     int         backendId;
                               3284                 : 
 1700 michael                  3285 UIC           0 :     Assert(OidIsValid(MyDatabaseId));
                               3286                 : 
 1700 michael                  3287 UBC           0 :     backendId = GetTempNamespaceBackendId(namespaceId);
 1700 michael                  3288 EUB             : 
                               3289                 :     /* No such namespace, or its name shows it's not temp? */
 1180 michael                  3290 UIC           0 :     if (backendId == InvalidBackendId)
 1136 tgl                      3291 UBC           0 :         return TEMP_NAMESPACE_NOT_TEMP;
 1700 michael                  3292 EUB             : 
                               3293                 :     /* Is the backend alive? */
 1700 michael                  3294 UIC           0 :     proc = BackendIdGetProc(backendId);
                               3295               0 :     if (proc == NULL)
 1136 tgl                      3296 UBC           0 :         return TEMP_NAMESPACE_IDLE;
 1700 michael                  3297 EUB             : 
                               3298                 :     /* Is the backend connected to the same database we are looking at? */
 1700 michael                  3299 UIC           0 :     if (proc->databaseId != MyDatabaseId)
 1136 tgl                      3300 UBC           0 :         return TEMP_NAMESPACE_IDLE;
 1700 michael                  3301 EUB             : 
                               3302                 :     /* Does the backend own the temporary namespace? */
 1700 michael                  3303 UIC           0 :     if (proc->tempNamespaceId != namespaceId)
 1136 tgl                      3304 UBC           0 :         return TEMP_NAMESPACE_IDLE;
                               3305                 : 
                               3306                 :     /* Yup, so namespace is busy */
 1136 tgl                      3307 UIC           0 :     return TEMP_NAMESPACE_IN_USE;
                               3308                 : }
                               3309                 : 
                               3310                 : /*
                               3311                 :  * GetTempNamespaceBackendId - if the given namespace is a temporary-table
                               3312                 :  * namespace (either my own, or another backend's), return the BackendId
                               3313                 :  * that owns it.  Temporary-toast-table namespaces are included, too.
 4622 rhaas                    3314 ECB             :  * If it isn't a temp namespace, return InvalidBackendId.
                               3315                 :  */
                               3316                 : int
 5395 tgl                      3317 GIC          17 : GetTempNamespaceBackendId(Oid namespaceId)
                               3318                 : {
                               3319                 :     int         result;
 5395 tgl                      3320 ECB             :     char       *nspname;
                               3321                 : 
 5395 tgl                      3322 EUB             :     /* See if the namespace name starts with "pg_temp_" or "pg_toast_temp_" */
 5395 tgl                      3323 CBC          17 :     nspname = get_namespace_name(namespaceId);
                               3324              17 :     if (!nspname)
 4382 bruce                    3325 UBC           0 :         return InvalidBackendId;    /* no such namespace? */
 5395 tgl                      3326 GBC          17 :     if (strncmp(nspname, "pg_temp_", 8) == 0)
 5395 tgl                      3327 GIC          17 :         result = atoi(nspname + 8);
 5395 tgl                      3328 UBC           0 :     else if (strncmp(nspname, "pg_toast_temp_", 14) == 0)
 5395 tgl                      3329 LBC           0 :         result = atoi(nspname + 14);
 5395 tgl                      3330 ECB             :     else
 4622 rhaas                    3331 UIC           0 :         result = InvalidBackendId;
 5395 tgl                      3332 GIC          17 :     pfree(nspname);
                               3333              17 :     return result;
                               3334                 : }
                               3335                 : 
                               3336                 : /*
                               3337                 :  * GetTempToastNamespace - get the OID of my temporary-toast-table namespace,
                               3338                 :  * which must already be assigned.  (This is only used when creating a toast
 5737 tgl                      3339 ECB             :  * table for a temp table, so we must have already done InitTempTableNamespace)
                               3340                 :  */
                               3341                 : Oid
 5737 tgl                      3342 CBC         430 : GetTempToastNamespace(void)
                               3343                 : {
 5737 tgl                      3344 GIC         430 :     Assert(OidIsValid(myTempToastNamespace));
                               3345             430 :     return myTempToastNamespace;
                               3346                 : }
                               3347                 : 
                               3348                 : 
                               3349                 : /*
                               3350                 :  * GetTempNamespaceState - fetch status of session's temporary namespace
                               3351                 :  *
                               3352                 :  * This is used for conveying state to a parallel worker, and is not meant
 2495 tgl                      3353 ECB             :  * for general-purpose access.
                               3354                 :  */
                               3355                 : void
 2495 tgl                      3356 CBC         403 : GetTempNamespaceState(Oid *tempNamespaceId, Oid *tempToastNamespaceId)
 2495 tgl                      3357 ECB             : {
                               3358                 :     /* Return namespace OIDs, or 0 if session has not created temp namespace */
 2495 tgl                      3359 GIC         403 :     *tempNamespaceId = myTempNamespace;
                               3360             403 :     *tempToastNamespaceId = myTempToastNamespace;
                               3361             403 : }
                               3362                 : 
                               3363                 : /*
                               3364                 :  * SetTempNamespaceState - set status of session's temporary namespace
                               3365                 :  *
                               3366                 :  * This is used for conveying state to a parallel worker, and is not meant for
                               3367                 :  * general-purpose access.  By transferring these namespace OIDs to workers,
                               3368                 :  * we ensure they will have the same notion of the search path as their leader
 2495 tgl                      3369 ECB             :  * does.
                               3370                 :  */
                               3371                 : void
 2495 tgl                      3372 CBC        1298 : SetTempNamespaceState(Oid tempNamespaceId, Oid tempToastNamespaceId)
 2495 tgl                      3373 ECB             : {
                               3374                 :     /* Worker should not have created its own namespaces ... */
 2495 tgl                      3375 GIC        1298 :     Assert(myTempNamespace == InvalidOid);
                               3376            1298 :     Assert(myTempToastNamespace == InvalidOid);
 2495 tgl                      3377 CBC        1298 :     Assert(myTempNamespaceSubID == InvalidSubTransactionId);
 2495 tgl                      3378 ECB             : 
                               3379                 :     /* Assign same namespace OIDs that leader has */
 2495 tgl                      3380 GIC        1298 :     myTempNamespace = tempNamespaceId;
                               3381            1298 :     myTempToastNamespace = tempToastNamespaceId;
                               3382                 : 
                               3383                 :     /*
                               3384                 :      * It's fine to leave myTempNamespaceSubID == InvalidSubTransactionId.
                               3385                 :      * Even if the namespace is new so far as the leader is concerned, it's
                               3386                 :      * not new to the worker, and we certainly wouldn't want the worker trying
 2495 tgl                      3387 ECB             :      * to destroy it.
                               3388                 :      */
                               3389                 : 
 2495 tgl                      3390 GIC        1298 :     baseSearchPathValid = false;    /* may need to rebuild list */
                               3391            1298 : }
                               3392                 : 
                               3393                 : 
                               3394                 : /*
                               3395                 :  * GetOverrideSearchPath - fetch current search path definition in form
                               3396                 :  * used by PushOverrideSearchPath.
                               3397                 :  *
                               3398                 :  * The result structure is allocated in the specified memory context
                               3399                 :  * (which might or might not be equal to CurrentMemoryContext); but any
 5861 tgl                      3400 ECB             :  * junk created by revalidation calculations will be in CurrentMemoryContext.
                               3401                 :  */
                               3402                 : OverrideSearchPath *
 5861 tgl                      3403 GIC       25790 : GetOverrideSearchPath(MemoryContext context)
                               3404                 : {
                               3405                 :     OverrideSearchPath *result;
 5861 tgl                      3406 ECB             :     List       *schemas;
                               3407                 :     MemoryContext oldcxt;
                               3408                 : 
 5861 tgl                      3409 GIC       25790 :     recomputeNamespacePath();
 5861 tgl                      3410 ECB             : 
 5861 tgl                      3411 CBC       25790 :     oldcxt = MemoryContextSwitchTo(context);
 5861 tgl                      3412 ECB             : 
 5861 tgl                      3413 GIC       25790 :     result = (OverrideSearchPath *) palloc0(sizeof(OverrideSearchPath));
 5861 tgl                      3414 CBC       25790 :     schemas = list_copy(activeSearchPath);
                               3415           55165 :     while (schemas && linitial_oid(schemas) != activeCreationNamespace)
                               3416                 :     {
 5861 tgl                      3417 GIC       29375 :         if (linitial_oid(schemas) == myTempNamespace)
 5861 tgl                      3418 CBC        4948 :             result->addTemp = true;
 5861 tgl                      3419 ECB             :         else
                               3420                 :         {
 5861 tgl                      3421 CBC       24427 :             Assert(linitial_oid(schemas) == PG_CATALOG_NAMESPACE);
 5861 tgl                      3422 GIC       24427 :             result->addCatalog = true;
 5861 tgl                      3423 ECB             :         }
 5861 tgl                      3424 CBC       29375 :         schemas = list_delete_first(schemas);
                               3425                 :     }
                               3426           25790 :     result->schemas = schemas;
 1109 tgl                      3427 GIC       25790 :     result->generation = activePathGeneration;
 5861 tgl                      3428 ECB             : 
 5861 tgl                      3429 GIC       25790 :     MemoryContextSwitchTo(oldcxt);
                               3430                 : 
                               3431           25790 :     return result;
                               3432                 : }
                               3433                 : 
                               3434                 : /*
                               3435                 :  * CopyOverrideSearchPath - copy the specified OverrideSearchPath.
                               3436                 :  *
 4223 tgl                      3437 EUB             :  * The result structure is allocated in CurrentMemoryContext.
                               3438                 :  */
                               3439                 : OverrideSearchPath *
 4223 tgl                      3440 UIC           0 : CopyOverrideSearchPath(OverrideSearchPath *path)
 4223 tgl                      3441 EUB             : {
                               3442                 :     OverrideSearchPath *result;
                               3443                 : 
 4223 tgl                      3444 UBC           0 :     result = (OverrideSearchPath *) palloc(sizeof(OverrideSearchPath));
                               3445               0 :     result->schemas = list_copy(path->schemas);
 4223 tgl                      3446 UIC           0 :     result->addCatalog = path->addCatalog;
 4223 tgl                      3447 UBC           0 :     result->addTemp = path->addTemp;
 1109 tgl                      3448 UIC           0 :     result->generation = path->generation;
                               3449                 : 
 4223                          3450               0 :     return result;
                               3451                 : }
                               3452                 : 
                               3453                 : /*
                               3454                 :  * OverrideSearchPathMatchesCurrent - does path match current setting?
                               3455                 :  *
                               3456                 :  * This is tested over and over in some common code paths, and in the typical
                               3457                 :  * scenario where the active search path seldom changes, it'll always succeed.
                               3458                 :  * We make that case fast by keeping a generation counter that is advanced
 1109 tgl                      3459 ECB             :  * whenever the active search path changes.
                               3460                 :  */
                               3461                 : bool
 3726 tgl                      3462 GIC      208943 : OverrideSearchPathMatchesCurrent(OverrideSearchPath *path)
                               3463                 : {
 3054 tgl                      3464 ECB             :     ListCell   *lc,
                               3465                 :                *lcp;
                               3466                 : 
 3054 tgl                      3467 CBC      208943 :     recomputeNamespacePath();
 3054 tgl                      3468 ECB             : 
                               3469                 :     /* Quick out if already known equal to active path. */
 1109 tgl                      3470 GIC      208943 :     if (path->generation == activePathGeneration)
 1109 tgl                      3471 CBC      208843 :         return true;
                               3472                 : 
                               3473                 :     /* We scan down the activeSearchPath to see if it matches the input. */
 3054                          3474             100 :     lc = list_head(activeSearchPath);
                               3475                 : 
 3054 tgl                      3476 ECB             :     /* If path->addTemp, first item should be my temp namespace. */
 3054 tgl                      3477 CBC         100 :     if (path->addTemp)
                               3478                 :     {
 3054 tgl                      3479 GBC           3 :         if (lc && lfirst_oid(lc) == myTempNamespace)
 1364 tgl                      3480 GIC           3 :             lc = lnext(activeSearchPath, lc);
                               3481                 :         else
 3054 tgl                      3482 LBC           0 :             return false;
                               3483                 :     }
 3054 tgl                      3484 ECB             :     /* If path->addCatalog, next item should be pg_catalog. */
 3054 tgl                      3485 CBC         100 :     if (path->addCatalog)
                               3486                 :     {
                               3487             100 :         if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
 1364 tgl                      3488 GIC          30 :             lc = lnext(activeSearchPath, lc);
                               3489                 :         else
 3054 tgl                      3490 CBC          70 :             return false;
 3054 tgl                      3491 EUB             :     }
                               3492                 :     /* We should now be looking at the activeCreationNamespace. */
 3054 tgl                      3493 CBC          30 :     if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
 3054 tgl                      3494 UIC           0 :         return false;
 3054 tgl                      3495 ECB             :     /* The remainder of activeSearchPath should match path->schemas. */
 3054 tgl                      3496 CBC          40 :     foreach(lcp, path->schemas)
                               3497                 :     {
                               3498              30 :         if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
 1364 tgl                      3499 GIC          10 :             lc = lnext(activeSearchPath, lc);
 3054 tgl                      3500 ECB             :         else
 3054 tgl                      3501 GBC          20 :             return false;
                               3502                 :     }
 3054 tgl                      3503 GIC          10 :     if (lc)
 3054 tgl                      3504 UIC           0 :         return false;
                               3505                 : 
                               3506                 :     /*
 1109 tgl                      3507 ECB             :      * Update path->generation so that future tests will return quickly, so
                               3508                 :      * long as the active search path doesn't change.
                               3509                 :      */
 1109 tgl                      3510 GIC          10 :     path->generation = activePathGeneration;
                               3511                 : 
 3054                          3512              10 :     return true;
                               3513                 : }
                               3514                 : 
                               3515                 : /*
                               3516                 :  * PushOverrideSearchPath - temporarily override the search path
                               3517                 :  *
                               3518                 :  * We allow nested overrides, hence the push/pop terminology.  The GUC
                               3519                 :  * search_path variable is ignored while an override is active.
                               3520                 :  *
                               3521                 :  * It's possible that newpath->useTemp is set but there is no longer any
                               3522                 :  * active temp namespace, if the path was saved during a transaction that
                               3523                 :  * created a temp namespace and was later rolled back.  In that case we just
                               3524                 :  * ignore useTemp.  A plausible alternative would be to create a new temp
                               3525                 :  * namespace, but for existing callers that's not necessary because an empty
                               3526                 :  * temp namespace wouldn't affect their results anyway.
                               3527                 :  *
                               3528                 :  * It's also worth noting that other schemas listed in newpath might not
                               3529                 :  * exist anymore either.  We don't worry about this because OIDs that match
 4622 tgl                      3530 ECB             :  * no existing namespace will simply not produce any hits during searches.
                               3531                 :  */
                               3532                 : void
 5624 bruce                    3533 GIC         649 : PushOverrideSearchPath(OverrideSearchPath *newpath)
                               3534                 : {
                               3535                 :     OverrideStackEntry *entry;
                               3536                 :     List       *oidlist;
                               3537                 :     Oid         firstNS;
                               3538                 :     MemoryContext oldcxt;
                               3539                 : 
                               3540                 :     /*
 5861 tgl                      3541 ECB             :      * Copy the list for safekeeping, and insert implicitly-searched
                               3542                 :      * namespaces as needed.  This code should track recomputeNamespacePath.
                               3543                 :      */
 5861 tgl                      3544 GIC         649 :     oldcxt = MemoryContextSwitchTo(TopMemoryContext);
                               3545                 : 
                               3546             649 :     oidlist = list_copy(newpath->schemas);
                               3547                 : 
 5861 tgl                      3548 ECB             :     /*
 5861 tgl                      3549 EUB             :      * Remember the first member of the explicit list.
                               3550                 :      */
 5861 tgl                      3551 CBC         649 :     if (oidlist == NIL)
 5861 tgl                      3552 UIC           0 :         firstNS = InvalidOid;
                               3553                 :     else
 5861 tgl                      3554 GIC         649 :         firstNS = linitial_oid(oidlist);
                               3555                 : 
                               3556                 :     /*
                               3557                 :      * Add any implicitly-searched namespaces to the list.  Note these go on
 5861 tgl                      3558 ECB             :      * the front, not the back; also notice that we do not check USAGE
                               3559                 :      * permissions for these.
                               3560                 :      */
 5861 tgl                      3561 CBC         649 :     if (newpath->addCatalog)
                               3562             346 :         oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
                               3563                 : 
 4622 tgl                      3564 GIC         649 :     if (newpath->addTemp && OidIsValid(myTempNamespace))
 5861                          3565             120 :         oidlist = lcons_oid(myTempNamespace, oidlist);
                               3566                 : 
 5861 tgl                      3567 ECB             :     /*
                               3568                 :      * Build the new stack entry, then insert it at the head of the list.
                               3569                 :      */
 5861 tgl                      3570 CBC         649 :     entry = (OverrideStackEntry *) palloc(sizeof(OverrideStackEntry));
 5861 tgl                      3571 GIC         649 :     entry->searchPath = oidlist;
 5861 tgl                      3572 CBC         649 :     entry->creationNamespace = firstNS;
 5861 tgl                      3573 GIC         649 :     entry->nestLevel = GetCurrentTransactionNestLevel();
                               3574                 : 
 5861 tgl                      3575 CBC         649 :     overrideStack = lcons(entry, overrideStack);
 5861 tgl                      3576 ECB             : 
                               3577                 :     /* And make it active. */
 5861 tgl                      3578 GIC         649 :     activeSearchPath = entry->searchPath;
                               3579             649 :     activeCreationNamespace = entry->creationNamespace;
 5624 bruce                    3580             649 :     activeTempCreationPending = false;  /* XXX is this OK? */
                               3581                 : 
                               3582                 :     /*
                               3583                 :      * We always increment activePathGeneration when pushing/popping an
                               3584                 :      * override path.  In current usage, these actions always change the
 1109 tgl                      3585 ECB             :      * effective path state, so there's no value in checking to see if it
                               3586                 :      * didn't change.
                               3587                 :      */
 1109 tgl                      3588 CBC         649 :     activePathGeneration++;
                               3589                 : 
 5861 tgl                      3590 GIC         649 :     MemoryContextSwitchTo(oldcxt);
 7632                          3591             649 : }
                               3592                 : 
                               3593                 : /*
                               3594                 :  * PopOverrideSearchPath - undo a previous PushOverrideSearchPath
                               3595                 :  *
                               3596                 :  * Any push during a (sub)transaction will be popped automatically at abort.
 5861 tgl                      3597 ECB             :  * But it's caller error if a push isn't popped in normal control flow.
                               3598                 :  */
                               3599                 : void
 5861 tgl                      3600 GIC         646 : PopOverrideSearchPath(void)
                               3601                 : {
 5861 tgl                      3602 ECB             :     OverrideStackEntry *entry;
 5861 tgl                      3603 EUB             : 
 5861 tgl                      3604 ECB             :     /* Sanity checks. */
 5861 tgl                      3605 CBC         646 :     if (overrideStack == NIL)
 5861 tgl                      3606 UBC           0 :         elog(ERROR, "bogus PopOverrideSearchPath call");
 5861 tgl                      3607 GIC         646 :     entry = (OverrideStackEntry *) linitial(overrideStack);
                               3608             646 :     if (entry->nestLevel != GetCurrentTransactionNestLevel())
 5861 tgl                      3609 LBC           0 :         elog(ERROR, "bogus PopOverrideSearchPath call");
 5861 tgl                      3610 ECB             : 
                               3611                 :     /* Pop the stack and free storage. */
 5861 tgl                      3612 GIC         646 :     overrideStack = list_delete_first(overrideStack);
                               3613             646 :     list_free(entry->searchPath);
 5861 tgl                      3614 CBC         646 :     pfree(entry);
                               3615                 : 
 5861 tgl                      3616 EUB             :     /* Activate the next level down. */
 5861 tgl                      3617 GBC         646 :     if (overrideStack)
 5861 tgl                      3618 EUB             :     {
 5861 tgl                      3619 UBC           0 :         entry = (OverrideStackEntry *) linitial(overrideStack);
 5861 tgl                      3620 UIC           0 :         activeSearchPath = entry->searchPath;
                               3621               0 :         activeCreationNamespace = entry->creationNamespace;
 2118                          3622               0 :         activeTempCreationPending = false;  /* XXX is this OK? */
                               3623                 :     }
 5861 tgl                      3624 ECB             :     else
                               3625                 :     {
                               3626                 :         /* If not baseSearchPathValid, this is useless but harmless */
 5861 tgl                      3627 GIC         646 :         activeSearchPath = baseSearchPath;
                               3628             646 :         activeCreationNamespace = baseCreationNamespace;
 5833                          3629             646 :         activeTempCreationPending = baseTempCreationPending;
 5861 tgl                      3630 ECB             :     }
 1109                          3631                 : 
                               3632                 :     /* As above, the generation always increments. */
 1109 tgl                      3633 GIC         646 :     activePathGeneration++;
 7632                          3634             646 : }
                               3635                 : 
                               3636                 : 
                               3637                 : /*
                               3638                 :  * get_collation_oid - find a collation by possibly qualified name
                               3639                 :  *
                               3640                 :  * Note that this will only find collations that work with the current
 2115 tgl                      3641 ECB             :  * database's encoding.
                               3642                 :  */
                               3643                 : Oid
  202 pg                       3644 GNC        5061 : get_collation_oid(List *collname, bool missing_ok)
 4443 peter_e                  3645 ECB             : {
                               3646                 :     char       *schemaname;
                               3647                 :     char       *collation_name;
 4412 tgl                      3648 GIC        5061 :     int32       dbencoding = GetDatabaseEncoding();
                               3649                 :     Oid         namespaceId;
                               3650                 :     Oid         colloid;
 4443 peter_e                  3651 ECB             :     ListCell   *l;
                               3652                 : 
                               3653                 :     /* deconstruct the name list */
  202 pg                       3654 GNC        5061 :     DeconstructQualifiedName(collname, &schemaname, &collation_name);
                               3655                 : 
 4443 peter_e                  3656 CBC        5061 :     if (schemaname)
 4443 peter_e                  3657 ECB             :     {
                               3658                 :         /* use exact schema given */
 3725 bruce                    3659 GIC        2948 :         namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
 3725 bruce                    3660 CBC        2948 :         if (missing_ok && !OidIsValid(namespaceId))
                               3661              12 :             return InvalidOid;
 4412 tgl                      3662 ECB             : 
 2115 tgl                      3663 GIC        2936 :         colloid = lookup_collation(collation_name, namespaceId, dbencoding);
 4412                          3664            2936 :         if (OidIsValid(colloid))
                               3665            2936 :             return colloid;
                               3666                 :     }
 4443 peter_e                  3667 ECB             :     else
                               3668                 :     {
                               3669                 :         /* search for it in search path */
 4443 peter_e                  3670 GIC        2113 :         recomputeNamespacePath();
 4443 peter_e                  3671 ECB             : 
 4443 peter_e                  3672 GIC        2909 :         foreach(l, activeSearchPath)
 4443 peter_e                  3673 ECB             :         {
 4443 peter_e                  3674 CBC        2866 :             namespaceId = lfirst_oid(l);
                               3675                 : 
                               3676            2866 :             if (namespaceId == myTempNamespace)
                               3677             314 :                 continue;       /* do not look in temp namespace */
 4443 peter_e                  3678 ECB             : 
 2115 tgl                      3679 GIC        2552 :             colloid = lookup_collation(collation_name, namespaceId, dbencoding);
 4443 peter_e                  3680            2552 :             if (OidIsValid(colloid))
                               3681            2070 :                 return colloid;
                               3682                 :         }
 4443 peter_e                  3683 ECB             :     }
                               3684                 : 
                               3685                 :     /* Not found in path */
 4412 tgl                      3686 GIC          43 :     if (!missing_ok)
 4443 peter_e                  3687              31 :         ereport(ERROR,
 4443 peter_e                  3688 ECB             :                 (errcode(ERRCODE_UNDEFINED_OBJECT),
                               3689                 :                  errmsg("collation \"%s\" for encoding \"%s\" does not exist",
                               3690                 :                         NameListToString(collname), GetDatabaseEncodingName())));
 4412 tgl                      3691 GIC          12 :     return InvalidOid;
                               3692                 : }
                               3693                 : 
                               3694                 : /*
 4630 rhaas                    3695 ECB             :  * get_conversion_oid - find a conversion by possibly qualified name
                               3696                 :  */
                               3697                 : Oid
  202 pg                       3698 GNC          93 : get_conversion_oid(List *conname, bool missing_ok)
                               3699                 : {
 7463 tgl                      3700 ECB             :     char       *schemaname;
                               3701                 :     char       *conversion_name;
                               3702                 :     Oid         namespaceId;
 4630 rhaas                    3703 GIC          93 :     Oid         conoid = InvalidOid;
 6892 neilc                    3704 ECB             :     ListCell   *l;
                               3705                 : 
 7463 tgl                      3706                 :     /* deconstruct the name list */
  202 pg                       3707 GNC          93 :     DeconstructQualifiedName(conname, &schemaname, &conversion_name);
                               3708                 : 
 7463 tgl                      3709 CBC          87 :     if (schemaname)
 7551 ishii                    3710 ECB             :     {
 7463 tgl                      3711                 :         /* use exact schema given */
 3725 bruce                    3712 GIC          19 :         namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
 3725 bruce                    3713 CBC          19 :         if (missing_ok && !OidIsValid(namespaceId))
 3725 bruce                    3714 GIC           3 :             conoid = InvalidOid;
                               3715                 :         else
 1601 andres                   3716              16 :             conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
                               3717                 :                                      PointerGetDatum(conversion_name),
                               3718                 :                                      ObjectIdGetDatum(namespaceId));
                               3719                 :     }
 7463 tgl                      3720 ECB             :     else
                               3721                 :     {
                               3722                 :         /* search for it in search path */
 7463 tgl                      3723 GIC          68 :         recomputeNamespacePath();
 7551 ishii                    3724 ECB             : 
 5861 tgl                      3725 GIC         151 :         foreach(l, activeSearchPath)
 7463 tgl                      3726 ECB             :         {
 6892 neilc                    3727 GBC         136 :             namespaceId = lfirst_oid(l);
                               3728                 : 
 5833 tgl                      3729 CBC         136 :             if (namespaceId == myTempNamespace)
 5624 bruce                    3730 UIC           0 :                 continue;       /* do not look in temp namespace */
                               3731                 : 
 1601 andres                   3732 CBC         136 :             conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid,
 4802 rhaas                    3733 ECB             :                                      PointerGetDatum(conversion_name),
                               3734                 :                                      ObjectIdGetDatum(namespaceId));
 7463 tgl                      3735 GIC         136 :             if (OidIsValid(conoid))
                               3736              53 :                 return conoid;
                               3737                 :         }
 7551 ishii                    3738 ECB             :     }
                               3739                 : 
                               3740                 :     /* Not found in path */
 4630 rhaas                    3741 GIC          34 :     if (!OidIsValid(conoid) && !missing_ok)
                               3742              18 :         ereport(ERROR,
 4630 rhaas                    3743 ECB             :                 (errcode(ERRCODE_UNDEFINED_OBJECT),
                               3744                 :                  errmsg("conversion \"%s\" does not exist",
                               3745                 :                         NameListToString(conname))));
 4630 rhaas                    3746 GIC          16 :     return conoid;
                               3747                 : }
                               3748                 : 
                               3749                 : /*
 7463 tgl                      3750 ECB             :  * FindDefaultConversionProc - find default encoding conversion proc
                               3751                 :  */
                               3752                 : Oid
 3940 peter_e                  3753 GIC        3458 : FindDefaultConversionProc(int32 for_encoding, int32 to_encoding)
                               3754                 : {
 7572 ishii                    3755 ECB             :     Oid         proc;
                               3756                 :     ListCell   *l;
                               3757                 : 
 7572 ishii                    3758 GIC        3458 :     recomputeNamespacePath();
 7572 ishii                    3759 ECB             : 
 5861 tgl                      3760 GIC        3458 :     foreach(l, activeSearchPath)
 7572 ishii                    3761 ECB             :     {
 6892 neilc                    3762 GBC        3458 :         Oid         namespaceId = lfirst_oid(l);
                               3763                 : 
 5833 tgl                      3764 CBC        3458 :         if (namespaceId == myTempNamespace)
 5833 tgl                      3765 LBC           0 :             continue;           /* do not look in temp namespace */
 5833 tgl                      3766 ECB             : 
 7572 ishii                    3767 GIC        3458 :         proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
                               3768            3458 :         if (OidIsValid(proc))
                               3769            3458 :             return proc;
 7572 ishii                    3770 EUB             :     }
                               3771                 : 
                               3772                 :     /* Not found in path */
 7572 ishii                    3773 UIC           0 :     return InvalidOid;
                               3774                 : }
                               3775                 : 
                               3776                 : /*
 7650 tgl                      3777 ECB             :  * recomputeNamespacePath - recompute path derived variables if needed.
                               3778                 :  */
                               3779                 : static void
 7650 tgl                      3780 GIC     2637267 : recomputeNamespacePath(void)
                               3781                 : {
 6385 bruce                    3782         2637267 :     Oid         roleid = GetUserId();
                               3783                 :     char       *rawname;
                               3784                 :     List       *namelist;
                               3785                 :     List       *oidlist;
                               3786                 :     List       *newpath;
                               3787                 :     ListCell   *l;
                               3788                 :     bool        temp_missing;
                               3789                 :     Oid         firstNS;
                               3790                 :     bool        pathChanged;
 7650 tgl                      3791 ECB             :     MemoryContext oldcxt;
                               3792                 : 
                               3793                 :     /* Do nothing if an override search spec is active. */
 5861 tgl                      3794 GIC     2637267 :     if (overrideStack)
 5861 tgl                      3795 CBC     2622694 :         return;
 5861 tgl                      3796 ECB             : 
                               3797                 :     /* Do nothing if path is already valid. */
 5861 tgl                      3798 GIC     2637149 :     if (baseSearchPathValid && namespaceUser == roleid)
 7650 tgl                      3799 CBC     2622576 :         return;
                               3800                 : 
                               3801                 :     /* Need a modifiable copy of namespace_search_path string */
                               3802           14573 :     rawname = pstrdup(namespace_search_path);
                               3803                 : 
                               3804                 :     /* Parse string into list of identifiers */
 7650 tgl                      3805 GIC       14573 :     if (!SplitIdentifierString(rawname, ',', &namelist))
 7650 tgl                      3806 EUB             :     {
                               3807                 :         /* syntax error in name list */
                               3808                 :         /* this should not happen if GUC checked check_search_path */
 7202 tgl                      3809 UIC           0 :         elog(ERROR, "invalid list syntax");
                               3810                 :     }
                               3811                 : 
                               3812                 :     /*
                               3813                 :      * Convert the list of names to a list of OIDs.  If any names are not
                               3814                 :      * recognizable or we don't have read access, just leave them out of the
 6385 bruce                    3815 ECB             :      * list.  (We can't raise an error, since the search_path setting has
                               3816                 :      * already been accepted.)  Don't make duplicate entries, either.
 7650 tgl                      3817                 :      */
 7650 tgl                      3818 GIC       14573 :     oidlist = NIL;
 5833 tgl                      3819 CBC       14573 :     temp_missing = false;
 7650 tgl                      3820 GIC       39789 :     foreach(l, namelist)
                               3821                 :     {
 7522 bruce                    3822 CBC       25216 :         char       *curname = (char *) lfirst(l);
                               3823                 :         Oid         namespaceId;
                               3824                 : 
 7650 tgl                      3825 GIC       25216 :         if (strcmp(curname, "$user") == 0)
                               3826                 :         {
 7650 tgl                      3827 ECB             :             /* $user --- substitute namespace matching user name, if any */
                               3828                 :             HeapTuple   tuple;
                               3829                 : 
 4802 rhaas                    3830 GIC       10426 :             tuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
 7650 tgl                      3831           10426 :             if (HeapTupleIsValid(tuple))
 7650 tgl                      3832 ECB             :             {
 6494                          3833                 :                 char       *rname;
 7650                          3834                 : 
 6494 tgl                      3835 CBC       10426 :                 rname = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname);
 4630 rhaas                    3836 GBC       10426 :                 namespaceId = get_namespace_oid(rname, true);
 7650 tgl                      3837           10426 :                 ReleaseSysCache(tuple);
                               3838           10426 :                 if (OidIsValid(namespaceId) &&
 6892 neilc                    3839 UBC           0 :                     !list_member_oid(oidlist, namespaceId) &&
  147 peter                    3840 UNC           0 :                     object_aclcheck(NamespaceRelationId, namespaceId, roleid,
 3656 rhaas                    3841 UIC           0 :                                           ACL_USAGE) == ACLCHECK_OK &&
                               3842               0 :                     InvokeNamespaceSearchHook(namespaceId, false))
 6892 neilc                    3843 LBC           0 :                     oidlist = lappend_oid(oidlist, namespaceId);
                               3844                 :             }
                               3845                 :         }
 5833 tgl                      3846 CBC       14790 :         else if (strcmp(curname, "pg_temp") == 0)
                               3847                 :         {
 5833 tgl                      3848 ECB             :             /* pg_temp --- substitute temp namespace, if any */
 5833 tgl                      3849 CBC         649 :             if (OidIsValid(myTempNamespace))
 5833 tgl                      3850 ECB             :             {
 3656 rhaas                    3851 GIC          37 :                 if (!list_member_oid(oidlist, myTempNamespace) &&
                               3852              37 :                     InvokeNamespaceSearchHook(myTempNamespace, false))
 5833 tgl                      3853              37 :                     oidlist = lappend_oid(oidlist, myTempNamespace);
                               3854                 :             }
 5833 tgl                      3855 ECB             :             else
                               3856                 :             {
                               3857                 :                 /* If it ought to be the creation namespace, set flag */
 5833 tgl                      3858 GIC         612 :                 if (oidlist == NIL)
                               3859               3 :                     temp_missing = true;
                               3860                 :             }
                               3861                 :         }
 7650 tgl                      3862 ECB             :         else
                               3863                 :         {
                               3864                 :             /* normal namespace reference */
 4630 rhaas                    3865 CBC       14141 :             namespaceId = get_namespace_oid(curname, true);
 7650 tgl                      3866           14141 :             if (OidIsValid(namespaceId) &&
 6892 neilc                    3867           28209 :                 !list_member_oid(oidlist, namespaceId) &&
  147 peter                    3868 GNC       14101 :                 object_aclcheck(NamespaceRelationId, namespaceId, roleid,
 3656 rhaas                    3869 GIC           3 :                                       ACL_USAGE) == ACLCHECK_OK &&
                               3870           14098 :                 InvokeNamespaceSearchHook(namespaceId, false))
 6892 neilc                    3871           14098 :                 oidlist = lappend_oid(oidlist, namespaceId);
                               3872                 :         }
                               3873                 :     }
                               3874                 : 
                               3875                 :     /*
                               3876                 :      * Remember the first member of the explicit list.  (Note: this is
 5833 tgl                      3877 ECB             :      * nominally wrong if temp_missing, but we need it anyway to distinguish
                               3878                 :      * explicit from implicit mention of pg_catalog.)
                               3879                 :      */
 7632 tgl                      3880 CBC       14573 :     if (oidlist == NIL)
 7632 tgl                      3881 GIC         630 :         firstNS = InvalidOid;
                               3882                 :     else
 6892 neilc                    3883           13943 :         firstNS = linitial_oid(oidlist);
                               3884                 : 
                               3885                 :     /*
                               3886                 :      * Add any implicitly-searched namespaces to the list.  Note these go on
 6385 bruce                    3887 ECB             :      * the front, not the back; also notice that we do not check USAGE
 7522                          3888                 :      * permissions for these.
                               3889                 :      */
 6892 neilc                    3890 CBC       14573 :     if (!list_member_oid(oidlist, PG_CATALOG_NAMESPACE))
                               3891           12938 :         oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
 7632 tgl                      3892 ECB             : 
 7632 tgl                      3893 GIC       14573 :     if (OidIsValid(myTempNamespace) &&
 6892 neilc                    3894            1373 :         !list_member_oid(oidlist, myTempNamespace))
                               3895            1336 :         oidlist = lcons_oid(myTempNamespace, oidlist);
                               3896                 : 
                               3897                 :     /*
                               3898                 :      * We want to detect the case where the effective value of the base search
 1109 tgl                      3899 ECB             :      * path variables didn't change.  As long as we're doing so, we can avoid
  888 michael                  3900                 :      * copying the OID list unnecessarily.
 7650 tgl                      3901                 :      */
 1109 tgl                      3902 GIC       14573 :     if (baseCreationNamespace == firstNS &&
 1109 tgl                      3903 CBC       14045 :         baseTempCreationPending == temp_missing &&
 1109 tgl                      3904 GIC        7021 :         equal(oidlist, baseSearchPath))
                               3905                 :     {
                               3906            6141 :         pathChanged = false;
 1109 tgl                      3907 ECB             :     }
                               3908                 :     else
                               3909                 :     {
 1109 tgl                      3910 CBC        8432 :         pathChanged = true;
 1109 tgl                      3911 ECB             : 
                               3912                 :         /* Must save OID list in permanent storage. */
 1109 tgl                      3913 GIC        8432 :         oldcxt = MemoryContextSwitchTo(TopMemoryContext);
                               3914            8432 :         newpath = list_copy(oidlist);
 1109 tgl                      3915 CBC        8432 :         MemoryContextSwitchTo(oldcxt);
 7650 tgl                      3916 ECB             : 
 1109                          3917                 :         /* Now safe to assign to state variables. */
 1109 tgl                      3918 CBC        8432 :         list_free(baseSearchPath);
 1109 tgl                      3919 GIC        8432 :         baseSearchPath = newpath;
                               3920            8432 :         baseCreationNamespace = firstNS;
                               3921            8432 :         baseTempCreationPending = temp_missing;
 1109 tgl                      3922 ECB             :     }
 7650                          3923                 : 
                               3924                 :     /* Mark the path valid. */
 5861 tgl                      3925 GIC       14573 :     baseSearchPathValid = true;
 6494 tgl                      3926 CBC       14573 :     namespaceUser = roleid;
 7650 tgl                      3927 ECB             : 
 5861                          3928                 :     /* And make it active. */
 5861 tgl                      3929 GIC       14573 :     activeSearchPath = baseSearchPath;
                               3930           14573 :     activeCreationNamespace = baseCreationNamespace;
 5833                          3931           14573 :     activeTempCreationPending = baseTempCreationPending;
                               3932                 : 
                               3933                 :     /*
                               3934                 :      * Bump the generation only if something actually changed.  (Notice that
                               3935                 :      * what we compared to was the old state of the base path variables; so
                               3936                 :      * this does not deal with the situation where we have just popped an
 1109 tgl                      3937 ECB             :      * override path and restored the prior state of the base path.  Instead
                               3938                 :      * we rely on the override-popping logic to have bumped the generation.)
                               3939                 :      */
 1109 tgl                      3940 GIC       14573 :     if (pathChanged)
 1109 tgl                      3941 CBC        8432 :         activePathGeneration++;
 1109 tgl                      3942 ECB             : 
 7650                          3943                 :     /* Clean up. */
 7650 tgl                      3944 GIC       14573 :     pfree(rawname);
 6892 neilc                    3945           14573 :     list_free(namelist);
                               3946           14573 :     list_free(oidlist);
                               3947                 : }
                               3948                 : 
                               3949                 : /*
                               3950                 :  * AccessTempTableNamespace
                               3951                 :  *      Provide access to a temporary namespace, potentially creating it
                               3952                 :  *      if not present yet.  This routine registers if the namespace gets
                               3953                 :  *      in use in this transaction.  'force' can be set to true to allow
                               3954                 :  *      the caller to enforce the creation of the temporary namespace for
 1542 michael                  3955 ECB             :  *      use in this backend, which happens if its creation is pending.
                               3956                 :  */
                               3957                 : static void
 1542 michael                  3958 GIC        3181 : AccessTempTableNamespace(bool force)
                               3959                 : {
                               3960                 :     /*
 1542 michael                  3961 ECB             :      * Make note that this temporary namespace has been accessed in this
                               3962                 :      * transaction.
                               3963                 :      */
 1542 michael                  3964 GIC        3181 :     MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPNAMESPACE;
                               3965                 : 
                               3966                 :     /*
                               3967                 :      * If the caller attempting to access a temporary schema expects the
 1542 michael                  3968 ECB             :      * creation of the namespace to be pending and should be enforced, then go
                               3969                 :      * through the creation.
                               3970                 :      */
 1542 michael                  3971 GIC        3181 :     if (!force && OidIsValid(myTempNamespace))
                               3972            2897 :         return;
                               3973                 : 
                               3974                 :     /*
 1542 michael                  3975 ECB             :      * The temporary tablespace does not exist yet and is wanted, so
                               3976                 :      * initialize it.
                               3977                 :      */
 1542 michael                  3978 GIC         284 :     InitTempTableNamespace();
                               3979                 : }
                               3980                 : 
                               3981                 : /*
                               3982                 :  * InitTempTableNamespace
 7679 tgl                      3983 ECB             :  *      Initialize temp table namespace on first use in a particular backend
                               3984                 :  */
                               3985                 : static void
 7632 tgl                      3986 GIC         284 : InitTempTableNamespace(void)
                               3987                 : {
                               3988                 :     char        namespaceName[NAMEDATALEN];
 7679 tgl                      3989 ECB             :     Oid         namespaceId;
                               3990                 :     Oid         toastspaceId;
                               3991                 : 
 5833 tgl                      3992 GIC         284 :     Assert(!OidIsValid(myTempNamespace));
                               3993                 : 
                               3994                 :     /*
                               3995                 :      * First, do permission check to see if we are authorized to make temp
                               3996                 :      * tables.  We use a nonstandard error message here since "databasename:
                               3997                 :      * permission denied" might be a tad cryptic.
                               3998                 :      *
                               3999                 :      * Note that ACL_CREATE_TEMP rights are rechecked in pg_namespace_aclmask;
                               4000                 :      * that's necessary since current user ID could change during the session.
 6385 bruce                    4001 ECB             :      * But there's no need to make the namespace in the first place until a
                               4002                 :      * temp table creation request is made by someone with appropriate rights.
 7652 tgl                      4003 EUB             :      */
  147 peter                    4004 GNC         284 :     if (object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(),
                               4005                 :                              ACL_CREATE_TEMP) != ACLCHECK_OK)
 7202 tgl                      4006 UIC           0 :         ereport(ERROR,
                               4007                 :                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                               4008                 :                  errmsg("permission denied to create temporary tables in database \"%s\"",
                               4009                 :                         get_database_name(MyDatabaseId))));
                               4010                 : 
                               4011                 :     /*
                               4012                 :      * Do not allow a Hot Standby session to make temp tables.  Aside from
                               4013                 :      * problems with modifying the system catalogs, there is a naming
                               4014                 :      * conflict: pg_temp_N belongs to the session with BackendId N on the
                               4015                 :      * primary, not to a hot standby session with the same BackendId.  We
                               4016                 :      * should not be able to get here anyway due to XactReadOnly checks, but
                               4017                 :      * let's just make real sure.  Note that this also backstops various
 2064 tgl                      4018 ECB             :      * operations that allow XactReadOnly transactions to modify temp tables;
 2064 tgl                      4019 EUB             :      * they'd need RecoveryInProgress checks if not for this.
                               4020                 :      */
 4796 tgl                      4021 GIC         284 :     if (RecoveryInProgress())
 4796 tgl                      4022 UIC           0 :         ereport(ERROR,
                               4023                 :                 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
 4796 tgl                      4024 ECB             :                  errmsg("cannot create temporary tables during recovery")));
 4796 tgl                      4025 EUB             : 
                               4026                 :     /* Parallel workers can't create temporary tables, either. */
 2901 rhaas                    4027 GIC         284 :     if (IsParallelWorker())
 2901 rhaas                    4028 UIC           0 :         ereport(ERROR,
 2901 rhaas                    4029 ECB             :                 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
                               4030                 :                  errmsg("cannot create temporary tables during a parallel operation")));
                               4031                 : 
 7325 bruce                    4032 CBC         284 :     snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
                               4033                 : 
 4630 rhaas                    4034 GIC         284 :     namespaceId = get_namespace_oid(namespaceName, true);
 7679 tgl                      4035             284 :     if (!OidIsValid(namespaceId))
                               4036                 :     {
                               4037                 :         /*
                               4038                 :          * First use of this temp namespace in this database; create it. The
                               4039                 :          * temp namespaces are always owned by the superuser.  We leave their
                               4040                 :          * permissions at default --- i.e., no access except to superuser ---
                               4041                 :          * to ensure that unprivileged users can't peek at other backends'
 6385 bruce                    4042 ECB             :          * temp tables.  This works because the places that access the temp
                               4043                 :          * namespace for my own backend skip permissions checks on it.
                               4044                 :          */
 4049 tgl                      4045 CBC          85 :         namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
                               4046                 :                                       true);
                               4047                 :         /* Advance command counter to make namespace visible */
 7679 tgl                      4048 GIC          85 :         CommandCounterIncrement();
                               4049                 :     }
                               4050                 :     else
                               4051                 :     {
                               4052                 :         /*
 6385 bruce                    4053 ECB             :          * If the namespace already exists, clean it out (in case the former
                               4054                 :          * owner crashed without doing so).
                               4055                 :          */
 7679 tgl                      4056 GIC         199 :         RemoveTempRelations(namespaceId);
                               4057                 :     }
                               4058                 : 
                               4059                 :     /*
                               4060                 :      * If the corresponding toast-table namespace doesn't exist yet, create
 5050 bruce                    4061 ECB             :      * it. (We assume there is no need to clean it out if it does exist, since
                               4062                 :      * dropping a parent table should make its toast table go away.)
                               4063                 :      */
 5737 tgl                      4064 CBC         284 :     snprintf(namespaceName, sizeof(namespaceName), "pg_toast_temp_%d",
 5737 tgl                      4065 ECB             :              MyBackendId);
                               4066                 : 
 4630 rhaas                    4067 CBC         284 :     toastspaceId = get_namespace_oid(namespaceName, true);
 5737 tgl                      4068 GIC         284 :     if (!OidIsValid(toastspaceId))
                               4069                 :     {
 4049 tgl                      4070 CBC          85 :         toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
                               4071                 :                                        true);
                               4072                 :         /* Advance command counter to make namespace visible */
 5737 tgl                      4073 GIC          85 :         CommandCounterIncrement();
                               4074                 :     }
                               4075                 : 
                               4076                 :     /*
                               4077                 :      * Okay, we've prepared the temp namespace ... but it's not committed yet,
 6385 bruce                    4078 ECB             :      * so all our work could be undone by transaction rollback.  Set flag for
                               4079                 :      * AtEOXact_Namespace to know what to do.
                               4080                 :      */
 7632 tgl                      4081 GIC         284 :     myTempNamespace = namespaceId;
 5737                          4082             284 :     myTempToastNamespace = toastspaceId;
                               4083                 : 
                               4084                 :     /*
                               4085                 :      * Mark MyProc as owning this namespace which other processes can use to
                               4086                 :      * decide if a temporary namespace is in use or not.  We assume that
                               4087                 :      * assignment of namespaceId is an atomic operation.  Even if it is not,
                               4088                 :      * the temporary relation which resulted in the creation of this temporary
                               4089                 :      * namespace is still locked until the current transaction commits, and
                               4090                 :      * its pg_namespace row is not visible yet.  However it does not matter:
 1692 michael                  4091 ECB             :      * this flag makes the namespace as being in use, so no objects created on
                               4092                 :      * it would be removed concurrently.
                               4093                 :      */
 1700 michael                  4094 CBC         284 :     MyProc->tempNamespaceId = namespaceId;
 1700 michael                  4095 ECB             : 
                               4096                 :     /* It should not be done already. */
  163 peter                    4097 GNC         284 :     Assert(myTempNamespaceSubID == InvalidSubTransactionId);
 6779 tgl                      4098 CBC         284 :     myTempNamespaceSubID = GetCurrentSubTransactionId();
                               4099                 : 
 5861 tgl                      4100 GIC         284 :     baseSearchPathValid = false;    /* need to rebuild list */
 7632                          4101             284 : }
                               4102                 : 
                               4103                 : /*
 7632 tgl                      4104 ECB             :  * End-of-transaction cleanup for namespaces.
                               4105                 :  */
                               4106                 : void
 2901 rhaas                    4107 GIC      485429 : AtEOXact_Namespace(bool isCommit, bool parallel)
                               4108                 : {
                               4109                 :     /*
                               4110                 :      * If we abort the transaction in which a temp namespace was selected,
                               4111                 :      * we'll have to do any creation or cleanout work over again.  So, just
                               4112                 :      * forget the namespace entirely until next time.  On the other hand, if
                               4113                 :      * we commit then register an exit callback to clean out the temp tables
 6385 bruce                    4114 ECB             :      * at backend shutdown.  (We only want to register the callback once per
                               4115                 :      * session, so this is a good place to do it.)
 7632 tgl                      4116                 :      */
 2901 rhaas                    4117 CBC      485429 :     if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
                               4118                 :     {
 7632 tgl                      4119 GIC         283 :         if (isCommit)
 3399 rhaas                    4120 CBC         273 :             before_shmem_exit(RemoveTempRelationsCallback, 0);
 7632 tgl                      4121 ECB             :         else
                               4122                 :         {
 7632 tgl                      4123 GIC          10 :             myTempNamespace = InvalidOid;
 5737                          4124              10 :             myTempToastNamespace = InvalidOid;
 2118                          4125              10 :             baseSearchPathValid = false;    /* need to rebuild list */
                               4126                 : 
                               4127                 :             /*
                               4128                 :              * Reset the temporary namespace flag in MyProc.  We assume that
                               4129                 :              * this operation is atomic.
                               4130                 :              *
                               4131                 :              * Because this transaction is aborting, the pg_namespace row is
                               4132                 :              * not visible to anyone else anyway, but that doesn't matter:
 1692 michael                  4133 ECB             :              * it's not a problem if objects contained in this namespace are
                               4134                 :              * removed concurrently.
 1700                          4135                 :              */
 1700 michael                  4136 GIC          10 :             MyProc->tempNamespaceId = InvalidOid;
                               4137                 :         }
 6779 tgl                      4138             283 :         myTempNamespaceSubID = InvalidSubTransactionId;
                               4139                 :     }
                               4140                 : 
 7632 tgl                      4141 ECB             :     /*
                               4142                 :      * Clean up if someone failed to do PopOverrideSearchPath
                               4143                 :      */
 5861 tgl                      4144 GBC      485429 :     if (overrideStack)
 7632 tgl                      4145 ECB             :     {
 5861 tgl                      4146 GIC           3 :         if (isCommit)
 5861 tgl                      4147 UIC           0 :             elog(WARNING, "leaked override search path");
 5861 tgl                      4148 GIC           6 :         while (overrideStack)
 5861 tgl                      4149 ECB             :         {
                               4150                 :             OverrideStackEntry *entry;
                               4151                 : 
 5861 tgl                      4152 CBC           3 :             entry = (OverrideStackEntry *) linitial(overrideStack);
 5861 tgl                      4153 GIC           3 :             overrideStack = list_delete_first(overrideStack);
                               4154               3 :             list_free(entry->searchPath);
 5861 tgl                      4155 CBC           3 :             pfree(entry);
 5861 tgl                      4156 ECB             :         }
                               4157                 :         /* If not baseSearchPathValid, this is useless but harmless */
 5861 tgl                      4158 GIC           3 :         activeSearchPath = baseSearchPath;
 5861 tgl                      4159 CBC           3 :         activeCreationNamespace = baseCreationNamespace;
 5833 tgl                      4160 GIC           3 :         activeTempCreationPending = baseTempCreationPending;
 1109 tgl                      4161 ECB             :         /* Always bump generation --- see note in recomputeNamespacePath */
 1109 tgl                      4162 GIC           3 :         activePathGeneration++;
                               4163                 :     }
 7679                          4164          485429 : }
                               4165                 : 
                               4166                 : /*
                               4167                 :  * AtEOSubXact_Namespace
                               4168                 :  *
                               4169                 :  * At subtransaction commit, propagate the temp-namespace-creation
                               4170                 :  * flag to the parent subtransaction.
                               4171                 :  *
 6829 tgl                      4172 ECB             :  * At subtransaction abort, forget the flag if we set it up.
                               4173                 :  */
                               4174                 : void
 6779 tgl                      4175 GIC        8785 : AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid,
                               4176                 :                       SubTransactionId parentSubid)
 6829 tgl                      4177 ECB             : {
                               4178                 :     OverrideStackEntry *entry;
 5861                          4179                 : 
 6779 tgl                      4180 CBC        8785 :     if (myTempNamespaceSubID == mySubid)
                               4181                 :     {
 6829 tgl                      4182 GIC           4 :         if (isCommit)
 6779 tgl                      4183 CBC           3 :             myTempNamespaceSubID = parentSubid;
                               4184                 :         else
 6829 tgl                      4185 ECB             :         {
 6779 tgl                      4186 CBC           1 :             myTempNamespaceSubID = InvalidSubTransactionId;
 6829 tgl                      4187 ECB             :             /* TEMP namespace creation failed, so reset state */
 6829 tgl                      4188 GIC           1 :             myTempNamespace = InvalidOid;
 5737                          4189               1 :             myTempToastNamespace = InvalidOid;
 2118                          4190               1 :             baseSearchPathValid = false;    /* need to rebuild list */
                               4191                 : 
                               4192                 :             /*
                               4193                 :              * Reset the temporary namespace flag in MyProc.  We assume that
                               4194                 :              * this operation is atomic.
                               4195                 :              *
                               4196                 :              * Because this subtransaction is aborting, the pg_namespace row
                               4197                 :              * is not visible to anyone else anyway, but that doesn't matter:
 1692 michael                  4198 ECB             :              * it's not a problem if objects contained in this namespace are
                               4199                 :              * removed concurrently.
                               4200                 :              */
 1700 michael                  4201 GIC           1 :             MyProc->tempNamespaceId = InvalidOid;
                               4202                 :         }
                               4203                 :     }
                               4204                 : 
 5861 tgl                      4205 ECB             :     /*
                               4206                 :      * Clean up if someone failed to do PopOverrideSearchPath
 5861 tgl                      4207 EUB             :      */
 5861 tgl                      4208 GBC        8785 :     while (overrideStack)
 5861 tgl                      4209 EUB             :     {
 5861 tgl                      4210 UBC           0 :         entry = (OverrideStackEntry *) linitial(overrideStack);
                               4211               0 :         if (entry->nestLevel < GetCurrentTransactionNestLevel())
                               4212               0 :             break;
                               4213               0 :         if (isCommit)
                               4214               0 :             elog(WARNING, "leaked override search path");
 5861 tgl                      4215 UIC           0 :         overrideStack = list_delete_first(overrideStack);
 5861 tgl                      4216 UBC           0 :         list_free(entry->searchPath);
 5861 tgl                      4217 UIC           0 :         pfree(entry);
                               4218                 :         /* Always bump generation --- see note in recomputeNamespacePath */
 1109                          4219               0 :         activePathGeneration++;
 5861 tgl                      4220 ECB             :     }
                               4221                 : 
 5861 tgl                      4222 EUB             :     /* Activate the next level down. */
 5861 tgl                      4223 GBC        8785 :     if (overrideStack)
 5861 tgl                      4224 EUB             :     {
 5861 tgl                      4225 UBC           0 :         entry = (OverrideStackEntry *) linitial(overrideStack);
 5861 tgl                      4226 UIC           0 :         activeSearchPath = entry->searchPath;
                               4227               0 :         activeCreationNamespace = entry->creationNamespace;
 2118                          4228               0 :         activeTempCreationPending = false;  /* XXX is this OK? */
                               4229                 : 
                               4230                 :         /*
 1109 tgl                      4231 EUB             :          * It's probably unnecessary to bump generation here, but this should
                               4232                 :          * not be a performance-critical case, so better to be over-cautious.
                               4233                 :          */
 1109 tgl                      4234 UIC           0 :         activePathGeneration++;
                               4235                 :     }
 5861 tgl                      4236 ECB             :     else
                               4237                 :     {
                               4238                 :         /* If not baseSearchPathValid, this is useless but harmless */
 5861 tgl                      4239 GIC        8785 :         activeSearchPath = baseSearchPath;
                               4240            8785 :         activeCreationNamespace = baseCreationNamespace;
 5833                          4241            8785 :         activeTempCreationPending = baseTempCreationPending;
                               4242                 : 
                               4243                 :         /*
                               4244                 :          * If we popped an override stack entry, then we already bumped the
                               4245                 :          * generation above.  If we did not, then the above assignments did
 1109 tgl                      4246 ECB             :          * nothing and we need not bump the generation.
                               4247                 :          */
                               4248                 :     }
 6829 tgl                      4249 GIC        8785 : }
                               4250                 : 
                               4251                 : /*
                               4252                 :  * Remove all relations in the specified temp namespace.
                               4253                 :  *
                               4254                 :  * This is called at backend shutdown (if we made any temp relations).
                               4255                 :  * It is also called when we begin using a pre-existing temp namespace,
                               4256                 :  * in order to clean out any relations that might have been created by
 7679 tgl                      4257 ECB             :  * a crashed backend.
                               4258                 :  */
                               4259                 : static void
 7679 tgl                      4260 GIC         479 : RemoveTempRelations(Oid tempNamespaceId)
                               4261                 : {
                               4262                 :     ObjectAddress object;
                               4263                 : 
                               4264                 :     /*
                               4265                 :      * We want to get rid of everything in the target namespace, but not the
                               4266                 :      * namespace itself (deleting it only to recreate it later would be a
                               4267                 :      * waste of cycles).  Hence, specify SKIP_ORIGINAL.  It's also an INTERNAL
 2319 tgl                      4268 ECB             :      * deletion, and we want to not drop any extensions that might happen to
                               4269                 :      * own temp objects.
 7679                          4270                 :      */
 6569 tgl                      4271 GIC         479 :     object.classId = NamespaceRelationId;
 7366 tgl                      4272 CBC         479 :     object.objectId = tempNamespaceId;
 7366 tgl                      4273 GIC         479 :     object.objectSubId = 0;
                               4274                 : 
 2319                          4275             479 :     performDeletion(&object, DROP_CASCADE,
                               4276                 :                     PERFORM_DELETION_INTERNAL |
 2319 tgl                      4277 ECB             :                     PERFORM_DELETION_QUIETLY |
                               4278                 :                     PERFORM_DELETION_SKIP_ORIGINAL |
                               4279                 :                     PERFORM_DELETION_SKIP_EXTENSIONS);
 7679 tgl                      4280 GIC         479 : }
                               4281                 : 
                               4282                 : /*
 7679 tgl                      4283 ECB             :  * Callback to remove temp relations at backend exit.
                               4284                 :  */
                               4285                 : static void
 7058 peter_e                  4286 GIC         273 : RemoveTempRelationsCallback(int code, Datum arg)
                               4287                 : {
 7522 bruce                    4288 CBC         273 :     if (OidIsValid(myTempNamespace))    /* should always be true */
 7679 tgl                      4289 ECB             :     {
                               4290                 :         /* Need to ensure we have a usable transaction. */
 7679 tgl                      4291 GIC         273 :         AbortOutOfAnyTransaction();
 7270 tgl                      4292 CBC         273 :         StartTransactionCommand();
  412 andres                   4293 GIC         273 :         PushActiveSnapshot(GetTransactionSnapshot());
 7679 tgl                      4294 ECB             : 
 7679 tgl                      4295 CBC         273 :         RemoveTempRelations(myTempNamespace);
                               4296                 : 
  412 andres                   4297             273 :         PopActiveSnapshot();
 7270 tgl                      4298 GIC         273 :         CommitTransactionCommand();
                               4299                 :     }
 7679                          4300             273 : }
                               4301                 : 
                               4302                 : /*
 5833 tgl                      4303 ECB             :  * Remove all temp tables from the temporary namespace.
                               4304                 :  */
                               4305                 : void
 5833 tgl                      4306 CBC           7 : ResetTempTableNamespace(void)
 5833 tgl                      4307 ECB             : {
 5833 tgl                      4308 GIC           7 :     if (OidIsValid(myTempNamespace))
                               4309               7 :         RemoveTempRelations(myTempNamespace);
                               4310               7 : }
                               4311                 : 
                               4312                 : 
                               4313                 : /*
                               4314                 :  * Routines for handling the GUC variable 'search_path'.
                               4315                 :  */
 7678 tgl                      4316 ECB             : 
                               4317                 : /* check_hook: validate new search_path value */
                               4318                 : bool
 4385 tgl                      4319 GIC        8821 : check_search_path(char **newval, void **extra, GucSource source)
                               4320                 : {
                               4321                 :     char       *rawname;
 7678 tgl                      4322 ECB             :     List       *namelist;
                               4323                 : 
                               4324                 :     /* Need a modifiable copy of string */
 4385 tgl                      4325 CBC        8821 :     rawname = pstrdup(*newval);
                               4326                 : 
                               4327                 :     /* Parse string into list of identifiers */
 7678 tgl                      4328 GBC        8821 :     if (!SplitIdentifierString(rawname, ',', &namelist))
 7678 tgl                      4329 EUB             :     {
                               4330                 :         /* syntax error in name list */
 4385 tgl                      4331 UBC           0 :         GUC_check_errdetail("List syntax is invalid.");
 7678 tgl                      4332 UIC           0 :         pfree(rawname);
 6892 neilc                    4333               0 :         list_free(namelist);
 4385 tgl                      4334               0 :         return false;
                               4335                 :     }
                               4336                 : 
                               4337                 :     /*
                               4338                 :      * We used to try to check that the named schemas exist, but there are
                               4339                 :      * many valid use-cases for having search_path settings that include
                               4340                 :      * schemas that don't exist; and often, we are not inside a transaction
                               4341                 :      * here and so can't consult the system catalogs anyway.  So now, the only
 4015 tgl                      4342 ECB             :      * requirement is syntactic validity of the identifier list.
 7678                          4343                 :      */
                               4344                 : 
 7678 tgl                      4345 CBC        8821 :     pfree(rawname);
 6892 neilc                    4346 GIC        8821 :     list_free(namelist);
                               4347                 : 
 4015 tgl                      4348            8821 :     return true;
                               4349                 : }
 4385 tgl                      4350 ECB             : 
                               4351                 : /* assign_hook: do extra actions as needed */
                               4352                 : void
 4385 tgl                      4353 GIC       12897 : assign_search_path(const char *newval, void *extra)
                               4354                 : {
                               4355                 :     /*
                               4356                 :      * We mark the path as needing recomputation, but don't do anything until
 6385 bruce                    4357 ECB             :      * it's needed.  This avoids trying to do database access during GUC
 4385 tgl                      4358                 :      * initialization, or outside a transaction.
                               4359                 :      */
 4385 tgl                      4360 GIC       12897 :     baseSearchPathValid = false;
 7678                          4361           12897 : }
                               4362                 : 
                               4363                 : /*
                               4364                 :  * InitializeSearchPath: initialize module during InitPostgres.
                               4365                 :  *
 7678 tgl                      4366 ECB             :  * This is called after we are up enough to be able to do catalog lookups.
                               4367                 :  */
                               4368                 : void
 7678 tgl                      4369 GIC       10393 : InitializeSearchPath(void)
                               4370                 : {
 7664                          4371           10393 :     if (IsBootstrapProcessingMode())
                               4372                 :     {
                               4373                 :         /*
                               4374                 :          * In bootstrap mode, the search path must be 'pg_catalog' so that
                               4375                 :          * tables are created in the proper namespace; ignore the GUC setting.
 7664 tgl                      4376 ECB             :          */
                               4377                 :         MemoryContext oldcxt;
                               4378                 : 
 7664 tgl                      4379 CBC         305 :         oldcxt = MemoryContextSwitchTo(TopMemoryContext);
 5861                          4380             305 :         baseSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
 7664                          4381             305 :         MemoryContextSwitchTo(oldcxt);
 5861                          4382             305 :         baseCreationNamespace = PG_CATALOG_NAMESPACE;
 5833                          4383             305 :         baseTempCreationPending = false;
 5861                          4384             305 :         baseSearchPathValid = true;
 7650                          4385             305 :         namespaceUser = GetUserId();
 5861                          4386             305 :         activeSearchPath = baseSearchPath;
 5861 tgl                      4387 GIC         305 :         activeCreationNamespace = baseCreationNamespace;
 5833                          4388             305 :         activeTempCreationPending = baseTempCreationPending;
 1109                          4389             305 :         activePathGeneration++; /* pro forma */
                               4390                 :     }
                               4391                 :     else
                               4392                 :     {
                               4393                 :         /*
 6385 bruce                    4394 ECB             :          * In normal mode, arrange for a callback on any syscache invalidation
                               4395                 :          * of pg_namespace rows.
                               4396                 :          */
 7650 tgl                      4397 GIC       10088 :         CacheRegisterSyscacheCallback(NAMESPACEOID,
 7650 tgl                      4398 ECB             :                                       NamespaceCallback,
                               4399                 :                                       (Datum) 0);
 7632                          4400                 :         /* Force search path to be recomputed on next use */
 5861 tgl                      4401 GIC       10088 :         baseSearchPathValid = false;
                               4402                 :     }
 7678                          4403           10393 : }
                               4404                 : 
                               4405                 : /*
                               4406                 :  * NamespaceCallback
 7650 tgl                      4407 ECB             :  *      Syscache inval callback function
                               4408                 :  */
                               4409                 : static void
 4254 tgl                      4410 CBC        8693 : NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue)
 7650 tgl                      4411 ECB             : {
                               4412                 :     /* Force search path to be recomputed on next use */
 5861 tgl                      4413 GIC        8693 :     baseSearchPathValid = false;
 7650                          4414            8693 : }
                               4415                 : 
                               4416                 : /*
                               4417                 :  * Fetch the active search path. The return value is a palloc'ed list
                               4418                 :  * of OIDs; the caller is responsible for freeing this storage as
                               4419                 :  * appropriate.
                               4420                 :  *
                               4421                 :  * The returned list includes the implicitly-prepended namespaces only if
                               4422                 :  * includeImplicit is true.
                               4423                 :  *
                               4424                 :  * Note: calling this may result in a CommandCounterIncrement operation,
 5833 tgl                      4425 ECB             :  * if we have to create or clean out the temp namespace.
                               4426                 :  */
                               4427                 : List *
 7632 tgl                      4428 GIC         366 : fetch_search_path(bool includeImplicit)
 7653 tgl                      4429 ECB             : {
                               4430                 :     List       *result;
                               4431                 : 
 7650 tgl                      4432 GIC         366 :     recomputeNamespacePath();
                               4433                 : 
                               4434                 :     /*
                               4435                 :      * If the temp namespace should be first, force it to exist.  This is so
                               4436                 :      * that callers can trust the result to reflect the actual default
                               4437                 :      * creation namespace.  It's a bit bogus to do this here, since
 5833 tgl                      4438 ECB             :      * current_schema() is supposedly a stable function without side-effects,
                               4439                 :      * but the alternatives seem worse.
                               4440                 :      */
 5833 tgl                      4441 CBC         366 :     if (activeTempCreationPending)
                               4442                 :     {
 1542 michael                  4443 GIC           3 :         AccessTempTableNamespace(true);
 5833 tgl                      4444 CBC           3 :         recomputeNamespacePath();
 5833 tgl                      4445 ECB             :     }
                               4446                 : 
 5861 tgl                      4447 CBC         366 :     result = list_copy(activeSearchPath);
 7632                          4448             366 :     if (!includeImplicit)
                               4449                 :     {
 5861 tgl                      4450 GIC         580 :         while (result && linitial_oid(result) != activeCreationNamespace)
 6892 neilc                    4451 CBC         307 :             result = list_delete_first(result);
                               4452                 :     }
                               4453                 : 
 7632 tgl                      4454 GIC         366 :     return result;
                               4455                 : }
                               4456                 : 
                               4457                 : /*
                               4458                 :  * Fetch the active search path into a caller-allocated array of OIDs.
                               4459                 :  * Returns the number of path entries.  (If this is more than sarray_len,
                               4460                 :  * then the data didn't fit and is not all stored.)
                               4461                 :  *
                               4462                 :  * The returned list always includes the implicitly-prepended namespaces,
                               4463                 :  * but never includes the temp namespace.  (This is suitable for existing
                               4464                 :  * users, which would want to ignore the temp namespace anyway.)  This
 5611 tgl                      4465 ECB             :  * definition allows us to not worry about initializing the temp namespace.
                               4466                 :  */
                               4467                 : int
 5611 tgl                      4468 GIC      502493 : fetch_search_path_array(Oid *sarray, int sarray_len)
                               4469                 : {
 5611 tgl                      4470 CBC      502493 :     int         count = 0;
                               4471                 :     ListCell   *l;
 5611 tgl                      4472 ECB             : 
 5611 tgl                      4473 GIC      502493 :     recomputeNamespacePath();
 5611 tgl                      4474 ECB             : 
 5611 tgl                      4475 GIC     1395921 :     foreach(l, activeSearchPath)
 5611 tgl                      4476 ECB             :     {
 5611 tgl                      4477 CBC      893428 :         Oid         namespaceId = lfirst_oid(l);
                               4478                 : 
                               4479          893428 :         if (namespaceId == myTempNamespace)
                               4480           61760 :             continue;           /* do not include temp namespace */
 5611 tgl                      4481 ECB             : 
 5611 tgl                      4482 GIC      831668 :         if (count < sarray_len)
                               4483          831668 :             sarray[count] = namespaceId;
 5611 tgl                      4484 CBC      831668 :         count++;
                               4485                 :     }
                               4486                 : 
 5611 tgl                      4487 GIC      502493 :     return count;
                               4488                 : }
                               4489                 : 
                               4490                 : 
                               4491                 : /*
                               4492                 :  * Export the FooIsVisible functions as SQL-callable functions.
                               4493                 :  *
                               4494                 :  * Note: as of Postgres 8.4, these will silently return NULL if called on
                               4495                 :  * a nonexistent object OID, rather than failing.  This is to avoid race
                               4496                 :  * condition errors when a query that's scanning a catalog using an MVCC
                               4497                 :  * snapshot uses one of these functions.  The underlying IsVisible functions
                               4498                 :  * always use an up-to-date snapshot and so might see the object as already
                               4499                 :  * gone when it's still visible to the transaction snapshot.  (There is no race
                               4500                 :  * condition in the current coding because we don't accept sinval messages
                               4501                 :  * between the SearchSysCacheExists test and the subsequent lookup.)
 7548 tgl                      4502 ECB             :  */
                               4503                 : 
                               4504                 : Datum
 7548 tgl                      4505 GIC        7976 : pg_table_is_visible(PG_FUNCTION_ARGS)
 7548 tgl                      4506 ECB             : {
 7548 tgl                      4507 GBC        7976 :     Oid         oid = PG_GETARG_OID(0);
                               4508                 : 
 4802 rhaas                    4509 CBC        7976 :     if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(oid)))
 5228 tgl                      4510 UIC           0 :         PG_RETURN_NULL();
                               4511                 : 
 7548 tgl                      4512 GIC        7976 :     PG_RETURN_BOOL(RelationIsVisible(oid));
 7548 tgl                      4513 ECB             : }
                               4514                 : 
                               4515                 : Datum
 7548 tgl                      4516 GIC        1935 : pg_type_is_visible(PG_FUNCTION_ARGS)
 7548 tgl                      4517 ECB             : {
 7548 tgl                      4518 GBC        1935 :     Oid         oid = PG_GETARG_OID(0);
                               4519                 : 
 4802 rhaas                    4520 CBC        1935 :     if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(oid)))
 5228 tgl                      4521 UIC           0 :         PG_RETURN_NULL();
                               4522                 : 
 7548 tgl                      4523 GIC        1935 :     PG_RETURN_BOOL(TypeIsVisible(oid));
 7548 tgl                      4524 ECB             : }
                               4525                 : 
                               4526                 : Datum
 7548 tgl                      4527 GIC        3667 : pg_function_is_visible(PG_FUNCTION_ARGS)
 7548 tgl                      4528 ECB             : {
 7548 tgl                      4529 GBC        3667 :     Oid         oid = PG_GETARG_OID(0);
                               4530                 : 
 4802 rhaas                    4531 CBC        3667 :     if (!SearchSysCacheExists1(PROCOID, ObjectIdGetDatum(oid)))
 5228 tgl                      4532 UIC           0 :         PG_RETURN_NULL();
                               4533                 : 
 7548 tgl                      4534 GIC        3667 :     PG_RETURN_BOOL(FunctionIsVisible(oid));
 7548 tgl                      4535 ECB             : }
                               4536                 : 
                               4537                 : Datum
 7548 tgl                      4538 GIC         850 : pg_operator_is_visible(PG_FUNCTION_ARGS)
 7548 tgl                      4539 ECB             : {
 7548 tgl                      4540 GBC         850 :     Oid         oid = PG_GETARG_OID(0);
                               4541                 : 
 4802 rhaas                    4542 CBC         850 :     if (!SearchSysCacheExists1(OPEROID, ObjectIdGetDatum(oid)))
 5228 tgl                      4543 UIC           0 :         PG_RETURN_NULL();
                               4544                 : 
 7548 tgl                      4545 GIC         850 :     PG_RETURN_BOOL(OperatorIsVisible(oid));
 7548 tgl                      4546 ECB             : }
                               4547                 : 
                               4548                 : Datum
 7548 tgl                      4549 GIC           9 : pg_opclass_is_visible(PG_FUNCTION_ARGS)
 7548 tgl                      4550 ECB             : {
 7548 tgl                      4551 GBC           9 :     Oid         oid = PG_GETARG_OID(0);
                               4552                 : 
 4802 rhaas                    4553 CBC           9 :     if (!SearchSysCacheExists1(CLAOID, ObjectIdGetDatum(oid)))
 5228 tgl                      4554 UIC           0 :         PG_RETURN_NULL();
                               4555                 : 
 7548 tgl                      4556 GIC           9 :     PG_RETURN_BOOL(OpclassIsVisible(oid));
 7548 tgl                      4557 ECB             : }
                               4558                 : 
 4284 rhaas                    4559                 : Datum
 4284 rhaas                    4560 GIC         132 : pg_opfamily_is_visible(PG_FUNCTION_ARGS)
 4284 rhaas                    4561 ECB             : {
 4284 rhaas                    4562 GBC         132 :     Oid         oid = PG_GETARG_OID(0);
                               4563                 : 
 4284 rhaas                    4564 CBC         132 :     if (!SearchSysCacheExists1(OPFAMILYOID, ObjectIdGetDatum(oid)))
 4284 rhaas                    4565 UIC           0 :         PG_RETURN_NULL();
                               4566                 : 
 4284 rhaas                    4567 GIC         132 :     PG_RETURN_BOOL(OpfamilyIsVisible(oid));
 4284 rhaas                    4568 EUB             : }
                               4569                 : 
 4443 peter_e                  4570                 : Datum
 4443 peter_e                  4571 UIC           0 : pg_collation_is_visible(PG_FUNCTION_ARGS)
 4443 peter_e                  4572 EUB             : {
 4443 peter_e                  4573 UBC           0 :     Oid         oid = PG_GETARG_OID(0);
                               4574                 : 
                               4575               0 :     if (!SearchSysCacheExists1(COLLOID, ObjectIdGetDatum(oid)))
 4443 peter_e                  4576 UIC           0 :         PG_RETURN_NULL();
                               4577                 : 
                               4578               0 :     PG_RETURN_BOOL(CollationIsVisible(oid));
 4443 peter_e                  4579 EUB             : }
                               4580                 : 
 7423 bruce                    4581                 : Datum
 7423 bruce                    4582 UIC           0 : pg_conversion_is_visible(PG_FUNCTION_ARGS)
 7423 bruce                    4583 EUB             : {
 7423 bruce                    4584 UBC           0 :     Oid         oid = PG_GETARG_OID(0);
                               4585                 : 
 4802 rhaas                    4586               0 :     if (!SearchSysCacheExists1(CONVOID, ObjectIdGetDatum(oid)))
 5228 tgl                      4587 UIC           0 :         PG_RETURN_NULL();
                               4588                 : 
 7423 bruce                    4589               0 :     PG_RETURN_BOOL(ConversionIsVisible(oid));
 7423 bruce                    4590 ECB             : }
                               4591                 : 
 2157 alvherre                 4592                 : Datum
 2156 tgl                      4593 GIC         183 : pg_statistics_obj_is_visible(PG_FUNCTION_ARGS)
 2157 alvherre                 4594 ECB             : {
 2157 alvherre                 4595 GBC         183 :     Oid         oid = PG_GETARG_OID(0);
                               4596                 : 
 2157 alvherre                 4597 CBC         183 :     if (!SearchSysCacheExists1(STATEXTOID, ObjectIdGetDatum(oid)))
 2157 alvherre                 4598 UIC           0 :         PG_RETURN_NULL();
                               4599                 : 
 2157 alvherre                 4600 GIC         183 :     PG_RETURN_BOOL(StatisticsObjIsVisible(oid));
 2157 alvherre                 4601 EUB             : }
                               4602                 : 
 5710 tgl                      4603                 : Datum
 5710 tgl                      4604 UIC           0 : pg_ts_parser_is_visible(PG_FUNCTION_ARGS)
 5710 tgl                      4605 EUB             : {
 5710 tgl                      4606 UBC           0 :     Oid         oid = PG_GETARG_OID(0);
                               4607                 : 
 4802 rhaas                    4608               0 :     if (!SearchSysCacheExists1(TSPARSEROID, ObjectIdGetDatum(oid)))
 5228 tgl                      4609 UIC           0 :         PG_RETURN_NULL();
                               4610                 : 
 5710                          4611               0 :     PG_RETURN_BOOL(TSParserIsVisible(oid));
 5710 tgl                      4612 EUB             : }
                               4613                 : 
                               4614                 : Datum
 5710 tgl                      4615 UIC           0 : pg_ts_dict_is_visible(PG_FUNCTION_ARGS)
 5710 tgl                      4616 EUB             : {
 5710 tgl                      4617 UBC           0 :     Oid         oid = PG_GETARG_OID(0);
                               4618                 : 
 4802 rhaas                    4619               0 :     if (!SearchSysCacheExists1(TSDICTOID, ObjectIdGetDatum(oid)))
 5228 tgl                      4620 UIC           0 :         PG_RETURN_NULL();
                               4621                 : 
 5710                          4622               0 :     PG_RETURN_BOOL(TSDictionaryIsVisible(oid));
 5710 tgl                      4623 EUB             : }
                               4624                 : 
                               4625                 : Datum
 5710 tgl                      4626 UIC           0 : pg_ts_template_is_visible(PG_FUNCTION_ARGS)
 5710 tgl                      4627 EUB             : {
 5710 tgl                      4628 UBC           0 :     Oid         oid = PG_GETARG_OID(0);
                               4629                 : 
 4802 rhaas                    4630               0 :     if (!SearchSysCacheExists1(TSTEMPLATEOID, ObjectIdGetDatum(oid)))
 5228 tgl                      4631 UIC           0 :         PG_RETURN_NULL();
                               4632                 : 
 5710                          4633               0 :     PG_RETURN_BOOL(TSTemplateIsVisible(oid));
 5710 tgl                      4634 EUB             : }
                               4635                 : 
                               4636                 : Datum
 5710 tgl                      4637 UIC           0 : pg_ts_config_is_visible(PG_FUNCTION_ARGS)
 5710 tgl                      4638 EUB             : {
 5710 tgl                      4639 UBC           0 :     Oid         oid = PG_GETARG_OID(0);
                               4640                 : 
 4802 rhaas                    4641               0 :     if (!SearchSysCacheExists1(TSCONFIGOID, ObjectIdGetDatum(oid)))
 5228 tgl                      4642 UIC           0 :         PG_RETURN_NULL();
                               4643                 : 
 5710                          4644               0 :     PG_RETURN_BOOL(TSConfigIsVisible(oid));
 5710 tgl                      4645 ECB             : }
                               4646                 : 
 6051                          4647                 : Datum
 6051 tgl                      4648 GIC         503 : pg_my_temp_schema(PG_FUNCTION_ARGS)
                               4649                 : {
                               4650             503 :     PG_RETURN_OID(myTempNamespace);
 6051 tgl                      4651 ECB             : }
                               4652                 : 
                               4653                 : Datum
 6051 tgl                      4654 GIC        2588 : pg_is_other_temp_schema(PG_FUNCTION_ARGS)
 6051 tgl                      4655 ECB             : {
 6051 tgl                      4656 GIC        2588 :     Oid         oid = PG_GETARG_OID(0);
                               4657                 : 
                               4658            2588 :     PG_RETURN_BOOL(isOtherTempNamespace(oid));
                               4659                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a