/* * GetDefaultTablespace -- get the OID of the current default tablespace * * Temporary objects have different default tablespaces, hence the * relpersistence parameter must be specified. * * May return InvalidOid to indicate "use the database's default tablespace". * * Note that caller is expected to check appropriate permissions for any * result other than InvalidOid. * * This exists to hide (and possibly optimize the use of) the * default_tablespace GUC variable. */ Oid GetDefaultTablespace(char relpersistence) { Oid result; /* The temp-table case is handled elsewhere */ if (relpersistence == RELPERSISTENCE_TEMP) { PrepareTempTablespaces(); return GetNextTempTableSpace(); } /* Fast path for default_tablespace == "" */ if (default_tablespace == NULL || default_tablespace[0] == '\0') return InvalidOid; /* * It is tempting to cache this lookup for more speed, but then we would * fail to detect the case where the tablespace was dropped since the GUC * variable was set. Note also that we don't complain if the value fails * to refer to an existing tablespace; we just silently return InvalidOid, * causing the new object to be created in the database's tablespace. */ result = get_tablespace_oid(default_tablespace, true); /* * Allow explicit specification of database's default tablespace in * default_tablespace without triggering permissions checks. */ if (result == MyDatabaseTableSpace) result = InvalidOid; return result; }
/* * Open a temporary file that will disappear when we close it. * * This routine takes care of generating an appropriate tempfile name. * There's no need to pass in fileFlags or fileMode either, since only * one setting makes any sense for a temp file. * * Unless interXact is true, the file is remembered by CurrentResourceOwner * to ensure it's closed and deleted when it's no longer needed, typically at * the end-of-transaction. In most cases, you don't want temporary files to * outlive the transaction that created them, so this should be false -- but * if you need "somewhat" temporary storage, this might be useful. In either * case, the file is removed when the File is explicitly closed. */ File OpenTemporaryFile(bool interXact) { File file = 0; /* * If some temp tablespace(s) have been given to us, try to use the next * one. If a given tablespace can't be found, we silently fall back to * the database's default tablespace. * * BUT: if the temp file is slated to outlive the current transaction, * force it into the database's default tablespace, so that it will not * pose a threat to possible tablespace drop attempts. */ if (numTempTableSpaces > 0 && !interXact) { Oid tblspcOid = GetNextTempTableSpace(); if (OidIsValid(tblspcOid)) file = OpenTemporaryFileInTablespace(tblspcOid, false); } /* * If not, or if tablespace is bad, create in database's default * tablespace. MyDatabaseTableSpace should normally be set before we get * here, but just in case it isn't, fall back to pg_default tablespace. */ if (file <= 0) file = OpenTemporaryFileInTablespace(MyDatabaseTableSpace ? MyDatabaseTableSpace : DEFAULTTABLESPACE_OID, true); /* Mark it for deletion at close */ VfdCache[file].fdstate |= FD_TEMPORARY; /* Register it with the current resource owner */ if (!interXact) { VfdCache[file].fdstate |= FD_XACT_TEMPORARY; ResourceOwnerEnlargeFiles(CurrentResourceOwner); ResourceOwnerRememberFile(CurrentResourceOwner, file); VfdCache[file].resowner = CurrentResourceOwner; } return file; }