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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

21

22#include <fcntl.h>

24#include <sys/stat.h>

25

66#include "utils/fmgroids.h"

71

72

73

74

75

76

77

78

79

80

81

83{

87

88typedef struct

89{

94

95typedef struct

96{

100

101

102

103

105{

108 bool permanent;

110

111

112

114static void movedb(const char *dbname, const char *tblspcname);

117 Oid *dbIdP, Oid *ownerIdP,

118 int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, bool *dbHasLoginEvtP,

120 Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbLocale,

121 char **dbIcurules,

122 char *dbLocProvider,

123 char **dbCollversion);

126static int errdetail_busy_db(int notherbackends, int npreparedxacts);

128 Oid dst_tsid);

131 Oid dbid, char *srcpath,

135 char *srcpath);

137 bool isRedo);

139 Oid src_tsid, Oid dst_tsid);

141

142

143

144

145

146

147static void

149 Oid src_tsid, Oid dst_tsid)

150{

151 char *srcpath;

153 List *rlocatorlist = NULL;

160

161

164

165

167

168

170

171

174

175

176

177

178

179 srcrelid.dbId = src_dboid;

180 dstrelid.dbId = dst_dboid;

181

182

183 foreach(cell, rlocatorlist)

184 {

185 relinfo = lfirst(cell);

186 srcrlocator = relinfo->rlocator;

187

188

189

190

191

192

193

194 if (srcrlocator.spcOid == src_tsid)

195 dstrlocator.spcOid = dst_tsid;

196 else

198

199 dstrlocator.dbOid = dst_dboid;

201

202

203

204

205

206

207

208

209

210

214

215

217

218

221 }

222

226}

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

251{

258 List *rlocatorlist = NIL;

263

264

266 RelationRelationId);

267

268

269 relid.dbId = dbid;

270 relid.relId = RelationRelationId;

272

273

274 rlocator.spcOid = tbid;

275 rlocator.dbOid = dbid;

276 rlocator.relNumber = relfilenumber;

277

281

282

284

285

286

287

288

289

290

292

293

294 for (blkno = 0; blkno < nblocks; blkno++)

295 {

297

300

304 {

306 continue;

307 }

308

309

311 srcpath, rlocatorlist,

312 snapshot);

313

315 }

317

318

320

321 return rlocatorlist;

322}

323

324

325

326

327

330 char *srcpath, List *rlocatorlist,

332{

337

339

340

342 offnum <= maxoff;

344 {

346

348

349

352 continue;

353

356

357

360 tuple.t_tableOid = RelationRelationId;

361

362

364 {

366

367

368

369

370

371

372

374 srcpath);

375 if (relinfo != NULL)

376 rlocatorlist = lappend(rlocatorlist, relinfo);

377 }

378 }

379

380 return rlocatorlist;

381}

382

383

384

385

386

387

388

389

390

393 char *srcpath)

394{

398

400

401

402

403

404

405

406

407

408

409

410

411

412 if (classForm->reltablespace == GLOBALTABLESPACE_OID ||

413 !RELKIND_HAS_STORAGE(classForm->relkind) ||

414 classForm->relpersistence == RELPERSISTENCE_TEMP)

415 return NULL;

416

417

418

419

420

422 relfilenumber = classForm->relfilenode;

423 else

425 classForm->oid);

426

427

429 elog(ERROR, "relation with OID %u does not have a valid relfilenumber",

430 classForm->oid);

431

432

434 if (OidIsValid(classForm->reltablespace))

436 else

438

441 relinfo->reloid = classForm->oid;

442

443

444 Assert(classForm->relpersistence != RELPERSISTENCE_TEMP);

446 (classForm->relpersistence == RELPERSISTENCE_PERMANENT) ? true : false;

447

448 return relinfo;

449}

450

451

452

453

454

455

456static void

458{

459 int fd;

460 int nbytes;

462 char buf[16];

463

464

465

466

467

468 sprintf(buf, "%s\n", PG_MAJORVERSION);

469 nbytes = strlen(PG_MAJORVERSION) + 1;

470

471

473 {

474

475 if (errno != EEXIST || !isRedo)

478 errmsg("could not create directory \"%s\": %m", dbpath)));

479 }

480

481

482

483

484

485

486 snprintf(versionfile, sizeof(versionfile), "%s/%s", dbpath, "PG_VERSION");

487

489 if (fd < 0 && errno == EEXIST && isRedo)

491

492 if (fd < 0)

495 errmsg("could not create file \"%s\": %m", versionfile)));

496

497

499 errno = 0;

500 if ((int) write(fd, buf, nbytes) != nbytes)

501 {

502

503 if (errno == 0)

504 errno = ENOSPC;

507 errmsg("could not write to file \"%s\": %m", versionfile)));

508 }

510

515 errmsg("could not fsync file \"%s\": %m", versionfile)));

518

519

521

522

523 if (!isRedo)

524 {

526

528

529 xlrec.db_id = dbid;

531

535

537

539 }

540}

541

542

543

544

545

546

547

548

549

550static void

552 Oid dst_tsid)

553{

557

558

559

560

561

562

563

564

565

566

567

568

569

570

571

575

576

577

578

579

583 {

585 Oid srctablespace = spaceform->oid;

586 Oid dsttablespace;

587 char *srcpath;

589 struct stat st;

590

591

592 if (srctablespace == GLOBALTABLESPACE_OID)

593 continue;

594

596

599 {

600

602 continue;

603 }

604

605 if (srctablespace == src_tsid)

606 dsttablespace = dst_tsid;

607 else

608 dsttablespace = srctablespace;

609

611

612

613

614

615

616

618

619

620 {

622

623 xlrec.db_id = dst_dboid;

627

631

634 }

637 }

640

641

642

643

644

645

646

647

648

649

650

651

652

653

654

655

656

657

658

659

660

661

662

663

664

665

666

667

668

669

670

671

672

673

674

678}

679

680

681

682

