PostgreSQL Source Code: src/backend/commands/tablespace.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

48

51#include <sys/stat.h>

52

76#include "utils/fmgroids.h"

81

82

86

88

90 const Oid tablespaceoid);

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111void

113{

114 struct stat st;

115 char *dir;

116

117

118

119

120

121 if (spcOid == GLOBALTABLESPACE_OID)

122 return;

123

126

128

129 if (stat(dir, &st) < 0)

130 {

131

132 if (errno == ENOENT)

133 {

134

135

136

137

139

140

141

142

143

145 {

146

147 }

148 else

149 {

150

152 {

153

154 if (errno != ENOENT || !isRedo)

157 errmsg("could not create directory \"%s\": %m",

158 dir)));

159

160

161

162

163

164

165

166

167

168

169

173 errmsg("could not create directory \"%s\": %m",

174 dir)));

175 }

176 }

177

179 }

180 else

181 {

184 errmsg("could not stat directory \"%s\": %m", dir)));

185 }

186 }

187 else

188 {

189

192 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

193 errmsg("\"%s\" exists but is not a directory",

194 dir)));

195 }

196

198}

199

200

201

202

203

204

205

206

209{

212 bool nulls[Natts_pg_tablespace] = {0};

214 Oid tablespaceoid;

215 char *location;

216 Oid ownerId;

217 Datum newOptions;

218 bool in_place;

219

220

223 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

224 errmsg("permission denied to create tablespace \"%s\"",

225 stmt->tablespacename),

226 errhint("Must be superuser to create a tablespace.")));

227

228

229 if (stmt->owner)

231 else

233

234

237

238

239 if (strchr(location, '\''))

241 (errcode(ERRCODE_INVALID_NAME),

242 errmsg("tablespace location cannot contain single quotes")));

243

245

246

247

248

249

250

251

254 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

255 errmsg("tablespace location must be an absolute path")));

256

257

258

259

260

261

262

266 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

267 errmsg("tablespace location \"%s\" is too long",

268 location)));

269

270

273 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

274 errmsg("tablespace location should not be inside the data directory")));

275

276

277

278

279

282 (errcode(ERRCODE_RESERVED_NAME),

283 errmsg("unacceptable tablespace name \"%s\"",

284 stmt->tablespacename),

285 errdetail("The prefix \"pg_\" is reserved for system tablespaces.")));

286

287

288

289

290

291#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS

292 if (strncmp(stmt->tablespacename, "regress_", 8) != 0)

293 elog(WARNING, "tablespaces created by regression test cases should have names starting with \"regress_\"");

294#endif

295

296

297

298

299

300

304 errmsg("tablespace \"%s\" already exists",

305 stmt->tablespacename)));

306

307

308

309

310

311

313

315 {

316

319 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

320 errmsg("pg_tablespace OID value not set when in binary upgrade mode")));

321

324 }

325 else

327 Anum_pg_tablespace_oid);

329 values[Anum_pg_tablespace_spcname - 1] =

331 values[Anum_pg_tablespace_spcowner - 1] =

333 nulls[Anum_pg_tablespace_spcacl - 1] = true;

334

335

337 stmt->options,

338 NULL, NULL, false, false);

340 if (newOptions != (Datum) 0)

341 values[Anum_pg_tablespace_spcoptions - 1] = newOptions;

342 else

343 nulls[Anum_pg_tablespace_spcoptions - 1] = true;

344

346

348

350

351

353

354

356

358

359

360 {

362

363 xlrec.ts_id = tablespaceoid;

364

369

371 }

372

373

374

375

376

377

378

380

382

383

385

386 return tablespaceoid;

387}

388

389

390

391

392

393

394void

396{

397 char *tablespacename = stmt->tablespacename;

403 Oid tablespaceoid;

404 char *detail;

405 char *detail_log;

406

407

408

409

411

413 Anum_pg_tablespace_spcname,

418

420 {

421 if (stmt->missing_ok)

422 {

424 (errcode(ERRCODE_UNDEFINED_OBJECT),

425 errmsg("tablespace \"%s\" does not exist",

426 tablespacename)));

427 }

428 else

429 {

431 (errmsg("tablespace \"%s\" does not exist, skipping",

432 tablespacename)));

435 }

436 return;

437 }

438

440 tablespaceoid = spcform->oid;

441

442

445 tablespacename);

446

447

448 if (IsPinnedObject(TableSpaceRelationId, tablespaceoid))

450 tablespacename);

451

452

454 &detail, &detail_log))

456 (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),

457 errmsg("tablespace \"%s\" cannot be dropped because some objects depend on it",

458 tablespacename),

461

462

464

465

466

467

469

471

472

473

474

477

478

479

480

482

