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{
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{
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 ((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 ((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 ((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 ((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 ((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 ((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)