685{

686 Oid src_dboid;

687 Oid src_owner;

688 int src_encoding = -1;

689 char *src_collate = NULL;

690 char *src_ctype = NULL;

691 char *src_locale = NULL;

692 char *src_icurules = NULL;

693 char src_locprovider = '\0';

694 char *src_collversion = NULL;

695 bool src_istemplate;

696 bool src_hasloginevt = false;

697 bool src_allowconn;

700 Oid src_deftablespace;

701 volatile Oid dst_deftablespace;

704 Datum new_record[Natts_pg_database] = {0};

705 bool new_record_nulls[Natts_pg_database] = {0};

707 Oid datdba;

709 DefElem *tablespacenameEl = NULL;

711 DefElem *templateEl = NULL;

712 DefElem *encodingEl = NULL;

713 DefElem *localeEl = NULL;

714 DefElem *builtinlocaleEl = NULL;

715 DefElem *collateEl = NULL;

717 DefElem *iculocaleEl = NULL;

718 DefElem *icurulesEl = NULL;

719 DefElem *locproviderEl = NULL;

720 DefElem *istemplateEl = NULL;

721 DefElem *allowconnectionsEl = NULL;

722 DefElem *connlimitEl = NULL;

723 DefElem *collversionEl = NULL;

724 DefElem *strategyEl = NULL;

726 char *dbowner = NULL;

727 const char *dbtemplate = NULL;

728 char *dbcollate = NULL;

729 char *dbctype = NULL;

730 const char *dblocale = NULL;

731 char *dbicurules = NULL;

732 char dblocprovider = '\0';

733 char *canonname;

735 bool dbistemplate = false;

736 bool dballowconnections = true;

738 char *dbcollversion = NULL;

739 int notherbackends;

740 int npreparedxacts;

743

744

746 {

748

749 if (strcmp(defel->defname, "tablespace") == 0)

750 {

751 if (tablespacenameEl)

753 tablespacenameEl = defel;

754 }

755 else if (strcmp(defel->defname, "owner") == 0)

756 {

757 if (ownerEl)

759 ownerEl = defel;

760 }

761 else if (strcmp(defel->defname, "template") == 0)

762 {

763 if (templateEl)

765 templateEl = defel;

766 }

767 else if (strcmp(defel->defname, "encoding") == 0)

768 {

769 if (encodingEl)

771 encodingEl = defel;

772 }

773 else if (strcmp(defel->defname, "locale") == 0)

774 {

775 if (localeEl)

777 localeEl = defel;

778 }

779 else if (strcmp(defel->defname, "builtin_locale") == 0)

780 {

781 if (builtinlocaleEl)

783 builtinlocaleEl = defel;

784 }

785 else if (strcmp(defel->defname, "lc_collate") == 0)

786 {

787 if (collateEl)

789 collateEl = defel;

790 }

791 else if (strcmp(defel->defname, "lc_ctype") == 0)

792 {

793 if (ctypeEl)

795 ctypeEl = defel;

796 }

797 else if (strcmp(defel->defname, "icu_locale") == 0)

798 {

799 if (iculocaleEl)

801 iculocaleEl = defel;

802 }

803 else if (strcmp(defel->defname, "icu_rules") == 0)

804 {

805 if (icurulesEl)

807 icurulesEl = defel;

808 }

809 else if (strcmp(defel->defname, "locale_provider") == 0)

810 {

811 if (locproviderEl)

813 locproviderEl = defel;

814 }

815 else if (strcmp(defel->defname, "is_template") == 0)

816 {

817 if (istemplateEl)

819 istemplateEl = defel;

820 }

821 else if (strcmp(defel->defname, "allow_connections") == 0)

822 {

823 if (allowconnectionsEl)

825 allowconnectionsEl = defel;

826 }

827 else if (strcmp(defel->defname, "connection_limit") == 0)

828 {

829 if (connlimitEl)

831 connlimitEl = defel;

832 }

833 else if (strcmp(defel->defname, "collation_version") == 0)

834 {

835 if (collversionEl)

837 collversionEl = defel;

838 }

839 else if (strcmp(defel->defname, "location") == 0)

840 {

842 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

843 errmsg("LOCATION is not supported anymore"),

844 errhint("Consider using tablespaces instead."),

846 }

847 else if (strcmp(defel->defname, "oid") == 0)

848 {

850

851

852

853

854

855

856

857

858

859

860

861

862

863

864

868 (errcode(ERRCODE_INVALID_PARAMETER_VALUE)),

870 }

871 else if (strcmp(defel->defname, "strategy") == 0)

872 {

873 if (strategyEl)

875 strategyEl = defel;

876 }

877 else

879 (errcode(ERRCODE_SYNTAX_ERROR),

880 errmsg("option \"%s\" not recognized", defel->defname),

882 }

883

884 if (ownerEl && ownerEl->arg)

886 if (templateEl && templateEl->arg)

888 if (encodingEl && encodingEl->arg)

889 {

890 const char *encoding_name;

891

893 {

896 if (strcmp(encoding_name, "") == 0 ||

899 (errcode(ERRCODE_UNDEFINED_OBJECT),

900 errmsg("%d is not a valid encoding code",

903 }

904 else

905 {

910 (errcode(ERRCODE_UNDEFINED_OBJECT),

911 errmsg("%s is not a valid encoding name",

912 encoding_name),

914 }

915 }

916 if (localeEl && localeEl->arg)

917 {

921 }

922 if (builtinlocaleEl && builtinlocaleEl->arg)

924 if (collateEl && collateEl->arg)

926 if (ctypeEl && ctypeEl->arg)

928 if (iculocaleEl && iculocaleEl->arg)

930 if (icurulesEl && icurulesEl->arg)

932 if (locproviderEl && locproviderEl->arg)

933 {

934 char *locproviderstr = defGetString(locproviderEl);

935

936 if (pg_strcasecmp(locproviderstr, "builtin") == 0)

937 dblocprovider = COLLPROVIDER_BUILTIN;

938 else if (pg_strcasecmp(locproviderstr, "icu") == 0)

939 dblocprovider = COLLPROVIDER_ICU;

940 else if (pg_strcasecmp(locproviderstr, "libc") == 0)

941 dblocprovider = COLLPROVIDER_LIBC;

942 else

944 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

945 errmsg("unrecognized locale provider: %s",

946 locproviderstr)));

947 }

948 if (istemplateEl && istemplateEl->arg)

950 if (allowconnectionsEl && allowconnectionsEl->arg)

951 dballowconnections = defGetBoolean(allowconnectionsEl);

952 if (connlimitEl && connlimitEl->arg)

953 {

957 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

958 errmsg("invalid connection limit: %d", dbconnlimit)));

959 }

960 if (collversionEl)

962

963

964 if (dbowner)

966 else

968

969

970

971

972

973

974

975

978 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

979 errmsg("permission denied to create database")));

980

982

983

984

985

986

987

988

989

990

991

992 if (!dbtemplate)

993 dbtemplate = "template1";

994

996 &src_dboid, &src_owner, &src_encoding,

997 &src_istemplate, &src_allowconn, &src_hasloginevt,

998 &src_frozenxid, &src_minmxid, &src_deftablespace,

999 &src_collate, &src_ctype, &src_locale, &src_icurules, &src_locprovider,

1000 &src_collversion))

1002 (errcode(ERRCODE_UNDEFINED_DATABASE),

1003 errmsg("template database \"%s\" does not exist",

1004 dbtemplate)));

1005

1006

1007

1008

1009

1012 errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

1013 errmsg("cannot use invalid database \"%s\" as template", dbtemplate),

1014 errhint("Use DROP DATABASE to drop invalid databases."));

1015

1016

1017

1018

1019

1020 if (!src_istemplate)

1021 {

1024 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

1025 errmsg("permission denied to copy database \"%s\"",

1026 dbtemplate)));

1027 }

1028

1029

1030 if (strategyEl && strategyEl->arg)

1031 {

1032 char *strategy;

1033

1037 else if (pg_strcasecmp(strategy, "file_copy") == 0)

1039 else

1041 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1042 errmsg("invalid create database strategy \"%s\"", strategy),

1043 errhint("Valid strategies are \"wal_log\" and \"file_copy\".")));

1044 }

1045

1046

1049 if (dbcollate == NULL)

1050 dbcollate = src_collate;

1051 if (dbctype == NULL)

1052 dbctype = src_ctype;

1053 if (dblocprovider == '\0')

1054 dblocprovider = src_locprovider;

1055 if (dblocale == NULL)

1056 dblocale = src_locale;

1057 if (dbicurules == NULL)

1058 dbicurules = src_icurules;

1059

1060

1063 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

1065

1066

1067 if (check\_locale(LC_COLLATE, dbcollate, &canonname))

1069 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

1070 errmsg("invalid LC_COLLATE locale name: \"%s\"", dbcollate),

1071 errhint("If the locale name is specific to ICU, use ICU_LOCALE.")));

1072 dbcollate = canonname;

1073 if (check\_locale(LC_CTYPE, dbctype, &canonname))

1075 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

1076 errmsg("invalid LC_CTYPE locale name: \"%s\"", dbctype),

1077 errhint("If the locale name is specific to ICU, use ICU_LOCALE.")));

1078 dbctype = canonname;

1079

1081

1082

1083 if (dblocprovider != COLLPROVIDER_BUILTIN)

1084 {

1085 if (builtinlocaleEl)

1087 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1088 errmsg("BUILTIN_LOCALE cannot be specified unless locale provider is builtin")));

1089 }

1090

1091 if (dblocprovider != COLLPROVIDER_ICU)

1092 {

1093 if (iculocaleEl)

1095 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1096 errmsg("ICU locale cannot be specified unless locale provider is ICU")));

1097