483

484

485

486

488

489

490

491

493 {

494

495

496

497

498

499

500

501

502

504

505

506

507

508

509

510

511

512

513

517

518

520 {

521

523 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

524 errmsg("tablespace \"%s\" is not empty",

525 tablespacename)));

526 }

527 }

528

529

530 {

532

533 xlrec.ts_id = tablespaceoid;

534

537

539 }

540

541

542

543

544

545

546

547

548

549

550

551

552

554

555

556

557

559

560

562}

563

564

565

566

567

568

569

570

571static void

573{

574 char *linkloc;

575 char *location_with_version_dir;

576 struct stat st;

577 bool in_place;

578

580

581

582

583

584

585

586 in_place = strlen(location) == 0;

587

588 if (in_place)

589 {

593 errmsg("could not create directory \"%s\": %m",

594 linkloc)));

595 }

596

597 location_with_version_dir = psprintf("%s/%s", in_place ? linkloc : location,

599

600

601

602

603

604

605

607 {

608 if (errno == ENOENT)

610 (errcode(ERRCODE_UNDEFINED_FILE),

611 errmsg("directory \"%s\" does not exist", location),

612 InRecovery ? errhint("Create this directory for the tablespace before "

613 "restarting the server.") : 0));

614 else

617 errmsg("could not set permissions on directory \"%s\": %m",

618 location)));

619 }

620

621

622

623

624

625

626

627

628 if (stat(location_with_version_dir, &st) < 0)

629 {

630 if (errno != ENOENT)

633 errmsg("could not stat directory \"%s\": %m",

634 location_with_version_dir)));

638 errmsg("could not create directory \"%s\": %m",

639 location_with_version_dir)));

640 }

643 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

644 errmsg("\"%s\" exists but is not a directory",

645 location_with_version_dir)));

648 (errcode(ERRCODE_OBJECT_IN_USE),

649 errmsg("directory \"%s\" already in use as a tablespace",

650 location_with_version_dir)));

651

652

653

654

657

658

659

660

661 if (!in_place && symlink(location, linkloc) < 0)

664 errmsg("could not create symbolic link \"%s\": %m",

665 linkloc)));

666

668 pfree(location_with_version_dir);

669}

670

671

672

673

674

675

676

677

678

679

680

681

682

683

684

685static bool

687{

688 char *linkloc;

689 char *linkloc_with_version_dir;

690 DIR *dirdesc;

692 char *subfile;

693 struct stat st;

694

697

698

699

700

701

702

703

704

705

706

707

708

709

710

711

712

713

714

715

716

717

718

719

720 dirdesc = AllocateDir(linkloc_with_version_dir);

721 if (dirdesc == NULL)

722 {

723 if (errno == ENOENT)

724 {

725 if (!redo)

728 errmsg("could not open directory \"%s\": %m",

729 linkloc_with_version_dir)));

730

731 goto remove_symlink;

732 }

733 else if (redo)

734 {

735

738 errmsg("could not open directory \"%s\": %m",

739 linkloc_with_version_dir)));

740 pfree(linkloc_with_version_dir);

741 return false;

742 }

743

744 }

745

746 while ((de = ReadDir(dirdesc, linkloc_with_version_dir)) != NULL)

747 {

748 if (strcmp(de->d_name, ".") == 0 ||

749 strcmp(de->d_name, "..") == 0)

750 continue;

751

752 subfile = psprintf("%s/%s", linkloc_with_version_dir, de->d_name);

753

754

756 {

759 pfree(linkloc_with_version_dir);

760 return false;

761 }

762

763

764 if (rmdir(subfile) < 0)

767 errmsg("could not remove directory \"%s\": %m",

768 subfile)));

769

771 }

772

774

775

776 if (rmdir(linkloc_with_version_dir) < 0)

777 {

780 errmsg("could not remove directory \"%s\": %m",

781 linkloc_with_version_dir)));

782 pfree(linkloc_with_version_dir);

783 return false;

784 }

785

786

787

788

789

790

791

792

793

794

795remove_symlink:

796 linkloc = pstrdup(linkloc_with_version_dir);

798 if (lstat(linkloc, &st) < 0)

799 {

800 int saved_errno = errno;

801

804 errmsg("could not stat file \"%s\": %m",

805 linkloc)));

806 }

808 {

809 if (rmdir(linkloc) < 0)

810 {

811 int saved_errno = errno;

812

815 errmsg("could not remove directory \"%s\": %m",

816 linkloc)));

817 }

818 }

820 {

821 if (unlink(linkloc) < 0)

822 {

823 int saved_errno = errno;

824

827 errmsg("could not remove symbolic link \"%s\": %m",

828 linkloc)));

829 }

830 }

831 else

