78#include "utils/fmgroids.h"
131 if (
stat(dir, &st) < 0)
159 errmsg(
"could not create directory \"%s\": %m",
175 errmsg(
"could not create directory \"%s\": %m",
186 errmsg(
"could not stat directory \"%s\": %m", dir)));
195 errmsg(
"\"%s\" exists but is not a directory",
226 errmsg(
"permission denied to create tablespace \"%s\"",
227 stmt->tablespacename),
228 errhint(
"Must be superuser to create a tablespace.")));
241 if (
strchr(location,
'\''))
244 errmsg(
"tablespace location cannot contain single quotes")));
250 errmsg(
"tablespace name \"%s\" contains a newline or carriage return character",
stmt->tablespacename)));
263 errmsg(
"tablespace location must be an absolute path")));
275 errmsg(
"tablespace location \"%s\" is too long",
282 errmsg(
"tablespace location should not be inside the data directory")));
291 errmsg(
"unacceptable tablespace name \"%s\"",
292 stmt->tablespacename),
293 errdetail(
"The prefix \"pg_\" is reserved for system tablespaces.")));
299#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
300 if (
strncmp(
stmt->tablespacename,
"regress_", 8) != 0)
301 elog(
WARNING,
"tablespaces created by regression test cases should have names starting with \"regress_\"");
312 errmsg(
"tablespace \"%s\" already exists",
313 stmt->tablespacename)));
328 errmsg(
"pg_tablespace OID value not set when in binary upgrade mode")));
405 char *tablespacename =
stmt->tablespacename;
429 if (!
stmt->missing_ok)
433 errmsg(
"tablespace \"%s\" does not exist",
439 (
errmsg(
"tablespace \"%s\" does not exist, skipping",
462 &detail, &detail_log))
465 errmsg(
"tablespace \"%s\" cannot be dropped because some objects depend on it",
532 errmsg(
"tablespace \"%s\" is not empty",
594 in_place =
strlen(location) == 0;
601 errmsg(
"could not create directory \"%s\": %m",
619 errmsg(
"directory \"%s\" does not exist", location),
621 "restarting the server.") : 0));
625 errmsg(
"could not set permissions on directory \"%s\": %m",
641 errmsg(
"could not stat directory \"%s\": %m",
646 errmsg(
"could not create directory \"%s\": %m",
652 errmsg(
"\"%s\" exists but is not a directory",
657 errmsg(
"directory \"%s\" already in use as a tablespace",
672 errmsg(
"could not create symbolic link \"%s\": %m",
736 errmsg(
"could not open directory \"%s\": %m",
746 errmsg(
"could not open directory \"%s\": %m",
775 errmsg(
"could not remove directory \"%s\": %m",
788 errmsg(
"could not remove directory \"%s\": %m",
808 int saved_errno =
errno;
812 errmsg(
"could not stat file \"%s\": %m",
819 int saved_errno =
errno;
823 errmsg(
"could not remove directory \"%s\": %m",
831 int saved_errno =
errno;
835 errmsg(
"could not remove symbolic link \"%s\": %m",
844 errmsg(
"\"%s\" is not a directory or symbolic link",
913 errmsg(
"could not remove directory \"%s\": %m",
921 errmsg(
"could not remove symbolic link \"%s\": %m",
929 errmsg(
"\"%s\" is not a directory or symbolic link",
961 errmsg(
"tablespace \"%s\" does not exist",
978 errmsg(
"unacceptable tablespace name \"%s\"", newname),
979 errdetail(
"The prefix \"pg_\" is reserved for system tablespaces.")));
985 errmsg(
"tablespace name \"%s\" contains a newline or carriage return character", newname)));
991#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
992 if (
strncmp(newname,
"regress_", 8) != 0)
993 elog(
WARNING,
"tablespaces created by regression test cases should have names starting with \"regress_\"");
1006 errmsg(
"tablespace \"%s\" already exists",
1056 errmsg(
"tablespace \"%s\" does not exist",
1057 stmt->tablespacename)));
1064 stmt->tablespacename);
1125 errmsg(
"tablespace \"%s\" does not exist",
1192 errmsg(
"cannot specify default tablespace for partitioned relations")));
1271 errmsg(
"tablespace \"%s\" does not exist",
1297 tblSpcs[numSpcs++] =
curoid;
1302 numSpcs *
sizeof(
Oid));
1423 tblSpcs[numSpcs++] =
curoid;
1474 errmsg(
"tablespace \"%s\" does not exist",
1576 errmsg(
"directories for tablespace %u could not be removed",
1578 errhint(
"You can remove the directories manually if necessary.")));
1582 elog(
PANIC,
"tblspc_redo: unknown op code %u", info);
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Oid AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt)
Oid binary_upgrade_next_pg_tablespace_oid
bool directory_is_empty(const char *path)
void remove_tablespace_symlink(const char *linkloc)
static bool destroy_tablespace_directories(Oid tablespaceoid, bool redo)
bool check_default_tablespace(char **newval, void **extra, GucSource source)
char * get_tablespace_name(Oid spc_oid)
void DropTableSpace(DropTableSpaceStmt *stmt)
void PrepareTempTablespaces(void)
Oid get_tablespace_oid(const char *tablespacename, bool missing_ok)
ObjectAddress RenameTableSpace(const char *oldname, const char *newname)
void assign_temp_tablespaces(const char *newval, void *extra)
Oid GetDefaultTablespace(char relpersistence, bool partitioned)
void TablespaceCreateDbspace(Oid spcOid, Oid dbOid, bool isRedo)
bool check_temp_tablespaces(char **newval, void **extra, GucSource source)
Oid CreateTableSpace(CreateTableSpaceStmt *stmt)
char * default_tablespace
static void create_tablespace_directories(const char *location, const Oid tablespaceoid)
void tblspc_redo(XLogReaderState *record)
bool allow_in_place_tablespaces
static Datum values[MAXATTR]
#define Assert(condition)
#define FLEXIBLE_ARRAY_MEMBER
#define OidIsValid(objectId)
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
bool IsPinnedObject(Oid classId, Oid objectId)
bool IsReservedName(const char *name)
void RequestCheckpoint(int flags)
int errcode_for_file_access(void)
int errcode(int sqlerrcode)
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
int int int errdetail_log(const char *fmt,...) pg_attribute_printf(1
#define ereport(elevel,...)
int MakePGDirectory(const char *directoryName)
bool TempTablespacesAreSet(void)
Oid GetNextTempTableSpace(void)
DIR * AllocateDir(const char *dirname)
struct dirent * ReadDir(DIR *dir, const char *dirname)
void SetTempTablespaces(Oid *tableSpaces, int numSpaces)
#define DirectFunctionCall1(func, arg1)
bool allowSystemTableMods
void * guc_malloc(int elevel, size_t size)
#define GUC_check_errdetail
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
HeapTuple heap_copytuple(HeapTuple tuple)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static void * GETSTRUCT(const HeapTupleData *tuple)
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
void list_free(List *list)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
void * MemoryContextAlloc(MemoryContext context, Size size)
MemoryContext TopTransactionContext
char * pstrdup(const char *in)
void pfree(void *pointer)
void namestrcpy(Name name, const char *str)
Datum namein(PG_FUNCTION_ARGS)
#define InvokeObjectPostCreateHook(classId, objectId, subId)
#define InvokeObjectPostAlterHook(classId, objectId, subId)
#define InvokeObjectDropHook(classId, objectId, subId)
#define ObjectAddressSet(addr, class_id, object_id)
static int list_length(const List *l)
static rewind_source * source
void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, int32 objectSubId)
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
bool checkSharedDependencies(Oid classId, Oid objectId, char **detail_msg, char **detail_log_msg)
END_CATALOG_STRUCT typedef FormData_pg_tablespace * Form_pg_tablespace
int pg_mkdir_p(char *path, int omode)
#define is_absolute_path(filename)
bool path_is_prefix_of_path(const char *path1, const char *path2)
void canonicalize_path(char *path)
void get_parent_directory(char *path)
static Datum ObjectIdGetDatum(Oid X)
static Datum CStringGetDatum(const char *X)
void WaitForProcSignalBarrier(uint64 generation)
uint64 EmitProcSignalBarrier(ProcSignalBarrierType type)
@ PROCSIGNAL_BARRIER_SMGRRELEASE
char * psprintf(const char *fmt,...)
#define RelationGetDescr(relation)
bytea * tablespace_reloptions(Datum reloptions, bool validate)
Datum transformRelOptions(Datum oldOptions, List *defList, const char *nameSpace, const char *const validnsps[], bool acceptOidsOff, bool isReset)
char * GetDatabasePath(Oid dbOid, Oid spcOid)
#define TABLESPACE_VERSION_DIRECTORY
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
void DeleteSharedSecurityLabel(Oid objectId, Oid classId)
void ResolveRecoveryConflictWithTablespace(Oid tsid)
#define BTEqualStrategyNumber
#define ERRCODE_DUPLICATE_OBJECT
char ts_path[FLEXIBLE_ARRAY_MEMBER]
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TableScanDesc table_beginscan_catalog(Relation relation, int nkeys, ScanKeyData *key)
static void table_endscan(TableScanDesc scan)
#define XLOG_TBLSPC_CREATE
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
#define symlink(oldpath, newpath)
bool IsTransactionState(void)
void ForceSyncCommit(void)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterData(const void *data, uint32 len)
void XLogBeginInsert(void)
#define XLogRecGetInfo(decoder)
#define XLogRecGetData(decoder)
#define XLogRecHasAnyBlockRefs(decoder)