1098 if (dbicurules)

1100 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),

1101 errmsg("ICU rules cannot be specified unless locale provider is ICU")));

1102 }

1103

1104

1105 if (dblocprovider == COLLPROVIDER_BUILTIN)

1106 {

1107

1108

1109

1110

1111 if (!dblocale)

1113 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1114 errmsg("LOCALE or BUILTIN_LOCALE must be specified")));

1115

1117 }

1118 else if (dblocprovider == COLLPROVIDER_ICU)

1119 {

1122 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1123 errmsg("encoding \"%s\" is not supported with ICU provider",

1125

1126

1127

1128

1129

1130 if (!dblocale)

1132 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1133 errmsg("LOCALE or ICU_LOCALE must be specified")));

1134

1135

1136

1137

1138

1139

1141 {

1144

1145 if (langtag && strcmp(dblocale, langtag) != 0)

1146 {

1148 (errmsg("using standard form \"%s\" for ICU locale \"%s\"",

1149 langtag, dblocale)));

1150

1151 dblocale = langtag;

1152 }

1153 }

1154

1156 }

1157

1158

1159 if (dblocprovider == COLLPROVIDER_LIBC)

1160 dblocale = NULL;

1161

1162

1163

1164

1165

1166

1167

1168

1169

1170

1171

1172 if (strcmp(dbtemplate, "template0") != 0)

1173 {

1174 if (encoding != src_encoding)

1176 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1177 errmsg("new encoding (%s) is incompatible with the encoding of the template database (%s)",

1180 errhint("Use the same encoding as in the template database, or use template0 as template.")));

1181

1182 if (strcmp(dbcollate, src_collate) != 0)

1184 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1185 errmsg("new collation (%s) is incompatible with the collation of the template database (%s)",

1186 dbcollate, src_collate),

1187 errhint("Use the same collation as in the template database, or use template0 as template.")));

1188

1189 if (strcmp(dbctype, src_ctype) != 0)

1191 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1192 errmsg("new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database (%s)",

1193 dbctype, src_ctype),

1194 errhint("Use the same LC_CTYPE as in the template database, or use template0 as template.")));

1195

1196 if (dblocprovider != src_locprovider)

1198 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1199 errmsg("new locale provider (%s) does not match locale provider of the template database (%s)",

1200 collprovider_name(dblocprovider), collprovider_name(src_locprovider)),

1201 errhint("Use the same locale provider as in the template database, or use template0 as template.")));

1202

1203 if (dblocprovider == COLLPROVIDER_ICU)

1204 {

1205 char *val1;

1206 char *val2;

1207

1210 if (strcmp(dblocale, src_locale) != 0)

1212 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1213 errmsg("new ICU locale (%s) is incompatible with the ICU locale of the template database (%s)",

1214 dblocale, src_locale),

1215 errhint("Use the same ICU locale as in the template database, or use template0 as template.")));

1216

1217 val1 = dbicurules;

1218 if (!val1)

1219 val1 = "";

1220 val2 = src_icurules;

1221 if (!val2)

1222 val2 = "";

1223 if (strcmp(val1, val2) != 0)

1225 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1226 errmsg("new ICU collation rules (%s) are incompatible with the ICU collation rules of the template database (%s)",

1227 val1, val2),

1228 errhint("Use the same ICU collation rules as in the template database, or use template0 as template.")));

1229 }

1230 }

1231

1232

1233

1234

1235

1236

1237

1238

1239

1240

1241

1242

1243

1244 if (src_collversion && !collversionEl)

1245 {

1246 char *actual_versionstr;

1248

1249 if (dblocprovider == COLLPROVIDER_LIBC)

1251 else

1253

1255 if (!actual_versionstr)

1257 (errmsg("template database \"%s\" has a collation version, but no actual collation version could be determined",

1258 dbtemplate)));

1259

1260 if (strcmp(actual_versionstr, src_collversion) != 0)

1262 (errmsg("template database \"%s\" has a collation version mismatch",

1263 dbtemplate),

1264 errdetail("The template database was created using collation version %s, "

1265 "but the operating system provides version %s.",

1266 src_collversion, actual_versionstr),

1267 errhint("Rebuild all objects in the template database that use the default collation and run "

1268 "ALTER DATABASE %s REFRESH COLLATION VERSION, "

1269 "or build PostgreSQL with the right library version.",

1271 }

1272

1273 if (dbcollversion == NULL)

1274 dbcollversion = src_collversion;

1275

1276

1277

1278

1279

1280

1281 if (dbcollversion == NULL)

1282 {

1284

1285 if (dblocprovider == COLLPROVIDER_LIBC)

1287 else

1289

1291 }

1292

1293

1294 if (tablespacenameEl && tablespacenameEl->arg)

1295 {

1296 char *tablespacename;

1298

1299 tablespacename = defGetString(tablespacenameEl);

1301

1306 tablespacename);

1307

1308

1309 if (dst_deftablespace == GLOBALTABLESPACE_OID)

1311 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1312 errmsg("pg_global cannot be used as default tablespace")));

1313

1314

1315

1316

1317

1318

1319

1320

1321

1322

1323

1324

1325

1326 if (dst_deftablespace != src_deftablespace)

1327 {

1328 char *srcpath;

1329 struct stat st;

1330

1331 srcpath = GetDatabasePath(src_dboid, dst_deftablespace);

1332

1333 if (stat(srcpath, &st) == 0 &&

1337 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

1338 errmsg("cannot assign new default tablespace \"%s\"",

1339 tablespacename),

1340 errdetail("There is a conflict because database \"%s\" already has some tables in this tablespace.",

1341 dbtemplate)));

1343 }

1344 }

1345 else

1346 {

1347

1348 dst_deftablespace = src_deftablespace;

1349

1350 }

1351

1352

1353

1354

1355

1356

1357#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS

1359 elog(WARNING, "databases created by regression test cases should have names including \"regression\"");

1360#endif

1361

1362

1363

1364

1365

1366

1369 (errcode(ERRCODE_DUPLICATE_DATABASE),

1370 errmsg("database \"%s\" already exists", dbname)));

1371

1372

1373

1374

1375

1376

1377

1378

1379

1380

1383 (errcode(ERRCODE_OBJECT_IN_USE),

1384 errmsg("source database \"%s\" is being accessed by other users",

1385 dbtemplate),

1387

1388

1389

1390

1391

1392

1394

1395

1396

1397

1398

1400 {

1402

1403 if (existing_dbname != NULL)

1405 (errcode(ERRCODE_INVALID_PARAMETER_VALUE)),

1406 errmsg("database OID %u is already in use by database \"%s\"",

1407 dboid, existing_dbname));

1408

1411 (errcode(ERRCODE_INVALID_PARAMETER_VALUE)),

1412 errmsg("data directory with the specified OID %u already exists", dboid));

1413 }

1414 else

1415 {

1416

1417 do

1418 {

1420 Anum_pg_database_oid);

1422 }

1423

1424

1425

1426

1427

1428

1429

1430 Assert((dblocprovider != COLLPROVIDER_LIBC && dblocale) ||

1431 (dblocprovider == COLLPROVIDER_LIBC && !dblocale));

1432

1433

1434 new_record[Anum_pg_database_oid - 1] = ObjectIdGetDatum(dboid);

1435 new_record[Anum_pg_database_datname - 1] =