832 {

833

835 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

836 errmsg("\"%s\" is not a directory or symbolic link",

837 linkloc)));

838 }

839

840 pfree(linkloc_with_version_dir);

842

843 return true;

844}

845

846

847

848

849

850

851

852bool

854{

855 DIR *dirdesc;

857

859

860 while ((de = ReadDir(dirdesc, path)) != NULL)

861 {

862 if (strcmp(de->d_name, ".") == 0 ||

863 strcmp(de->d_name, "..") == 0)

864 continue;

866 return false;

867 }

868

870 return true;

871}

872

873

874

875

876

877

878

879

880

881

882void

884{

885 struct stat st;

886

887 if (lstat(linkloc, &st) < 0)

888 {

889 if (errno == ENOENT)

890 return;

893 errmsg("could not stat file \"%s\": %m", linkloc)));

894 }

895

897 {

898

899

900

901

902 if (rmdir(linkloc) < 0 && errno != ENOENT)

905 errmsg("could not remove directory \"%s\": %m",

906 linkloc)));

907 }

909 {

910 if (unlink(linkloc) < 0 && errno != ENOENT)

913 errmsg("could not remove symbolic link \"%s\": %m",

914 linkloc)));

915 }

916 else

917 {

918

920 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

921 errmsg("\"%s\" is not a directory or symbolic link",

922 linkloc)));

923 }

924}

925

926

927

928

931{

932 Oid tspId;

940

941

943

945 Anum_pg_tablespace_spcname,

952 (errcode(ERRCODE_UNDEFINED_OBJECT),

953 errmsg("tablespace \"%s\" does not exist",

954 oldname)));

955

958 tspId = newform->oid;

959

961

962

965

966

969 (errcode(ERRCODE_RESERVED_NAME),

970 errmsg("unacceptable tablespace name \"%s\"", newname),

971 errdetail("The prefix \"pg_\" is reserved for system tablespaces.")));

972

973

974

975

976

977#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS

978 if (strncmp(newname, "regress_", 8) != 0)

979 elog(WARNING, "tablespaces created by regression test cases should have names starting with \"regress_\"");

980#endif

981

982

984 Anum_pg_tablespace_spcname,

992 errmsg("tablespace \"%s\" already exists",

993 newname)));

994

996

997

998 namestrcpy(&(newform->spcname), newname);

999

1001

1003

1005

1007

1008 return address;

1009}

1010

1011

1012

1013

1016{

1021 Oid tablespaceoid;

1023 Datum newOptions;

1024 Datum repl_val[Natts_pg_tablespace];

1025 bool isnull;

1026 bool repl_null[Natts_pg_tablespace];

1027 bool repl_repl[Natts_pg_tablespace];

1029

1030

1032

1034 Anum_pg_tablespace_spcname,

1041 (errcode(ERRCODE_UNDEFINED_OBJECT),

1042 errmsg("tablespace \"%s\" does not exist",

1043 stmt->tablespacename)));

1044

1046

1047

1050 stmt->tablespacename);

1051

1052

1053 datum = heap_getattr(tup, Anum_pg_tablespace_spcoptions,

1056 stmt->options, NULL, NULL, false,

1057 stmt->isReset);

1059

1060

1061 memset(repl_null, false, sizeof(repl_null));

1062 memset(repl_repl, false, sizeof(repl_repl));

1063 if (newOptions != (Datum) 0)

1064 repl_val[Anum_pg_tablespace_spcoptions - 1] = newOptions;

1065 else

1066 repl_null[Anum_pg_tablespace_spcoptions - 1] = true;

1067 repl_repl[Anum_pg_tablespace_spcoptions - 1] = true;

1069 repl_null, repl_repl);

1070

1071

1073

1075

1077

1078

1081

1082 return tablespaceoid;

1083}

1084

1085

1086

1087

1088

1089

1090bool

