]> granicus.if.org Git - postgresql/blobdiff - src/backend/catalog/namespace.c
Update copyright for 2016
[postgresql] / src / backend / catalog / namespace.c
index 911f015f27ec933c4082660364d672170b86de8e..8b105fe62f6ac89800ab8f541daba1bd3097d477 100644 (file)
@@ -9,7 +9,7 @@
  * and implementing search-path-controlled searches.
  *
  *
- * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
@@ -20,6 +20,7 @@
 #include "postgres.h"
 
 #include "access/htup_details.h"
+#include "access/parallel.h"
 #include "access/xact.h"
 #include "access/xlog.h"
 #include "catalog/dependency.h"
@@ -261,9 +262,9 @@ RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode,
         * with the answer changing under them, or that they already hold some
         * appropriate lock, and therefore return the first answer we get without
         * checking for invalidation messages.  Also, if the requested lock is
-        * already held, LockRelationOid will not AcceptInvalidationMessages,
-        * so we may fail to notice a change.  We could protect against that case
-        * by calling AcceptInvalidationMessages() before beginning this loop, but
+        * already held, LockRelationOid will not AcceptInvalidationMessages, so
+        * we may fail to notice a change.  We could protect against that case by
+        * calling AcceptInvalidationMessages() before beginning this loop, but
         * that would add a significant amount overhead, so for now we don't.
         */
        for (;;)
@@ -1075,8 +1076,8 @@ FuncnameGetCandidates(List *names, int nargs, List *argnames,
                 */
                effective_nargs = Max(pronargs, nargs);
                newResult = (FuncCandidateList)
-                       palloc(sizeof(struct _FuncCandidateList) - sizeof(Oid)
-                                  effective_nargs * sizeof(Oid));
+                       palloc(offsetof(struct _FuncCandidateList, args) +
+                                  effective_nargs * sizeof(Oid));
                newResult->pathpos = pathpos;
                newResult->oid = HeapTupleGetOid(proctup);
                newResult->nargs = effective_nargs;
@@ -1597,7 +1598,8 @@ OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok)
         * separate palloc for each operator, but profiling revealed that the
         * pallocs used an unreasonably large fraction of parsing time.
         */
-#define SPACE_PER_OP MAXALIGN(sizeof(struct _FuncCandidateList) + sizeof(Oid))
+#define SPACE_PER_OP MAXALIGN(offsetof(struct _FuncCandidateList, args) + \
+                                                         2 * sizeof(Oid))
 
        if (catlist->n_members > 0)
                resultSpace = palloc(catlist->n_members * SPACE_PER_OP);
@@ -2767,24 +2769,13 @@ LookupCreationNamespace(const char *nspname)
 /*
  * Common checks on switching namespaces.
  *
- * We complain if (1) the old and new namespaces are the same, (2) either the
- * old or new namespaces is a temporary schema (or temporary toast schema), or
- * (3) either the old or new namespaces is the TOAST schema.
+ * We complain if either the old or new namespaces is a temporary schema
+ * (or temporary toast schema), or if either the old or new namespaces is the
+ * TOAST schema.
  */
 void
-CheckSetNamespace(Oid oldNspOid, Oid nspOid, Oid classid, Oid objid)
+CheckSetNamespace(Oid oldNspOid, Oid nspOid)
 {
-       if (oldNspOid == nspOid)
-               ereport(ERROR,
-                               (classid == RelationRelationId ?
-                                errcode(ERRCODE_DUPLICATE_TABLE) :
-                                classid == ProcedureRelationId ?
-                                errcode(ERRCODE_DUPLICATE_FUNCTION) :
-                                errcode(ERRCODE_DUPLICATE_OBJECT),
-                                errmsg("%s is already in schema \"%s\"",
-                                               getObjectDescriptionOids(classid, objid),
-                                               get_namespace_name(nspOid))));
-
        /* disallow renaming into or out of temp schemas */
        if (isAnyTempNamespace(nspOid) || isAnyTempNamespace(oldNspOid))
                ereport(ERROR,
@@ -2935,7 +2926,7 @@ NameListToString(List *names)
                if (IsA(name, String))
                        appendStringInfoString(&string, strVal(name));
                else if (IsA(name, A_Star))
-                       appendStringInfoString(&string, "*");
+                       appendStringInfoChar(&string, '*');
                else
                        elog(ERROR, "unexpected node type in name list: %d",
                                 (int) nodeTag(name));
@@ -3145,20 +3136,44 @@ CopyOverrideSearchPath(OverrideSearchPath *path)
 bool
 OverrideSearchPathMatchesCurrent(OverrideSearchPath *path)
 {
-       /* Easiest way to do this is GetOverrideSearchPath() and compare */
-       bool            result;
-       OverrideSearchPath *cur;
+       ListCell   *lc,
+                          *lcp;
 
-       cur = GetOverrideSearchPath(CurrentMemoryContext);
-       if (path->addCatalog == cur->addCatalog &&
-               path->addTemp == cur->addTemp &&
-               equal(path->schemas, cur->schemas))
-               result = true;
-       else
-               result = false;
-       list_free(cur->schemas);
-       pfree(cur);
-       return result;
+       recomputeNamespacePath();
+
+       /* We scan down the activeSearchPath to see if it matches the input. */
+       lc = list_head(activeSearchPath);
+
+       /* If path->addTemp, first item should be my temp namespace. */
+       if (path->addTemp)
+       {
+               if (lc && lfirst_oid(lc) == myTempNamespace)
+                       lc = lnext(lc);
+               else
+                       return false;
+       }
+       /* If path->addCatalog, next item should be pg_catalog. */
+       if (path->addCatalog)
+       {
+               if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE)
+                       lc = lnext(lc);
+               else
+                       return false;
+       }
+       /* We should now be looking at the activeCreationNamespace. */
+       if (activeCreationNamespace != (lc ? lfirst_oid(lc) : InvalidOid))
+               return false;
+       /* The remainder of activeSearchPath should match path->schemas. */
+       foreach(lcp, path->schemas)
+       {
+               if (lc && lfirst_oid(lc) == lfirst_oid(lcp))
+                       lc = lnext(lc);
+               else
+                       return false;
+       }
+       if (lc)
+               return false;
+       return true;
 }
 
 /*
@@ -3621,6 +3636,12 @@ InitTempTableNamespace(void)
                                (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
                                 errmsg("cannot create temporary tables during recovery")));
 
+       /* Parallel workers can't create temporary tables, either. */
+       if (IsParallelWorker())
+               ereport(ERROR,
+                               (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
+                                errmsg("cannot create temporary tables in parallel mode")));
+
        snprintf(namespaceName, sizeof(namespaceName), "pg_temp_%d", MyBackendId);
 
        namespaceId = get_namespace_oid(namespaceName, true);
@@ -3684,7 +3705,7 @@ InitTempTableNamespace(void)
  * End-of-transaction cleanup for namespaces.
  */
 void
-AtEOXact_Namespace(bool isCommit)
+AtEOXact_Namespace(bool isCommit, bool parallel)
 {
        /*
         * If we abort the transaction in which a temp namespace was selected,
@@ -3694,7 +3715,7 @@ AtEOXact_Namespace(bool isCommit)
         * at backend shutdown.  (We only want to register the callback once per
         * session, so this is a good place to do it.)
         */
-       if (myTempNamespaceSubID != InvalidSubTransactionId)
+       if (myTempNamespaceSubID != InvalidSubTransactionId && !parallel)
        {
                if (isCommit)
                        before_shmem_exit(RemoveTempRelationsCallback, 0);