1437 new_record[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(datdba);

1439 new_record[Anum_pg_database_datlocprovider - 1] = CharGetDatum(dblocprovider);

1440 new_record[Anum_pg_database_datistemplate - 1] = BoolGetDatum(dbistemplate);

1441 new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(dballowconnections);

1442 new_record[Anum_pg_database_dathasloginevt - 1] = BoolGetDatum(src_hasloginevt);

1443 new_record[Anum_pg_database_datconnlimit - 1] = Int32GetDatum(dbconnlimit);

1444 new_record[Anum_pg_database_datfrozenxid - 1] = TransactionIdGetDatum(src_frozenxid);

1445 new_record[Anum_pg_database_datminmxid - 1] = TransactionIdGetDatum(src_minmxid);

1446 new_record[Anum_pg_database_dattablespace - 1] = ObjectIdGetDatum(dst_deftablespace);

1447 new_record[Anum_pg_database_datcollate - 1] = CStringGetTextDatum(dbcollate);

1448 new_record[Anum_pg_database_datctype - 1] = CStringGetTextDatum(dbctype);

1449 if (dblocale)

1450 new_record[Anum_pg_database_datlocale - 1] = CStringGetTextDatum(dblocale);

1451 else

1452 new_record_nulls[Anum_pg_database_datlocale - 1] = true;

1453 if (dbicurules)

1454 new_record[Anum_pg_database_daticurules - 1] = CStringGetTextDatum(dbicurules);

1455 else

1456 new_record_nulls[Anum_pg_database_daticurules - 1] = true;

1457 if (dbcollversion)

1458 new_record[Anum_pg_database_datcollversion - 1] = CStringGetTextDatum(dbcollversion);

1459 else

1460 new_record_nulls[Anum_pg_database_datcollversion - 1] = true;

1461

1462

1463

1464

1465

1466

1467 new_record_nulls[Anum_pg_database_datacl - 1] = true;

1468

1470 new_record, new_record_nulls);

1471

1473

1474

1475

1476

1477

1478

1480

1481

1483

1484

1486

1487

1488

1489

1490

1491

1492

1493

1494

1495

1496

1497

1500

1501

1502

1503

1504

1505

1506

1507

1510 fparms.strategy = dbstrategy;

1511

1514 {

1515

1516

1517

1518

1519

1520

1521

1524 dst_deftablespace);

1525 else

1527 dst_deftablespace);

1528

1529

1530

1531

1533

1534

1535

1536

1537

1538

1539

1541 }

1544

1545 return dboid;

1546}

1547

1548

1549

1550

1551

1552

1553

1554

1555

1556

1557

1558

1559

1560

1561

1562

1563

1564

1565

1566

1567

1568

1569

1570void

1572{

1575

1576 if (!(ctype_encoding == encoding ||

1578 ctype_encoding == -1 ||

1579#ifdef WIN32

1581#endif

1584 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1585 errmsg("encoding \"%s\" does not match locale \"%s\"",

1587 ctype),

1588 errdetail("The chosen LC_CTYPE setting requires encoding \"%s\".",

1590

1591 if (!(collate_encoding == encoding ||

1593 collate_encoding == -1 ||

1594#ifdef WIN32

1596#endif

1599 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1600 errmsg("encoding \"%s\" does not match locale \"%s\"",

1602 collate),

1603 errdetail("The chosen LC_COLLATE setting requires encoding \"%s\".",

1605}

1606

1607

1608static void

1610{

1612

1613

1614

1615

1616

1617

1618

1619

1620

1621

1623 {

1626

1627

1630 }

1631

1632

1633

1634

1635

1636

1638

1639

1641}

1642

1643

1644

1645

1646

1647void

1649{

1650 Oid db_id;

1651 bool db_istemplate;

1655 void *inplace_state;

1657 int notherbackends;

1658 int npreparedxacts;

1659 int nslots,

1660 nslots_active;

1661 int nsubscriptions;

1662

1663

1664

1665

1666

1667

1668

1669

1671

1673 &db_istemplate, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL))

1674 {

1675 if (!missing_ok)

1676 {

1678 (errcode(ERRCODE_UNDEFINED_DATABASE),

1679 errmsg("database \"%s\" does not exist", dbname)));

1680 }

1681 else

1682 {

1683

1686 (errmsg("database \"%s\" does not exist, skipping",

1688 return;

1689 }

1690 }

1691

1692

1693

1694

1698

1699

1701

1702

1703

1704

1705

1706

1707 if (db_istemplate)

1709 (errcode(ERRCODE_WRONG_OBJECT_TYPE),

1710 errmsg("cannot drop a template database")));

1711

1712

1715 (errcode(ERRCODE_OBJECT_IN_USE),

1716 errmsg("cannot drop the currently open database")));

1717

1718

1719

1720

1721

1722

1723

1725 if (nslots_active)

1726 {

1728 (errcode(ERRCODE_OBJECT_IN_USE),

1729 errmsg("database \"%s\" is used by an active logical replication slot",

1732 "There are %d active slots.",

1733 nslots_active, nslots_active)));

1734 }

1735

1736

1737

1738

1739

1740

1741

1744 (errcode(ERRCODE_OBJECT_IN_USE),

1745 errmsg("database \"%s\" is being used by logical replication subscription",

1748 "There are %d subscriptions.",

1749 nsubscriptions, nsubscriptions)));

1750

1751

1752

1753

1754

1755

1756 if (force)

1758

1759

1760

1761

1762

1763

1764

1767 (errcode(ERRCODE_OBJECT_IN_USE),

1768 errmsg("database \"%s\" is being accessed by other users",

1771

1772

1773

1774

1777

1778

1779

1780

1782

1783

1784

1785

1787

1788

1789

1790

1792

1793

1794

1795

1796

1797

1798

1799

1800

1801

1802

1803

1805 Anum_pg_database_datname,

1809 NULL, 1, &scankey, &tup, &inplace_state);

1811 elog(ERROR, "cache lookup failed for database %u", db_id);

1816

1817

1818

1819

1820

1823

1824

1825

1826

1828

1829

1830

1831

1832

1833

1835

1836

1837

1838

1839

1840

1841

1843

1844

1845

1846

1847

1849

1850

1852

1853

1854

1855

1857

1858

1859

1860

1862

1863

1864

1865

1866

1867

1868

1870}

1871

1872

1873

1874

1875

1878{

1879 Oid db_id;

1883 int notherbackends;

1884 int npreparedxacts;

1886

1887

1888

1889

1890

1892

1894 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL))

1896 (errcode(ERRCODE_UNDEFINED_DATABASE),

1897 errmsg("database \"%s\" does not exist", oldname)));

1898

1899

1902 oldname);

1903

1904

1907 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

1908 errmsg("permission denied to rename database")));

1909

1910

1911

1912

1913

1914#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS

1915 if (strstr(newname, "regression") == NULL)

1916 elog(WARNING, "databases created by regression test cases should have names including \"regression\"");

1917#endif

1918

1919

1920

1921

1922

1925 (errcode(ERRCODE_DUPLICATE_DATABASE),

1926 errmsg("database \"%s\" already exists", newname)));

1927

1928

1929

1930

1931

1932

1933

1936 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

1937 errmsg("current database cannot be renamed")));

1938

1939

1940

1941

1942

1943

1944

1947 (errcode(ERRCODE_OBJECT_IN_USE),

1948 errmsg("database \"%s\" is being accessed by other users",

1949 oldname),

1951

1952

1955 elog(ERROR, "cache lookup failed for database %u", db_id);

1956 otid = newtup->t_self;

1960

1962

1964

1965

1966

1967

1969

1970 return address;

1971}

1972

1973

1974

1975

1976

1977static void

1979{

1980 Oid db_id;

1982 int notherbackends;

1983 int npreparedxacts;

1985 newtuple;

1986 Oid src_tblspcoid,

1987 dst_tblspcoid;

1991 char *src_dbpath;

1992 char *dst_dbpath;

1993 DIR *dstdir;

1994 struct dirent *xlde;

1996

1997

1998

1999

2000

2001

2002

2004

2006 NULL, NULL, NULL, NULL, &src_tblspcoid, NULL, NULL, NULL, NULL, NULL, NULL))

2008 (errcode(ERRCODE_UNDEFINED_DATABASE),

2009 errmsg("database \"%s\" does not exist", dbname)));