1092{

1093

1094

1095

1096

1097

1099 {

1100 if (**newval != '\0' &&

1102 {

1103

1104

1105

1106

1108 {

1110 (errcode(ERRCODE_UNDEFINED_OBJECT),

1111 errmsg("tablespace \"%s\" does not exist",

1113 }

1114 else

1115 {

1118 return false;

1119 }

1120 }

1121 }

1122

1123 return true;

1124}

1125

1126

1127

1128

1129

1130

1131

1132

1133

1134

1135

1136

1137

1138

1139

1140

1141

1144{

1145 Oid result;

1146

1147

1148 if (relpersistence == RELPERSISTENCE_TEMP)

1149 {

1152 }

1153

1154

1157

1158

1159

1160

1161

1162

1163

1164

1166

1167

1168

1169

1170

1171

1172

1174 {

1175 if (partitioned)

1177 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

1178 errmsg("cannot specify default tablespace for partitioned relations")));

1180 }

1181 return result;

1182}

1183

1184

1185

1186

1187

1188

1189typedef struct

1190{

1191

1195

1196

1197bool

1199{

1200 char *rawname;

1201 List *namelist;

1202

1203

1205

1206

1208 {

1209

1213 return false;

1214 }

1215

1216

1217

1218

1219

1220

1221

1223 {

1225 Oid *tblSpcs;

1226 int numSpcs;

1228

1229

1231 numSpcs = 0;

1232 foreach(l, namelist)

1233 {

1234 char *curname = (char *) lfirst(l);

1235 Oid curoid;

1237

1238

1239 if (curname[0] == '\0')

1240 {

1241

1243 continue;

1244 }

1245

1246

1247

1248

1249

1250

1253 {

1256 (errcode(ERRCODE_UNDEFINED_OBJECT),

1257 errmsg("tablespace \"%s\" does not exist",

1258 curname)));

1259 continue;

1260 }

1261

1262

1263

1264

1265

1267 {

1268

1270 continue;

1271 }

1272

1273

1277 {

1280 continue;

1281 }

1282

1283 tblSpcs[numSpcs++] = curoid;

1284 }

1285

1286

1288 numSpcs * sizeof(Oid));

1289 if (!myextra)

1290 return false;

1291 myextra->numSpcs = numSpcs;

1292 memcpy(myextra->tblSpcs, tblSpcs, numSpcs * sizeof(Oid));

1293 *extra = myextra;

1294

1296 }

1297

1300

1301 return true;

1302}

1303

1304

1305void

1307{

1309

1310

1311

1312

1313

1314

1315

1316

1317 if (myextra)

1319 else

1321}

1322

1323

1324

1325

1326

1327

1328

1329

1330void

1332{

1333 char *rawname;

1334 List *namelist;

1335 Oid *tblSpcs;

1336 int numSpcs;

1338

1339

1341 return;

1342

1343

1344

1345

1346

1347

1348

1349

1351 return;

1352

1353

1355

1356

1358 {

1359

1363 return;

1364 }

1365

1366

1369 numSpcs = 0;

1370 foreach(l, namelist)

1371 {

1372 char *curname = (char *) lfirst(l);

1373 Oid curoid;

1375

1376

1377 if (curname[0] == '\0')

1378 {

1379

1381 continue;

1382 }

1383

1384

1387 {

1388

1389 continue;

1390 }

1391

1392

1393

1394

1395

1397 {

1398

1400 continue;

1401 }

1402

1403

1407 continue;

1408

1409 tblSpcs[numSpcs++] = curoid;

1410 }

1411

1413

1416}

1417

1418

1419

1420

1421

1422

1423

1424

1427{

1428 Oid result;

1433

1434

1435

1436

1437

1438

1440

1442 Anum_pg_tablespace_spcname,

1447

1448

1451 else

1453

1456

1457 if (OidIsValid(result) && !missing_ok)

1459 (errcode(ERRCODE_UNDEFINED_OBJECT),

1460 errmsg("tablespace \"%s\" does not exist",

1461 tablespacename)));

1462

1463 return result;

1464}

1465

1466

1467

1468

1469

1470

1471char *

1473{

1474 char *result;

1479

1480

1481

1482

1483

1484

1486

1488 Anum_pg_tablespace_oid,

1493

1494

1497 else

1498 result = NULL;

1499

1502

1503 return result;

1504}

1505

1506

1507

1508

1509

1510void

1512{

1514

1515

1517

1519 {

1521 char *location = xlrec->ts_path;

1522

1524 }

1526 {

1528

1529

1531

1532

1533

1534

1535

1536

1537

1538

1539

1540

1541

1542

1543

1544

1545

1546

1548 {

1550

1551

1552

1553

1554

1555

1556

1557

1558

1561 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

1562 errmsg("directories for tablespace %u could not be removed",

1564 errhint("You can remove the directories manually if necessary.")));

1565 }

1566 }

1567 else

1568 elog(PANIC, "tblspc_redo: unknown op code %u", info);

1569}

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 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 errdetail_internal(const char *fmt,...)

int errcode_for_file_access(void)

int errdetail(const char *fmt,...)

int errhint(const char *fmt,...)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

int errdetail_log(const char *fmt,...)

#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

Assert(PointerIsAligned(start, uint64))

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, ItemPointer otid, HeapTuple tup)

void CatalogTupleInsert(Relation heapRel, HeapTuple tup)

void CatalogTupleDelete(Relation heapRel, ItemPointer 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)

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 *namspace, 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, struct 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)

#define CHECKPOINT_IMMEDIATE

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)