2010

2011

2012

2013

2014

2015

2016

2019

2020

2021

2022

2026

2027

2028

2029

2032 (errcode(ERRCODE_OBJECT_IN_USE),

2033 errmsg("cannot change the tablespace of the currently open database")));

2034

2035

2036

2037

2039

2040

2041

2042

2047 tblspcname);

2048

2049

2050

2051

2052 if (dst_tblspcoid == GLOBALTABLESPACE_OID)

2054 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

2055 errmsg("pg_global cannot be used as default tablespace")));

2056

2057

2058

2059

2060 if (src_tblspcoid == dst_tblspcoid)

2061 {

2065 return;

2066 }

2067

2068

2069

2070

2071

2072

2073

2076 (errcode(ERRCODE_OBJECT_IN_USE),

2077 errmsg("database \"%s\" is being accessed by other users",

2080

2081

2082

2083

2086

2087

2088

2089

2090

2091

2092

2093

2094

2095

2096

2097

2100

2101

2103

2104

2105

2106

2107

2108

2109

2110

2111

2112

2113

2114

2115

2116

2117

2118

2120

2121

2122

2123

2124

2125

2126

2127

2129 if (dstdir != NULL)

2130 {

2131 while ((xlde = ReadDir(dstdir, dst_dbpath)) != NULL)

2132 {

2133 if (strcmp(xlde->d_name, ".") == 0 ||

2134 strcmp(xlde->d_name, "..") == 0)

2135 continue;

2136

2138 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

2139 errmsg("some relations of database \"%s\" are already in tablespace \"%s\"",

2140 dbname, tblspcname),

2141 errhint("You must move them back to the database's default tablespace before using this command.")));

2142 }

2143

2145

2146

2147

2148

2149

2150 if (rmdir(dst_dbpath) != 0)

2151 elog(ERROR, "could not remove directory \"%s\": %m",

2152 dst_dbpath);

2153 }

2154

2155

2156

2157

2158

2159

2160

2165 {

2166 Datum new_record[Natts_pg_database] = {0};

2167 bool new_record_nulls[Natts_pg_database] = {0};

2168 bool new_record_repl[Natts_pg_database] = {0};

2169

2170

2171

2172

2173 copydir(src_dbpath, dst_dbpath, false);

2174

2175

2176

2177

2178 {

2180

2181 xlrec.db_id = db_id;

2185

2189

2192 }

2193

2194

2195

2196

2198 Anum_pg_database_datname,

2202 NULL, 1, &scankey);

2206 (errcode(ERRCODE_UNDEFINED_DATABASE),

2207 errmsg("database \"%s\" does not exist", dbname)));

2209

2210 new_record[Anum_pg_database_dattablespace - 1] = ObjectIdGetDatum(dst_tblspcoid);

2211 new_record_repl[Anum_pg_database_dattablespace - 1] = true;

2212

2214 new_record,

2215 new_record_nulls, new_record_repl);

2218

2220

2222

2223

2224

2225

2226

2227

2228

2229

2231

2232

2233

2234

2235

2236

2237

2239

2240

2241

2242

2244 }

2247

2248

2249

2250

2251

2252

2253

2254

2255

2256

2257

2258

2261

2262

2264

2265

2266

2267

2268 if (rmtree(src_dbpath, true))

2270 (errmsg("some useless files may be left behind in old database directory \"%s\"",

2271 src_dbpath)));

2272

2273

2274

2275

2276 {

2278

2279 xlrec.db_id = db_id;

2281

2285

2288 }

2289

2290

2293

2294 pfree(src_dbpath);

2295 pfree(dst_dbpath);

2296}

2297

2298

2299static void

2301{

2304

2305

2307

2309

2311}

2312

2313

2314

2315

2316void

2318{

2319 bool force = false;

2321

2322 foreach(lc, stmt->options)

2323 {

2325

2326 if (strcmp(opt->defname, "force") == 0)

2327 force = true;

2328 else

2330 (errcode(ERRCODE_SYNTAX_ERROR),

2331 errmsg("unrecognized DROP DATABASE option \"%s\"", opt->defname),

2333 }

2334

2336}

2337

2338

2339

2340

2343{

2345 Oid dboid;

2347 newtuple;

2352 bool dbistemplate = false;

2353 bool dballowconnections = true;

2355 DefElem *distemplate = NULL;

2356 DefElem *dallowconnections = NULL;

2357 DefElem *dconnlimit = NULL;

2358 DefElem *dtablespace = NULL;

2359 Datum new_record[Natts_pg_database] = {0};

2360 bool new_record_nulls[Natts_pg_database] = {0};

2361 bool new_record_repl[Natts_pg_database] = {0};

2362

2363

2365 {

2367

2368 if (strcmp(defel->defname, "is_template") == 0)

2369 {

2370 if (distemplate)

2372 distemplate = defel;

2373 }

2374 else if (strcmp(defel->defname, "allow_connections") == 0)

2375 {

2376 if (dallowconnections)

2378 dallowconnections = defel;

2379 }

2380 else if (strcmp(defel->defname, "connection_limit") == 0)

2381 {

2382 if (dconnlimit)

2384 dconnlimit = defel;

2385 }

2386 else if (strcmp(defel->defname, "tablespace") == 0)

2387 {

2388 if (dtablespace)

2390 dtablespace = defel;

2391 }

2392 else

2394 (errcode(ERRCODE_SYNTAX_ERROR),

2395 errmsg("option \"%s\" not recognized", defel->defname),

2397 }

2398

2399 if (dtablespace)

2400 {

2401

2402

2403

2404

2405

2408 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

2409 errmsg("option \"%s\" cannot be specified with other options",

2412

2416 }

2417

2418 if (distemplate && distemplate->arg)

2420 if (dallowconnections && dallowconnections->arg)

2421 dballowconnections = defGetBoolean(dallowconnections);

2422 if (dconnlimit && dconnlimit->arg)

2423 {

2427 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

2428 errmsg("invalid connection limit: %d", dbconnlimit)));

2429 }

2430

2431

2432

2433

2434

2435

2438 Anum_pg_database_datname,

2442 NULL, 1, &scankey);

2446 (errcode(ERRCODE_UNDEFINED_DATABASE),

2447 errmsg("database \"%s\" does not exist", stmt->dbname)));

2449

2451 dboid = datform->oid;

2452

2454 {

2456 errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

2457 errmsg("cannot alter invalid database \"%s\"", stmt->dbname),

2458 errhint("Use DROP DATABASE to drop invalid databases."));

2459 }

2460

2463 stmt->dbname);

2464

2465

2466

2467

2468

2469

2470

2471 if (!dballowconnections && dboid == MyDatabaseId)

2473 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

2474 errmsg("cannot disallow connections for current database")));

2475

2476

2477

2478

2479 if (distemplate)

2480 {

2481 new_record[Anum_pg_database_datistemplate - 1] = BoolGetDatum(dbistemplate);

2482 new_record_repl[Anum_pg_database_datistemplate - 1] = true;

2483 }

2484 if (dallowconnections)

2485 {

2486 new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(dballowconnections);

2487 new_record_repl[Anum_pg_database_datallowconn - 1] = true;

2488 }

2489 if (dconnlimit)

2490 {

2491 new_record[Anum_pg_database_datconnlimit - 1] = Int32GetDatum(dbconnlimit);

2492 new_record_repl[Anum_pg_database_datconnlimit - 1] = true;

2493 }

2494

2496 new_record_nulls, new_record_repl);

2499

2501

2503

2504

2506

2507 return dboid;

2508}

2509

2510

2511

2512

2513

2516{

2520 Oid db_id;

2525 bool isnull;

2526 char *oldversion;

2527 char *newversion;

2528

2531 Anum_pg_database_datname,

2535 NULL, 1, &scankey);

2539 (errcode(ERRCODE_UNDEFINED_DATABASE),

2540 errmsg("database \"%s\" does not exist", stmt->dbname)));

2541

2543 db_id = datForm->oid;

2544

2547 stmt->dbname);

2549

2552

2553 if (datForm->datlocprovider == COLLPROVIDER_LIBC)

2554 {

2556 if (isnull)

2557 elog(ERROR, "unexpected null in pg_database");

2558 }

2559 else

2560 {

2562 if (isnull)

2563 elog(ERROR, "unexpected null in pg_database");

2564 }

2565

2568

2569

2570 if ((!oldversion && newversion) || (oldversion && !newversion))

2571 elog(ERROR, "invalid collation version change");

2572 else if (oldversion && newversion && strcmp(newversion, oldversion) != 0)

2573 {

2574 bool nulls[Natts_pg_database] = {0};

2575 bool replaces[Natts_pg_database] = {0};

2578

2580 (errmsg("changing version from %s to %s",

2581 oldversion, newversion)));

2582

2584 replaces[Anum_pg_database_datcollversion - 1] = true;

2585

2587 values, nulls, replaces);

2590 }

2591 else

2593 (errmsg("version has not changed")));

2595

2597

2599

2601

2603

2604 return address;

2605}

2606

2607

2608

2609

2610

2613{

2615

2616

2617

2618

2619

2621

2624 stmt->dbname);

2625

2627

2629

2630 return datid;

2631}

2632

2633

2634

2635

2636

2639{

2640 Oid db_id;

2647

2648

2649

2650

2651

2652

2655 Anum_pg_database_datname,

2659 NULL, 1, &scankey);

2663 (errcode(ERRCODE_UNDEFINED_DATABASE),

2664 errmsg("database \"%s\" does not exist", dbname)));

2665

2667 db_id = datForm->oid;

2668

2669

2670

2671

2672

2673

2674 if (datForm->datdba != newOwnerId)

2675 {

2676 Datum repl_val[Natts_pg_database];

2677 bool repl_null[Natts_pg_database] = {0};

2678 bool repl_repl[Natts_pg_database] = {0};

2679 Acl *newAcl;

2681 bool isNull;

2683

2684

2688

2689

2691

2692

2693

2694

2695

2696

2697

2698

2699

2700

2703 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),

2704 errmsg("permission denied to change owner of database")));

2705

2707

2708 repl_repl[Anum_pg_database_datdba - 1] = true;

2709 repl_val[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(newOwnerId);

2710

2711

2712

2713

2714

2716 Anum_pg_database_datacl,

2718 &isNull);

2719 if (!isNull)

2720 {

2722 datForm->datdba, newOwnerId);

2723 repl_repl[Anum_pg_database_datacl - 1] = true;

2724 repl_val[Anum_pg_database_datacl - 1] = PointerGetDatum(newAcl);

2725 }

2726

2730

2732

2733

2735 }

2736

2738

2740

2742

2743

2745

2746 return address;

2747}

2748

2749

2752{

2757 char *version;

2758

2762 (errcode(ERRCODE_UNDEFINED_OBJECT),

2763 errmsg("database with OID %u does not exist", dbid)));

2764

2766

2769 else

2771

2774

2776

2777 if (version)

2779 else

2781}

2782

2783

2784

2785

2786

2787

2788

2789

2790

2791

2792

2793

2794static bool

2796 Oid *dbIdP, Oid *ownerIdP,

2797 int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, bool *dbHasLoginEvtP,

2799 Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbLocale,

2800 char **dbIcurules,

2801 char *dbLocProvider,

2802 char **dbCollversion)

2803{

2804 bool result = false;

2806

2808

2809

2811

2812

2813

2814

2815

2816

2817 for (;;)

2818 {

2822 Oid dbOid;

2823

2824

2825

2826

2827

2829 Anum_pg_database_datname,

2832

2834 NULL, 1, &scanKey);

2835

2837

2839 {

2840

2842 break;

2843 }

2844

2846

2848

2849

2850

2851

2852 if (lockmode != NoLock)

2854

2855

2856

2857

2858

2859

2862 {

2864

2865 if (strcmp(name, NameStr(dbform->datname)) == 0)

2866 {

2868 bool isnull;

2869

2870

2871 if (dbIdP)

2872 *dbIdP = dbOid;

2873

2874 if (ownerIdP)

2875 *ownerIdP = dbform->datdba;

2876

2877 if (encodingP)

2878 *encodingP = dbform->encoding;

2879

2880 if (dbIsTemplateP)

2881 *dbIsTemplateP = dbform->datistemplate;

2882

2883 if (dbHasLoginEvtP)

2884 *dbHasLoginEvtP = dbform->dathasloginevt;

2885

2886 if (dbAllowConnP)

2887 *dbAllowConnP = dbform->datallowconn;

2888

2889 if (dbFrozenXidP)

2890 *dbFrozenXidP = dbform->datfrozenxid;

2891

2892 if (dbMinMultiP)

2893 *dbMinMultiP = dbform->datminmxid;

2894

2895 if (dbTablespace)

2896 *dbTablespace = dbform->dattablespace;

2897

2898 if (dbLocProvider)

2899 *dbLocProvider = dbform->datlocprovider;

2900 if (dbCollate)

2901 {

2904 }

2905 if (dbCtype)

2906 {

2909 }

2910 if (dbLocale)

2911 {

2912 datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datlocale, &isnull);

2913 if (isnull)

2914 *dbLocale = NULL;

2915 else

2917 }

2918 if (dbIcurules)

2919 {

2920 datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_daticurules, &isnull);

2921 if (isnull)

2922 *dbIcurules = NULL;

2923 else

2925 }

2926 if (dbCollversion)

2927 {

2928 datum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datcollversion, &isnull);

2929 if (isnull)

2930 *dbCollversion = NULL;

2931 else

2933 }

2935 result = true;

2936 break;

2937 }

2938

2940 }

2941

2942 if (lockmode != NoLock)

2944 }

2945

2947

2948 return result;

2949}

2950

2951

2952bool

2954{

2955 bool result = false;

2957

2958

2960 return true;

2961

2964 {

2967 }

2968 return result;

2969}

2970

2971

2972

2973

2974

2975

2976

2977static void

2979{

2985 int ntblspc;

2986 int i;

2987 Oid *tablespace_ids;

2988

2992 {

2994 Oid dsttablespace = spcform->oid;

2996 struct stat st;

2997

2998

2999 if (dsttablespace == GLOBALTABLESPACE_OID)

3000 continue;

3001

3003

3005 {

3006

3008 continue;

3009 }

3010

3013 (errmsg("some useless files may be left behind in old database directory \"%s\"",

3015

3016 ltblspc = lappend_oid(ltblspc, dsttablespace);

3018 }

3019

3021 if (ntblspc == 0)

3022 {

3025 return;

3026 }

3027

3028 tablespace_ids = (Oid *) palloc(ntblspc * sizeof(Oid));

3029 i = 0;

3030 foreach(cell, ltblspc)

3032

3033

3034 {

3036

3037 xlrec.db_id = db_id;

3039

3043

3046 }

3047

3049 pfree(tablespace_ids);

3050

3053}

3054

3055

3056

3057

3058

3059

3060

3061

3062

3063

3064

3065

3066

3067static bool

3069{

3070 bool result = false;

3074

3078 {

3080 Oid dsttablespace = spcform->oid;

3082 struct stat st;

3083

3084

3085 if (dsttablespace == GLOBALTABLESPACE_OID)

3086 continue;

3087

3089

3091 {

3092

3094 result = true;

3095 break;

3096 }

3097

3099 }

3100

3103

3104 return result;

3105}

3106

3107

3108

3109

3110static int

3112{

3113 if (notherbackends > 0 && npreparedxacts > 0)

3114

3115

3116

3117

3118

3119 errdetail("There are %d other session(s) and %d prepared transaction(s) using the database.",

3120 notherbackends, npreparedxacts);

3121 else if (notherbackends > 0)

3122 errdetail_plural("There is %d other session using the database.",

3123 "There are %d other sessions using the database.",

3124 notherbackends,

3125 notherbackends);

3126 else

3127 errdetail_plural("There is %d prepared transaction using the database.",

3128 "There are %d prepared transactions using the database.",

3129 npreparedxacts,

3130 npreparedxacts);

3131 return 0;

3132}

3133

3134

3135

3136

3137

3138

3139

3142{

3147 Oid oid;

3148

3149

3150

3151

3152

3155 Anum_pg_database_datname,

3159 NULL, 1, entry);

3160

3162

3163

3166 else

3168

3171

3172 if (OidIsValid(oid) && !missing_ok)

3174 (errcode(ERRCODE_UNDEFINED_DATABASE),

3175 errmsg("database \"%s\" does not exist",

3177

3178 return oid;

3179}

3180

3181

3182

3183

3184

3185

3186

3187char *

3189{

3191 char *result;

3192

3195 {

3198 }

3199 else

3200 result = NULL;

3201

3202 return result;

3203}

3204

3205

3206

3207

3208

3209

3210

3211bool

3213{

3215}

3216

3217

3218

3219

3220

3221bool

3223{

3227

3230 elog(ERROR, "cache lookup failed for database %u", dboid);

3232

3234

3236

3238}

3239

3240

3241

3242

3243

3244

3245

3246

3247

3248

3249

3250

3251

3252

3253

3254static void

3256{

3257 struct stat st;

3258

3260

3261 if (stat(path, &st) == 0)

3262 return;

3263

3265 elog(PANIC, "requested to created invalid directory: %s", path);

3266

3269 errmsg("missing directory \"%s\"", path));

3270

3272 "creating missing directory: %s", path);

3273

3276 errmsg("could not create missing directory \"%s\": %m", path));

3277}

3278

3279

3280

3281

3282

3283void

3285{

3287

3288

3290

3292 {

3295 char *src_path;

3296 char *dst_path;

3297 char *parent_path;

3298 struct stat st;

3299

3302

3303

3304

3305

3306

3307

3309 {

3310 if (rmtree(dst_path, true))

3311

3313 (errmsg("some useless files may be left behind in old database directory \"%s\"",

3314 dst_path)));

3315 }

3316

3317

3318

3319

3320

3321 parent_path = pstrdup(dst_path);

3323 if (stat(parent_path, &st) < 0)

3324 {

3325 if (errno != ENOENT)

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

3328 dst_path));

3329

3330

3332 }

3333 pfree(parent_path);

3334

3335

3336

3337

3338

3339

3340

3341 if (stat(src_path, &st) < 0 && errno == ENOENT)

3343

3344

3345

3346

3347

3349

3350

3352

3353

3354

3355

3356

3357

3358 copydir(src_path, dst_path, false);

3359

3360 pfree(src_path);

3361 pfree(dst_path);

3362 }

3364 {

3367 char *dbpath;

3368 char *parent_path;

3369

3371

3372

3373 parent_path = pstrdup(dbpath);

3376

3377

3379 true);

3381 }

3383 {

3385 char *dst_path;

3386 int i;

3387

3389 {

3390

3391

3392

3393

3394

3395

3396

3397

3398

3399

3402 }

3403

3404

3406

3407

3409

3410

3412

3413

3415

3416

3418

3420 {

3422

3423

3424 if (rmtree(dst_path, true))

3426 (errmsg("some useless files may be left behind in old database directory \"%s\"",

3427 dst_path)));

3428 pfree(dst_path);

3429 }

3430

3432 {

3433

3434

3435

3436

3437

3438

3439

3441 }

3442 }

3443 else

3444 elog(PANIC, "dbase_redo: unknown op code %u", info);

3445}

Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)

Oid get_role_oid(const char *rolname, bool missing_ok)

void check_can_set_role(Oid member, Oid role)

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)

bool directory_is_empty(const char *path)

Oid get_tablespace_oid(const char *tablespacename, bool missing_ok)

bool allow_in_place_tablespaces

static Datum values[MAXATTR]

void DropDatabaseBuffers(Oid dbid)

BlockNumber BufferGetBlockNumber(Buffer buffer)

void CreateAndCopyRelationData(RelFileLocator src_rlocator, RelFileLocator dst_rlocator, bool permanent)

void UnlockReleaseBuffer(Buffer buffer)

void LockBuffer(Buffer buffer, int mode)

Buffer ReadBufferWithoutRelcache(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy, bool permanent)

void FlushDatabaseBuffers(Oid dbid)

#define BUFFER_LOCK_SHARE

static Page BufferGetPage(Buffer buffer)

static bool PageIsEmpty(const PageData *page)

static Item PageGetItem(const PageData *page, const ItemIdData *itemId)

static bool PageIsNew(const PageData *page)

static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)

static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)

#define CStringGetTextDatum(s)

#define TextDatumGetCString(d)

TransactionId MultiXactId

#define OidIsValid(objectId)

Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)

void RequestCheckpoint(int flags)

void copydir(const char *fromdir, const char *todir, bool recurse)

static void remove_dbtablespaces(Oid db_id)

static void CreateDirAndVersionFile(char *dbpath, Oid dbid, Oid tsid, bool isRedo)

ObjectAddress AlterDatabaseRefreshColl(AlterDatabaseRefreshCollStmt *stmt)

bool have_createdb_privilege(void)

ObjectAddress RenameDatabase(const char *oldname, const char *newname)

Oid get_database_oid(const char *dbname, bool missing_ok)

static void movedb_failure_callback(int code, Datum arg)

static void CreateDatabaseUsingWalLog(Oid src_dboid, Oid dst_dboid, Oid src_tsid, Oid dst_tsid)

static List * ScanSourceDatabasePgClass(Oid tbid, Oid dbid, char *srcpath)

static void recovery_create_dbdir(char *path, bool only_tblspc)

char * get_database_name(Oid dbid)

ObjectAddress AlterDatabaseOwner(const char *dbname, Oid newOwnerId)

bool database_is_invalid_form(Form_pg_database datform)

Datum pg_database_collation_actual_version(PG_FUNCTION_ARGS)

static void movedb(const char *dbname, const char *tblspcname)

static List * ScanSourceDatabasePgClassPage(Page page, Buffer buf, Oid tbid, Oid dbid, char *srcpath, List *rlocatorlist, Snapshot snapshot)

void check_encoding_locale_matches(int encoding, const char *collate, const char *ctype)

Oid createdb(ParseState *pstate, const CreatedbStmt *stmt)

Oid AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel)

static int errdetail_busy_db(int notherbackends, int npreparedxacts)

static CreateDBRelInfo * ScanSourceDatabasePgClassTuple(HeapTupleData *tuple, Oid tbid, Oid dbid, char *srcpath)

static bool check_db_file_conflict(Oid db_id)

struct CreateDBRelInfo CreateDBRelInfo

void dbase_redo(XLogReaderState *record)

static void CreateDatabaseUsingFileCopy(Oid src_dboid, Oid dst_dboid, Oid src_tsid, Oid dst_tsid)

void DropDatabase(ParseState *pstate, DropdbStmt *stmt)

void dropdb(const char *dbname, bool missing_ok, bool force)

Oid AlterDatabaseSet(AlterDatabaseSetStmt *stmt)

static bool get_db_info(const char *name, LOCKMODE lockmode, Oid *dbIdP, Oid *ownerIdP, int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, bool *dbHasLoginEvtP, TransactionId *dbFrozenXidP, MultiXactId *dbMinMultiP, Oid *dbTablespace, char **dbCollate, char **dbCtype, char **dbLocale, char **dbIcurules, char *dbLocProvider, char **dbCollversion)

static void createdb_failure_callback(int code, Datum arg)

bool database_is_invalid_oid(Oid dboid)

#define XLOG_DBASE_CREATE_WAL_LOG

#define MinSizeOfDbaseDropRec

#define XLOG_DBASE_CREATE_FILE_COPY

int32 defGetInt32(DefElem *def)

char * defGetString(DefElem *def)

bool defGetBoolean(DefElem *def)

void errorConflictingDefElem(DefElem *defel, ParseState *pstate)

Oid defGetObjectId(DefElem *def)

int errcode_for_file_access(void)

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

int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)

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

int errcode(int sqlerrcode)

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

#define ereport(elevel,...)

bool is_encoding_supported_by_icu(int encoding)

int MakePGDirectory(const char *directoryName)

int CloseTransientFile(int fd)

void fsync_fname(const char *fname, bool isdir)

int data_sync_elevel(int elevel)

DIR * AllocateDir(const char *dirname)

struct dirent * ReadDir(DIR *dir, const char *dirname)

int OpenTransientFile(const char *fileName, int fileFlags)

static char dstpath[MAXPGPATH]

#define DirectFunctionCall1(func, arg1)

#define PG_RETURN_TEXT_P(x)

BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)

void systable_endscan(SysScanDesc sysscan)

void systable_inplace_update_begin(Relation relation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, const ScanKeyData *key, HeapTuple *oldtupcopy, void **state)

void systable_inplace_update_finish(void *state, HeapTuple tuple)

HeapTuple systable_getnext(SysScanDesc sysscan)

SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)

bool allowSystemTableMods

Assert(PointerIsAligned(start, uint64))

HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)

bool HeapTupleSatisfiesVisibility(HeapTuple htup, Snapshot snapshot, Buffer buffer)

HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)

HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)

void heap_freetuple(HeapTuple htup)

HeapTupleHeaderData * HeapTupleHeader

#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)

#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)

#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)

invalidindex index d is invalid

#define ItemIdGetLength(itemId)

#define ItemIdIsNormal(itemId)

#define ItemIdIsDead(itemId)

#define ItemIdIsUsed(itemId)

#define ItemIdIsRedirected(itemId)

static void ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum)

List * lappend(List *list, void *datum)

List * lappend_oid(List *list, Oid datum)

void list_free(List *list)

void list_free_deep(List *list)

void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)

void UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)

void UnlockRelationId(LockRelId *relid, LOCKMODE lockmode)

void LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)

void UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)

void LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)

void LockRelationId(LockRelId *relid, LOCKMODE lockmode)

void UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)

#define AccessExclusiveLock

#define InplaceUpdateTupleLock

char * pstrdup(const char *in)

void pfree(void *pointer)

void ForgetDatabaseSyncRequests(Oid dbid)

#define START_CRIT_SECTION()

#define CHECK_FOR_INTERRUPTS()

#define END_CRIT_SECTION()

#define InvalidMultiXactId

void namestrcpy(Name name, const char *str)

Datum namein(PG_FUNCTION_ARGS)

#define IsA(nodeptr, _type_)

#define InvokeObjectPostCreateHook(classId, objectId, subId)

#define InvokeObjectPostAlterHook(classId, objectId, subId)

#define InvokeObjectDropHook(classId, objectId, subId)

#define ObjectAddressSet(addr, class_id, object_id)

#define OffsetNumberNext(offsetNumber)

#define FirstOffsetNumber

int parser_errposition(ParseState *pstate, int location)

FormData_pg_authid * Form_pg_authid

FormData_pg_class * Form_pg_class

FormData_pg_database * Form_pg_database

#define DATCONNLIMIT_INVALID_DB

#define DATCONNLIMIT_UNLIMITED

void DropSetting(Oid databaseid, Oid roleid)

void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)

static int list_length(const List *l)

void icu_validate_locale(const char *loc_str)

char * get_collation_actual_version(char collprovider, const char *collcollate)

char * icu_language_tag(const char *loc_str, int elevel)

const char * builtin_validate_locale(int encoding, const char *locale)

bool check_locale(int category, const char *locale, char **canonname)

void dropDatabaseDependencies(Oid databaseId)

void changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)

void copyTemplateDependencies(Oid templateDbId, Oid newDbId)

void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)

void shdepLockAndCheckObject(Oid classId, Oid objectId)

int CountDBSubscriptions(Oid dbid)

FormData_pg_tablespace * Form_pg_tablespace

#define PG_VALID_BE_ENCODING(_enc)

#define pg_encoding_to_char

#define pg_valid_server_encoding

void pgstat_drop_database(Oid databaseid)

int pg_mkdir_p(char *path, int omode)

int pg_strcasecmp(const char *s1, const char *s2)

void get_parent_directory(char *path)

int pg_get_encoding_from_locale(const char *ctype, bool write_message)

static Datum PointerGetDatum(const void *X)

static Datum TransactionIdGetDatum(TransactionId X)

static Datum BoolGetDatum(bool X)

static Datum ObjectIdGetDatum(Oid X)

static Pointer DatumGetPointer(Datum X)

static Datum CStringGetDatum(const char *X)

static Datum Int32GetDatum(int32 X)

static Datum CharGetDatum(char X)

static int fd(const char *x, int i)

void TerminateOtherDBBackends(Oid databaseId)

bool CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared)

#define INVALID_PROC_NUMBER

void WaitForProcSignalBarrier(uint64 generation)

uint64 EmitProcSignalBarrier(ProcSignalBarrierType type)

@ PROCSIGNAL_BARRIER_SMGRRELEASE

#define RelationGetDescr(relation)

RelFileNumber RelationMapOidToFilenumberForDatabase(char *dbpath, Oid relationId)

void RelationMapCopy(Oid dbid, Oid tsid, char *srcdbpath, char *dstdbpath)

char * GetDatabasePath(Oid dbOid, Oid spcOid)

#define PG_TBLSPC_DIR_SLASH

#define InvalidRelFileNumber

#define RelFileNumberIsValid(relnumber)

bool rmtree(const char *path, bool rmtopdir)

const char * quote_identifier(const char *ident)

void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)

void DeleteSharedSecurityLabel(Oid objectId, Oid classId)

bool ReplicationSlotsCountDBSlots(Oid dboid, int *nslots, int *nactive)

void ReplicationSlotsDropDBSlots(Oid dboid)

BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)

SMgrRelation smgropen(RelFileLocator rlocator, ProcNumber backend)

void smgrclose(SMgrRelation reln)

Snapshot GetLatestSnapshot(void)

void UnregisterSnapshot(Snapshot snapshot)

Snapshot RegisterSnapshot(Snapshot snapshot)

void PopActiveSnapshot(void)

void ResolveRecoveryConflictWithDatabase(Oid dbid)

#define BTEqualStrategyNumber

CreateDBStrategy strategy

Oid tablespace_ids[FLEXIBLE_ARRAY_MEMBER]

void ReleaseSysCache(HeapTuple tuple)

HeapTuple SearchSysCacheLockedCopy1(int cacheId, Datum key1)

HeapTuple SearchSysCache1(int cacheId, Datum key1)

Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)

Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)

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 InvalidTransactionId

#define FirstNormalObjectId

text * cstring_to_text(const char *s)

static void pgstat_report_wait_start(uint32 wait_event_info)

static void pgstat_report_wait_end(void)

void PreventInTransactionBlock(bool isTopLevel, const char *stmtType)

void StartTransactionCommand(void)

void ForceSyncCommit(void)

void CommitTransactionCommand(void)

bool RecoveryInProgress(void)

XLogRecPtr XactLastRecEnd

void XLogFlush(XLogRecPtr record)

#define CHECKPOINT_FLUSH_ALL

#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)

#define XLR_SPECIAL_REL_UPDATE

void XLogDropDatabase(Oid dbid)