PostgreSQL Source Code  git master
dbcommands.h File Reference
Include dependency graph for dbcommands.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

Oid createdb (ParseState *pstate, const CreatedbStmt *stmt)
 
void dropdb (const char *dbname, bool missing_ok, bool force)
 
void DropDatabase (ParseState *pstate, DropdbStmt *stmt)
 
ObjectAddress RenameDatabase (const char *oldname, const char *newname)
 
Oid AlterDatabase (ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel)
 
ObjectAddress AlterDatabaseRefreshColl (AlterDatabaseRefreshCollStmt *stmt)
 
Oid AlterDatabaseSet (AlterDatabaseSetStmt *stmt)
 
ObjectAddress AlterDatabaseOwner (const char *dbname, Oid newOwnerId)
 
Oid get_database_oid (const char *dbname, bool missing_ok)
 
char * get_database_name (Oid dbid)
 
bool have_createdb_privilege (void)
 
void check_encoding_locale_matches (int encoding, const char *collate, const char *ctype)
 

Function Documentation

◆ AlterDatabase()

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

Definition at line 2341 of file dbcommands.c.

2342 {
2343  Relation rel;
2344  Oid dboid;
2345  HeapTuple tuple,
2346  newtuple;
2347  Form_pg_database datform;
2348  ScanKeyData scankey;
2349  SysScanDesc scan;
2350  ListCell *option;
2351  bool dbistemplate = false;
2352  bool dballowconnections = true;
2353  int dbconnlimit = DATCONNLIMIT_UNLIMITED;
2354  DefElem *distemplate = NULL;
2355  DefElem *dallowconnections = NULL;
2356  DefElem *dconnlimit = NULL;
2357  DefElem *dtablespace = NULL;
2358  Datum new_record[Natts_pg_database] = {0};
2359  bool new_record_nulls[Natts_pg_database] = {0};
2360  bool new_record_repl[Natts_pg_database] = {0};
2361 
2362  /* Extract options from the statement node tree */
2363  foreach(option, stmt->options)
2364  {
2365  DefElem *defel = (DefElem *) lfirst(option);
2366 
2367  if (strcmp(defel->defname, "is_template") == 0)
2368  {
2369  if (distemplate)
2370  errorConflictingDefElem(defel, pstate);
2371  distemplate = defel;
2372  }
2373  else if (strcmp(defel->defname, "allow_connections") == 0)
2374  {
2375  if (dallowconnections)
2376  errorConflictingDefElem(defel, pstate);
2377  dallowconnections = defel;
2378  }
2379  else if (strcmp(defel->defname, "connection_limit") == 0)
2380  {
2381  if (dconnlimit)
2382  errorConflictingDefElem(defel, pstate);
2383  dconnlimit = defel;
2384  }
2385  else if (strcmp(defel->defname, "tablespace") == 0)
2386  {
2387  if (dtablespace)
2388  errorConflictingDefElem(defel, pstate);
2389  dtablespace = defel;
2390  }
2391  else
2392  ereport(ERROR,
2393  (errcode(ERRCODE_SYNTAX_ERROR),
2394  errmsg("option \"%s\" not recognized", defel->defname),
2395  parser_errposition(pstate, defel->location)));
2396  }
2397 
2398  if (dtablespace)
2399  {
2400  /*
2401  * While the SET TABLESPACE syntax doesn't allow any other options,
2402  * somebody could write "WITH TABLESPACE ...". Forbid any other
2403  * options from being specified in that case.
2404  */
2405  if (list_length(stmt->options) != 1)
2406  ereport(ERROR,
2407  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2408  errmsg("option \"%s\" cannot be specified with other options",
2409  dtablespace->defname),
2410  parser_errposition(pstate, dtablespace->location)));
2411  /* this case isn't allowed within a transaction block */
2412  PreventInTransactionBlock(isTopLevel, "ALTER DATABASE SET TABLESPACE");
2413  movedb(stmt->dbname, defGetString(dtablespace));
2414  return InvalidOid;
2415  }
2416 
2417  if (distemplate && distemplate->arg)
2418  dbistemplate = defGetBoolean(distemplate);
2419  if (dallowconnections && dallowconnections->arg)
2420  dballowconnections = defGetBoolean(dallowconnections);
2421  if (dconnlimit && dconnlimit->arg)
2422  {
2423  dbconnlimit = defGetInt32(dconnlimit);
2424  if (dbconnlimit < DATCONNLIMIT_UNLIMITED)
2425  ereport(ERROR,
2426  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2427  errmsg("invalid connection limit: %d", dbconnlimit)));
2428  }
2429 
2430  /*
2431  * Get the old tuple. We don't need a lock on the database per se,
2432  * because we're not going to do anything that would mess up incoming
2433  * connections.
2434  */
2435  rel = table_open(DatabaseRelationId, RowExclusiveLock);
2436  ScanKeyInit(&scankey,
2437  Anum_pg_database_datname,
2438  BTEqualStrategyNumber, F_NAMEEQ,
2439  CStringGetDatum(stmt->dbname));
2440  scan = systable_beginscan(rel, DatabaseNameIndexId, true,
2441  NULL, 1, &scankey);
2442  tuple = systable_getnext(scan);
2443  if (!HeapTupleIsValid(tuple))
2444  ereport(ERROR,
2445  (errcode(ERRCODE_UNDEFINED_DATABASE),
2446  errmsg("database \"%s\" does not exist", stmt->dbname)));
2447  LockTuple(rel, &tuple->t_self, InplaceUpdateTupleLock);
2448 
2449  datform = (Form_pg_database) GETSTRUCT(tuple);
2450  dboid = datform->oid;
2451 
2452  if (database_is_invalid_form(datform))
2453  {
2454  ereport(FATAL,
2455  errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2456  errmsg("cannot alter invalid database \"%s\"", stmt->dbname),
2457  errhint("Use DROP DATABASE to drop invalid databases."));
2458  }
2459 
2460  if (!object_ownercheck(DatabaseRelationId, dboid, GetUserId()))
2462  stmt->dbname);
2463 
2464  /*
2465  * In order to avoid getting locked out and having to go through
2466  * standalone mode, we refuse to disallow connections to the database
2467  * we're currently connected to. Lockout can still happen with concurrent
2468  * sessions but the likeliness of that is not high enough to worry about.
2469  */
2470  if (!dballowconnections && dboid == MyDatabaseId)
2471  ereport(ERROR,
2472  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2473  errmsg("cannot disallow connections for current database")));
2474 
2475  /*
2476  * Build an updated tuple, perusing the information just obtained
2477  */
2478  if (distemplate)
2479  {
2480  new_record[Anum_pg_database_datistemplate - 1] = BoolGetDatum(dbistemplate);
2481  new_record_repl[Anum_pg_database_datistemplate - 1] = true;
2482  }
2483  if (dallowconnections)
2484  {
2485  new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(dballowconnections);
2486  new_record_repl[Anum_pg_database_datallowconn - 1] = true;
2487  }
2488  if (dconnlimit)
2489  {
2490  new_record[Anum_pg_database_datconnlimit - 1] = Int32GetDatum(dbconnlimit);
2491  new_record_repl[Anum_pg_database_datconnlimit - 1] = true;
2492  }
2493 
2494  newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel), new_record,
2495  new_record_nulls, new_record_repl);
2496  CatalogTupleUpdate(rel, &tuple->t_self, newtuple);
2497  UnlockTuple(rel, &tuple->t_self, InplaceUpdateTupleLock);
2498 
2499  InvokeObjectPostAlterHook(DatabaseRelationId, dboid, 0);
2500 
2501  systable_endscan(scan);
2502 
2503  /* Close pg_database, but keep lock till commit */
2504  table_close(rel, NoLock);
2505 
2506  return dboid;
2507 }
@ ACLCHECK_NOT_OWNER
Definition: acl.h:185
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2622
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition: aclchk.c:4064
bool database_is_invalid_form(Form_pg_database datform)
Definition: dbcommands.c:3211
static void movedb(const char *dbname, const char *tblspcname)
Definition: dbcommands.c:1977
int32 defGetInt32(DefElem *def)
Definition: define.c:162
bool defGetBoolean(DefElem *def)
Definition: define.c:107
char * defGetString(DefElem *def)
Definition: define.c:48
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition: define.c:384
int errhint(const char *fmt,...)
Definition: elog.c:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define FATAL
Definition: elog.h:41
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:604
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:511
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:387
Oid MyDatabaseId
Definition: globals.c:93
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition: heaptuple.c:1209
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
#define stmt
Definition: indent_codes.h:59
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
void LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
Definition: lmgr.c:557
void UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode)
Definition: lmgr.c:594
#define NoLock
Definition: lockdefs.h:34
#define InplaceUpdateTupleLock
Definition: lockdefs.h:48
#define RowExclusiveLock
Definition: lockdefs.h:38
Oid GetUserId(void)
Definition: miscinit.c:524
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:197
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:106
@ OBJECT_DATABASE
Definition: parsenodes.h:2277
FormData_pg_database * Form_pg_database
Definition: pg_database.h:96
#define DATCONNLIMIT_UNLIMITED
Definition: pg_database.h:117
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
uintptr_t Datum
Definition: postgres.h:64
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
#define RelationGetDescr(relation)
Definition: rel.h:531
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
char * defname
Definition: parsenodes.h:817
ParseLoc location
Definition: parsenodes.h:821
Node * arg
Definition: parsenodes.h:818
ItemPointerData t_self
Definition: htup.h:65
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
void PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
Definition: xact.c:3640

References aclcheck_error(), ACLCHECK_NOT_OWNER, DefElem::arg, BoolGetDatum(), BTEqualStrategyNumber, CatalogTupleUpdate(), CStringGetDatum(), database_is_invalid_form(), DATCONNLIMIT_UNLIMITED, defGetBoolean(), defGetInt32(), defGetString(), DefElem::defname, ereport, errcode(), errhint(), errmsg(), ERROR, errorConflictingDefElem(), FATAL, GETSTRUCT, GetUserId(), heap_modify_tuple(), HeapTupleIsValid, InplaceUpdateTupleLock, Int32GetDatum(), InvalidOid, InvokeObjectPostAlterHook, lfirst, list_length(), DefElem::location, LockTuple(), movedb(), MyDatabaseId, NoLock, OBJECT_DATABASE, object_ownercheck(), parser_errposition(), PreventInTransactionBlock(), RelationGetDescr, RowExclusiveLock, ScanKeyInit(), stmt, systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), and UnlockTuple().

Referenced by standard_ProcessUtility().

◆ AlterDatabaseOwner()

ObjectAddress AlterDatabaseOwner ( const char *  dbname,
Oid  newOwnerId 
)

Definition at line 2637 of file dbcommands.c.

2638 {
2639  Oid db_id;
2640  HeapTuple tuple;
2641  Relation rel;
2642  ScanKeyData scankey;
2643  SysScanDesc scan;
2644  Form_pg_database datForm;
2645  ObjectAddress address;
2646 
2647  /*
2648  * Get the old tuple. We don't need a lock on the database per se,
2649  * because we're not going to do anything that would mess up incoming
2650  * connections.
2651  */
2652  rel = table_open(DatabaseRelationId, RowExclusiveLock);
2653  ScanKeyInit(&scankey,
2654  Anum_pg_database_datname,
2655  BTEqualStrategyNumber, F_NAMEEQ,
2657  scan = systable_beginscan(rel, DatabaseNameIndexId, true,
2658  NULL, 1, &scankey);
2659  tuple = systable_getnext(scan);
2660  if (!HeapTupleIsValid(tuple))
2661  ereport(ERROR,
2662  (errcode(ERRCODE_UNDEFINED_DATABASE),
2663  errmsg("database \"%s\" does not exist", dbname)));
2664 
2665  datForm = (Form_pg_database) GETSTRUCT(tuple);
2666  db_id = datForm->oid;
2667 
2668  /*
2669  * If the new owner is the same as the existing owner, consider the
2670  * command to have succeeded. This is to be consistent with other
2671  * objects.
2672  */
2673  if (datForm->datdba != newOwnerId)
2674  {
2675  Datum repl_val[Natts_pg_database];
2676  bool repl_null[Natts_pg_database] = {0};
2677  bool repl_repl[Natts_pg_database] = {0};
2678  Acl *newAcl;
2679  Datum aclDatum;
2680  bool isNull;
2681  HeapTuple newtuple;
2682 
2683  /* Otherwise, must be owner of the existing object */
2684  if (!object_ownercheck(DatabaseRelationId, db_id, GetUserId()))
2686  dbname);
2687 
2688  /* Must be able to become new owner */
2689  check_can_set_role(GetUserId(), newOwnerId);
2690 
2691  /*
2692  * must have createdb rights
2693  *
2694  * NOTE: This is different from other alter-owner checks in that the
2695  * current user is checked for createdb privileges instead of the
2696  * destination owner. This is consistent with the CREATE case for
2697  * databases. Because superusers will always have this right, we need
2698  * no special case for them.
2699  */
2700  if (!have_createdb_privilege())
2701  ereport(ERROR,
2702  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2703  errmsg("permission denied to change owner of database")));
2704 
2705  LockTuple(rel, &tuple->t_self, InplaceUpdateTupleLock);
2706 
2707  repl_repl[Anum_pg_database_datdba - 1] = true;
2708  repl_val[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(newOwnerId);
2709 
2710  /*
2711  * Determine the modified ACL for the new owner. This is only
2712  * necessary when the ACL is non-null.
2713  */
2714  aclDatum = heap_getattr(tuple,
2715  Anum_pg_database_datacl,
2716  RelationGetDescr(rel),
2717  &isNull);
2718  if (!isNull)
2719  {
2720  newAcl = aclnewowner(DatumGetAclP(aclDatum),
2721  datForm->datdba, newOwnerId);
2722  repl_repl[Anum_pg_database_datacl - 1] = true;
2723  repl_val[Anum_pg_database_datacl - 1] = PointerGetDatum(newAcl);
2724  }
2725 
2726  newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel), repl_val, repl_null, repl_repl);
2727  CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
2728  UnlockTuple(rel, &tuple->t_self, InplaceUpdateTupleLock);
2729 
2730  heap_freetuple(newtuple);
2731 
2732  /* Update owner dependency reference */
2733  changeDependencyOnOwner(DatabaseRelationId, db_id, newOwnerId);
2734  }
2735 
2736  InvokeObjectPostAlterHook(DatabaseRelationId, db_id, 0);
2737 
2738  ObjectAddressSet(address, DatabaseRelationId, db_id);
2739 
2740  systable_endscan(scan);
2741 
2742  /* Close pg_database, but keep lock till commit */
2743  table_close(rel, NoLock);
2744 
2745  return address;
2746 }
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition: acl.c:1103
void check_can_set_role(Oid member, Oid role)
Definition: acl.c:5325
#define DatumGetAclP(X)
Definition: acl.h:120
bool have_createdb_privilege(void)
Definition: dbcommands.c:2952
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1434
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
void changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
Definition: pg_shdepend.c:316
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
char * dbname
Definition: streamutil.c:50

References aclcheck_error(), ACLCHECK_NOT_OWNER, aclnewowner(), BTEqualStrategyNumber, CatalogTupleUpdate(), changeDependencyOnOwner(), check_can_set_role(), CStringGetDatum(), DatumGetAclP, dbname, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, GetUserId(), have_createdb_privilege(), heap_freetuple(), heap_getattr(), heap_modify_tuple(), HeapTupleIsValid, InplaceUpdateTupleLock, InvokeObjectPostAlterHook, LockTuple(), NoLock, OBJECT_DATABASE, object_ownercheck(), ObjectAddressSet, ObjectIdGetDatum(), PointerGetDatum(), RelationGetDescr, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), and UnlockTuple().

Referenced by ExecAlterOwnerStmt().

◆ AlterDatabaseRefreshColl()

ObjectAddress AlterDatabaseRefreshColl ( AlterDatabaseRefreshCollStmt stmt)

Definition at line 2514 of file dbcommands.c.

2515 {
2516  Relation rel;
2517  ScanKeyData scankey;
2518  SysScanDesc scan;
2519  Oid db_id;
2520  HeapTuple tuple;
2521  Form_pg_database datForm;
2522  ObjectAddress address;
2523  Datum datum;
2524  bool isnull;
2525  char *oldversion;
2526  char *newversion;
2527 
2528  rel = table_open(DatabaseRelationId, RowExclusiveLock);
2529  ScanKeyInit(&scankey,
2530  Anum_pg_database_datname,
2531  BTEqualStrategyNumber, F_NAMEEQ,
2532  CStringGetDatum(stmt->dbname));
2533  scan = systable_beginscan(rel, DatabaseNameIndexId, true,
2534  NULL, 1, &scankey);
2535  tuple = systable_getnext(scan);
2536  if (!HeapTupleIsValid(tuple))
2537  ereport(ERROR,
2538  (errcode(ERRCODE_UNDEFINED_DATABASE),
2539  errmsg("database \"%s\" does not exist", stmt->dbname)));
2540 
2541  datForm = (Form_pg_database) GETSTRUCT(tuple);
2542  db_id = datForm->oid;
2543 
2544  if (!object_ownercheck(DatabaseRelationId, db_id, GetUserId()))
2546  stmt->dbname);
2547  LockTuple(rel, &tuple->t_self, InplaceUpdateTupleLock);
2548 
2549  datum = heap_getattr(tuple, Anum_pg_database_datcollversion, RelationGetDescr(rel), &isnull);
2550  oldversion = isnull ? NULL : TextDatumGetCString(datum);
2551 
2552  if (datForm->datlocprovider == COLLPROVIDER_LIBC)
2553  {
2554  datum = heap_getattr(tuple, Anum_pg_database_datcollate, RelationGetDescr(rel), &isnull);
2555  if (isnull)
2556  elog(ERROR, "unexpected null in pg_database");
2557  }
2558  else
2559  {
2560  datum = heap_getattr(tuple, Anum_pg_database_datlocale, RelationGetDescr(rel), &isnull);
2561  if (isnull)
2562  elog(ERROR, "unexpected null in pg_database");
2563  }
2564 
2565  newversion = get_collation_actual_version(datForm->datlocprovider,
2566  TextDatumGetCString(datum));
2567 
2568  /* cannot change from NULL to non-NULL or vice versa */
2569  if ((!oldversion && newversion) || (oldversion && !newversion))
2570  elog(ERROR, "invalid collation version change");
2571  else if (oldversion && newversion && strcmp(newversion, oldversion) != 0)
2572  {
2573  bool nulls[Natts_pg_database] = {0};
2574  bool replaces[Natts_pg_database] = {0};
2575  Datum values[Natts_pg_database] = {0};
2576  HeapTuple newtuple;
2577 
2578  ereport(NOTICE,
2579  (errmsg("changing version from %s to %s",
2580  oldversion, newversion)));
2581 
2582  values[Anum_pg_database_datcollversion - 1] = CStringGetTextDatum(newversion);
2583  replaces[Anum_pg_database_datcollversion - 1] = true;
2584 
2585  newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel),
2586  values, nulls, replaces);
2587  CatalogTupleUpdate(rel, &tuple->t_self, newtuple);
2588  heap_freetuple(newtuple);
2589  }
2590  else
2591  ereport(NOTICE,
2592  (errmsg("version has not changed")));
2593  UnlockTuple(rel, &tuple->t_self, InplaceUpdateTupleLock);
2594 
2595  InvokeObjectPostAlterHook(DatabaseRelationId, db_id, 0);
2596 
2597  ObjectAddressSet(address, DatabaseRelationId, db_id);
2598 
2599  systable_endscan(scan);
2600 
2601  table_close(rel, NoLock);
2602 
2603  return address;
2604 }
static Datum values[MAXATTR]
Definition: bootstrap.c:151
#define CStringGetTextDatum(s)
Definition: builtins.h:97
#define TextDatumGetCString(d)
Definition: builtins.h:98
#define elog(elevel,...)
Definition: elog.h:225
#define NOTICE
Definition: elog.h:35
char * get_collation_actual_version(char collprovider, const char *collcollate)
Definition: pg_locale.c:1483

References aclcheck_error(), ACLCHECK_NOT_OWNER, BTEqualStrategyNumber, CatalogTupleUpdate(), CStringGetDatum(), CStringGetTextDatum, elog, ereport, errcode(), errmsg(), ERROR, get_collation_actual_version(), GETSTRUCT, GetUserId(), heap_freetuple(), heap_getattr(), heap_modify_tuple(), HeapTupleIsValid, InplaceUpdateTupleLock, InvokeObjectPostAlterHook, LockTuple(), NoLock, NOTICE, OBJECT_DATABASE, object_ownercheck(), ObjectAddressSet, RelationGetDescr, RowExclusiveLock, ScanKeyInit(), stmt, systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), TextDatumGetCString, UnlockTuple(), and values.

Referenced by standard_ProcessUtility().

◆ AlterDatabaseSet()

Oid AlterDatabaseSet ( AlterDatabaseSetStmt stmt)

Definition at line 2611 of file dbcommands.c.

2612 {
2613  Oid datid = get_database_oid(stmt->dbname, false);
2614 
2615  /*
2616  * Obtain a lock on the database and make sure it didn't go away in the
2617  * meantime.
2618  */
2619  shdepLockAndCheckObject(DatabaseRelationId, datid);
2620 
2621  if (!object_ownercheck(DatabaseRelationId, datid, GetUserId()))
2623  stmt->dbname);
2624 
2625  AlterSetting(datid, InvalidOid, stmt->setstmt);
2626 
2627  UnlockSharedObject(DatabaseRelationId, datid, 0, AccessShareLock);
2628 
2629  return datid;
2630 }
Oid get_database_oid(const char *dbname, bool missing_ok)
Definition: dbcommands.c:3140
void UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1131
#define AccessShareLock
Definition: lockdefs.h:36
void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt)
void shdepLockAndCheckObject(Oid classId, Oid objectId)
Definition: pg_shdepend.c:1211

References AccessShareLock, aclcheck_error(), ACLCHECK_NOT_OWNER, AlterSetting(), get_database_oid(), GetUserId(), InvalidOid, OBJECT_DATABASE, object_ownercheck(), shdepLockAndCheckObject(), stmt, and UnlockSharedObject().

Referenced by standard_ProcessUtility().

◆ check_encoding_locale_matches()

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

Definition at line 1570 of file dbcommands.c.

1571 {
1572  int ctype_encoding = pg_get_encoding_from_locale(ctype, true);
1573  int collate_encoding = pg_get_encoding_from_locale(collate, true);
1574 
1575  if (!(ctype_encoding == encoding ||
1576  ctype_encoding == PG_SQL_ASCII ||
1577  ctype_encoding == -1 ||
1578 #ifdef WIN32
1579  encoding == PG_UTF8 ||
1580 #endif
1581  (encoding == PG_SQL_ASCII && superuser())))
1582  ereport(ERROR,
1583  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1584  errmsg("encoding \"%s\" does not match locale \"%s\"",
1586  ctype),
1587  errdetail("The chosen LC_CTYPE setting requires encoding \"%s\".",
1588  pg_encoding_to_char(ctype_encoding))));
1589 
1590  if (!(collate_encoding == encoding ||
1591  collate_encoding == PG_SQL_ASCII ||
1592  collate_encoding == -1 ||
1593 #ifdef WIN32
1594  encoding == PG_UTF8 ||
1595 #endif
1596  (encoding == PG_SQL_ASCII && superuser())))
1597  ereport(ERROR,
1598  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1599  errmsg("encoding \"%s\" does not match locale \"%s\"",
1601  collate),
1602  errdetail("The chosen LC_COLLATE setting requires encoding \"%s\".",
1603  pg_encoding_to_char(collate_encoding))));
1604 }
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int32 encoding
Definition: pg_database.h:41
@ PG_SQL_ASCII
Definition: pg_wchar.h:226
@ PG_UTF8
Definition: pg_wchar.h:232
#define pg_encoding_to_char
Definition: pg_wchar.h:630
int pg_get_encoding_from_locale(const char *ctype, bool write_message)
Definition: chklocale.c:301
bool superuser(void)
Definition: superuser.c:46

References encoding, ereport, errcode(), errdetail(), errmsg(), ERROR, pg_encoding_to_char, pg_get_encoding_from_locale(), PG_SQL_ASCII, PG_UTF8, and superuser().

Referenced by createdb(), and DefineCollation().

◆ createdb()

Oid createdb ( ParseState pstate,
const CreatedbStmt stmt 
)

Definition at line 683 of file dbcommands.c.

684 {
685  Oid src_dboid;
686  Oid src_owner;
687  int src_encoding = -1;
688  char *src_collate = NULL;
689  char *src_ctype = NULL;
690  char *src_locale = NULL;
691  char *src_icurules = NULL;
692  char src_locprovider = '\0';
693  char *src_collversion = NULL;
694  bool src_istemplate;
695  bool src_hasloginevt = false;
696  bool src_allowconn;
697  TransactionId src_frozenxid = InvalidTransactionId;
698  MultiXactId src_minmxid = InvalidMultiXactId;
699  Oid src_deftablespace;
700  volatile Oid dst_deftablespace;
701  Relation pg_database_rel;
702  HeapTuple tuple;
703  Datum new_record[Natts_pg_database] = {0};
704  bool new_record_nulls[Natts_pg_database] = {0};
705  Oid dboid = InvalidOid;
706  Oid datdba;
707  ListCell *option;
708  DefElem *tablespacenameEl = NULL;
709  DefElem *ownerEl = NULL;
710  DefElem *templateEl = NULL;
711  DefElem *encodingEl = NULL;
712  DefElem *localeEl = NULL;
713  DefElem *builtinlocaleEl = NULL;
714  DefElem *collateEl = NULL;
715  DefElem *ctypeEl = NULL;
716  DefElem *iculocaleEl = NULL;
717  DefElem *icurulesEl = NULL;
718  DefElem *locproviderEl = NULL;
719  DefElem *istemplateEl = NULL;
720  DefElem *allowconnectionsEl = NULL;
721  DefElem *connlimitEl = NULL;
722  DefElem *collversionEl = NULL;
723  DefElem *strategyEl = NULL;
724  char *dbname = stmt->dbname;
725  char *dbowner = NULL;
726  const char *dbtemplate = NULL;
727  char *dbcollate = NULL;
728  char *dbctype = NULL;
729  const char *dblocale = NULL;
730  char *dbicurules = NULL;
731  char dblocprovider = '\0';
732  char *canonname;
733  int encoding = -1;
734  bool dbistemplate = false;
735  bool dballowconnections = true;
736  int dbconnlimit = DATCONNLIMIT_UNLIMITED;
737  char *dbcollversion = NULL;
738  int notherbackends;
739  int npreparedxacts;
740  CreateDBStrategy dbstrategy = CREATEDB_WAL_LOG;
742 
743  /* Extract options from the statement node tree */
744  foreach(option, stmt->options)
745  {
746  DefElem *defel = (DefElem *) lfirst(option);
747 
748  if (strcmp(defel->defname, "tablespace") == 0)
749  {
750  if (tablespacenameEl)
751  errorConflictingDefElem(defel, pstate);
752  tablespacenameEl = defel;
753  }
754  else if (strcmp(defel->defname, "owner") == 0)
755  {
756  if (ownerEl)
757  errorConflictingDefElem(defel, pstate);
758  ownerEl = defel;
759  }
760  else if (strcmp(defel->defname, "template") == 0)
761  {
762  if (templateEl)
763  errorConflictingDefElem(defel, pstate);
764  templateEl = defel;
765  }
766  else if (strcmp(defel->defname, "encoding") == 0)
767  {
768  if (encodingEl)
769  errorConflictingDefElem(defel, pstate);
770  encodingEl = defel;
771  }
772  else if (strcmp(defel->defname, "locale") == 0)
773  {
774  if (localeEl)
775  errorConflictingDefElem(defel, pstate);
776  localeEl = defel;
777  }
778  else if (strcmp(defel->defname, "builtin_locale") == 0)
779  {
780  if (builtinlocaleEl)
781  errorConflictingDefElem(defel, pstate);
782  builtinlocaleEl = defel;
783  }
784  else if (strcmp(defel->defname, "lc_collate") == 0)
785  {
786  if (collateEl)
787  errorConflictingDefElem(defel, pstate);
788  collateEl = defel;
789  }
790  else if (strcmp(defel->defname, "lc_ctype") == 0)
791  {
792  if (ctypeEl)
793  errorConflictingDefElem(defel, pstate);
794  ctypeEl = defel;
795  }
796  else if (strcmp(defel->defname, "icu_locale") == 0)
797  {
798  if (iculocaleEl)
799  errorConflictingDefElem(defel, pstate);
800  iculocaleEl = defel;
801  }
802  else if (strcmp(defel->defname, "icu_rules") == 0)
803  {
804  if (icurulesEl)
805  errorConflictingDefElem(defel, pstate);
806  icurulesEl = defel;
807  }
808  else if (strcmp(defel->defname, "locale_provider") == 0)
809  {
810  if (locproviderEl)
811  errorConflictingDefElem(defel, pstate);
812  locproviderEl = defel;
813  }
814  else if (strcmp(defel->defname, "is_template") == 0)
815  {
816  if (istemplateEl)
817  errorConflictingDefElem(defel, pstate);
818  istemplateEl = defel;
819  }
820  else if (strcmp(defel->defname, "allow_connections") == 0)
821  {
822  if (allowconnectionsEl)
823  errorConflictingDefElem(defel, pstate);
824  allowconnectionsEl = defel;
825  }
826  else if (strcmp(defel->defname, "connection_limit") == 0)
827  {
828  if (connlimitEl)
829  errorConflictingDefElem(defel, pstate);
830  connlimitEl = defel;
831  }
832  else if (strcmp(defel->defname, "collation_version") == 0)
833  {
834  if (collversionEl)
835  errorConflictingDefElem(defel, pstate);
836  collversionEl = defel;
837  }
838  else if (strcmp(defel->defname, "location") == 0)
839  {
841  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
842  errmsg("LOCATION is not supported anymore"),
843  errhint("Consider using tablespaces instead."),
844  parser_errposition(pstate, defel->location)));
845  }
846  else if (strcmp(defel->defname, "oid") == 0)
847  {
848  dboid = defGetObjectId(defel);
849 
850  /*
851  * We don't normally permit new databases to be created with
852  * system-assigned OIDs. pg_upgrade tries to preserve database
853  * OIDs, so we can't allow any database to be created with an OID
854  * that might be in use in a freshly-initialized cluster created
855  * by some future version. We assume all such OIDs will be from
856  * the system-managed OID range.
857  *
858  * As an exception, however, we permit any OID to be assigned when
859  * allow_system_table_mods=on (so that initdb can assign system
860  * OIDs to template0 and postgres) or when performing a binary
861  * upgrade (so that pg_upgrade can preserve whatever OIDs it finds
862  * in the source cluster).
863  */
864  if (dboid < FirstNormalObjectId &&
866  ereport(ERROR,
867  (errcode(ERRCODE_INVALID_PARAMETER_VALUE)),
868  errmsg("OIDs less than %u are reserved for system objects", FirstNormalObjectId));
869  }
870  else if (strcmp(defel->defname, "strategy") == 0)
871  {
872  if (strategyEl)
873  errorConflictingDefElem(defel, pstate);
874  strategyEl = defel;
875  }
876  else
877  ereport(ERROR,
878  (errcode(ERRCODE_SYNTAX_ERROR),
879  errmsg("option \"%s\" not recognized", defel->defname),
880  parser_errposition(pstate, defel->location)));
881  }
882 
883  if (ownerEl && ownerEl->arg)
884  dbowner = defGetString(ownerEl);
885  if (templateEl && templateEl->arg)
886  dbtemplate = defGetString(templateEl);
887  if (encodingEl && encodingEl->arg)
888  {
889  const char *encoding_name;
890 
891  if (IsA(encodingEl->arg, Integer))
892  {
893  encoding = defGetInt32(encodingEl);
894  encoding_name = pg_encoding_to_char(encoding);
895  if (strcmp(encoding_name, "") == 0 ||
896  pg_valid_server_encoding(encoding_name) < 0)
897  ereport(ERROR,
898  (errcode(ERRCODE_UNDEFINED_OBJECT),
899  errmsg("%d is not a valid encoding code",
900  encoding),
901  parser_errposition(pstate, encodingEl->location)));
902  }
903  else
904  {
905  encoding_name = defGetString(encodingEl);
906  encoding = pg_valid_server_encoding(encoding_name);
907  if (encoding < 0)
908  ereport(ERROR,
909  (errcode(ERRCODE_UNDEFINED_OBJECT),
910  errmsg("%s is not a valid encoding name",
911  encoding_name),
912  parser_errposition(pstate, encodingEl->location)));
913  }
914  }
915  if (localeEl && localeEl->arg)
916  {
917  dbcollate = defGetString(localeEl);
918  dbctype = defGetString(localeEl);
919  dblocale = defGetString(localeEl);
920  }
921  if (builtinlocaleEl && builtinlocaleEl->arg)
922  dblocale = defGetString(builtinlocaleEl);
923  if (collateEl && collateEl->arg)
924  dbcollate = defGetString(collateEl);
925  if (ctypeEl && ctypeEl->arg)
926  dbctype = defGetString(ctypeEl);
927  if (iculocaleEl && iculocaleEl->arg)
928  dblocale = defGetString(iculocaleEl);
929  if (icurulesEl && icurulesEl->arg)
930  dbicurules = defGetString(icurulesEl);
931  if (locproviderEl && locproviderEl->arg)
932  {
933  char *locproviderstr = defGetString(locproviderEl);
934 
935  if (pg_strcasecmp(locproviderstr, "builtin") == 0)
936  dblocprovider = COLLPROVIDER_BUILTIN;
937  else if (pg_strcasecmp(locproviderstr, "icu") == 0)
938  dblocprovider = COLLPROVIDER_ICU;
939  else if (pg_strcasecmp(locproviderstr, "libc") == 0)
940  dblocprovider = COLLPROVIDER_LIBC;
941  else
942  ereport(ERROR,
943  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
944  errmsg("unrecognized locale provider: %s",
945  locproviderstr)));
946  }
947  if (istemplateEl && istemplateEl->arg)
948  dbistemplate = defGetBoolean(istemplateEl);
949  if (allowconnectionsEl && allowconnectionsEl->arg)
950  dballowconnections = defGetBoolean(allowconnectionsEl);
951  if (connlimitEl && connlimitEl->arg)
952  {
953  dbconnlimit = defGetInt32(connlimitEl);
954  if (dbconnlimit < DATCONNLIMIT_UNLIMITED)
955  ereport(ERROR,
956  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
957  errmsg("invalid connection limit: %d", dbconnlimit)));
958  }
959  if (collversionEl)
960  dbcollversion = defGetString(collversionEl);
961 
962  /* obtain OID of proposed owner */
963  if (dbowner)
964  datdba = get_role_oid(dbowner, false);
965  else
966  datdba = GetUserId();
967 
968  /*
969  * To create a database, must have createdb privilege and must be able to
970  * become the target role (this does not imply that the target role itself
971  * must have createdb privilege). The latter provision guards against
972  * "giveaway" attacks. Note that a superuser will always have both of
973  * these privileges a fortiori.
974  */
976  ereport(ERROR,
977  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
978  errmsg("permission denied to create database")));
979 
980  check_can_set_role(GetUserId(), datdba);
981 
982  /*
983  * Lookup database (template) to be cloned, and obtain share lock on it.
984  * ShareLock allows two CREATE DATABASEs to work from the same template
985  * concurrently, while ensuring no one is busy dropping it in parallel
986  * (which would be Very Bad since we'd likely get an incomplete copy
987  * without knowing it). This also prevents any new connections from being
988  * made to the source until we finish copying it, so we can be sure it
989  * won't change underneath us.
990  */
991  if (!dbtemplate)
992  dbtemplate = "template1"; /* Default template database name */
993 
994  if (!get_db_info(dbtemplate, ShareLock,
995  &src_dboid, &src_owner, &src_encoding,
996  &src_istemplate, &src_allowconn, &src_hasloginevt,
997  &src_frozenxid, &src_minmxid, &src_deftablespace,
998  &src_collate, &src_ctype, &src_locale, &src_icurules, &src_locprovider,
999  &src_collversion))
1000  ereport(ERROR,
1001  (errcode(ERRCODE_UNDEFINED_DATABASE),
1002  errmsg("template database \"%s\" does not exist",
1003  dbtemplate)));
1004 
1005  /*
1006  * If the source database was in the process of being dropped, we can't
1007  * use it as a template.
1008  */
1009  if (database_is_invalid_oid(src_dboid))
1010  ereport(ERROR,
1011  errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1012  errmsg("cannot use invalid database \"%s\" as template", dbtemplate),
1013  errhint("Use DROP DATABASE to drop invalid databases."));
1014 
1015  /*
1016  * Permission check: to copy a DB that's not marked datistemplate, you
1017  * must be superuser or the owner thereof.
1018  */
1019  if (!src_istemplate)
1020  {
1021  if (!object_ownercheck(DatabaseRelationId, src_dboid, GetUserId()))
1022  ereport(ERROR,
1023  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1024  errmsg("permission denied to copy database \"%s\"",
1025  dbtemplate)));
1026  }
1027 
1028  /* Validate the database creation strategy. */
1029  if (strategyEl && strategyEl->arg)
1030  {
1031  char *strategy;
1032 
1033  strategy = defGetString(strategyEl);
1034  if (pg_strcasecmp(strategy, "wal_log") == 0)
1035  dbstrategy = CREATEDB_WAL_LOG;
1036  else if (pg_strcasecmp(strategy, "file_copy") == 0)
1037  dbstrategy = CREATEDB_FILE_COPY;
1038  else
1039  ereport(ERROR,
1040  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1041  errmsg("invalid create database strategy \"%s\"", strategy),
1042  errhint("Valid strategies are \"wal_log\" and \"file_copy\".")));
1043  }
1044 
1045  /* If encoding or locales are defaulted, use source's setting */
1046  if (encoding < 0)
1047  encoding = src_encoding;
1048  if (dbcollate == NULL)
1049  dbcollate = src_collate;
1050  if (dbctype == NULL)
1051  dbctype = src_ctype;
1052  if (dblocprovider == '\0')
1053  dblocprovider = src_locprovider;
1054  if (dblocale == NULL)
1055  dblocale = src_locale;
1056  if (dbicurules == NULL)
1057  dbicurules = src_icurules;
1058 
1059  /* Some encodings are client only */
1061  ereport(ERROR,
1062  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1063  errmsg("invalid server encoding %d", encoding)));
1064 
1065  /* Check that the chosen locales are valid, and get canonical spellings */
1066  if (!check_locale(LC_COLLATE, dbcollate, &canonname))
1067  ereport(ERROR,
1068  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1069  errmsg("invalid LC_COLLATE locale name: \"%s\"", dbcollate),
1070  errhint("If the locale name is specific to ICU, use ICU_LOCALE.")));
1071  dbcollate = canonname;
1072  if (!check_locale(LC_CTYPE, dbctype, &canonname))
1073  ereport(ERROR,
1074  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1075  errmsg("invalid LC_CTYPE locale name: \"%s\"", dbctype),
1076  errhint("If the locale name is specific to ICU, use ICU_LOCALE.")));
1077  dbctype = canonname;
1078 
1079  check_encoding_locale_matches(encoding, dbcollate, dbctype);
1080 
1081  /* validate provider-specific parameters */
1082  if (dblocprovider != COLLPROVIDER_BUILTIN)
1083  {
1084  if (builtinlocaleEl)
1085  ereport(ERROR,
1086  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1087  errmsg("BUILTIN_LOCALE cannot be specified unless locale provider is builtin")));
1088  }
1089 
1090  if (dblocprovider != COLLPROVIDER_ICU)
1091  {
1092  if (iculocaleEl)
1093  ereport(ERROR,
1094  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1095  errmsg("ICU locale cannot be specified unless locale provider is ICU")));
1096 
1097  if (dbicurules)
1098  ereport(ERROR,
1099  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1100  errmsg("ICU rules cannot be specified unless locale provider is ICU")));
1101  }
1102 
1103  /* validate and canonicalize locale for the provider */
1104  if (dblocprovider == COLLPROVIDER_BUILTIN)
1105  {
1106  /*
1107  * This would happen if template0 uses the libc provider but the new
1108  * database uses builtin.
1109  */
1110  if (!dblocale)
1111  ereport(ERROR,
1112  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1113  errmsg("LOCALE or BUILTIN_LOCALE must be specified")));
1114 
1115  dblocale = builtin_validate_locale(encoding, dblocale);
1116  }
1117  else if (dblocprovider == COLLPROVIDER_ICU)
1118  {
1120  ereport(ERROR,
1121  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1122  errmsg("encoding \"%s\" is not supported with ICU provider",
1124 
1125  /*
1126  * This would happen if template0 uses the libc provider but the new
1127  * database uses icu.
1128  */
1129  if (!dblocale)
1130  ereport(ERROR,
1131  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1132  errmsg("LOCALE or ICU_LOCALE must be specified")));
1133 
1134  /*
1135  * During binary upgrade, or when the locale came from the template
1136  * database, preserve locale string. Otherwise, canonicalize to a
1137  * language tag.
1138  */
1139  if (!IsBinaryUpgrade && dblocale != src_locale)
1140  {
1141  char *langtag = icu_language_tag(dblocale,
1143 
1144  if (langtag && strcmp(dblocale, langtag) != 0)
1145  {
1146  ereport(NOTICE,
1147  (errmsg("using standard form \"%s\" for ICU locale \"%s\"",
1148  langtag, dblocale)));
1149 
1150  dblocale = langtag;
1151  }
1152  }
1153 
1154  icu_validate_locale(dblocale);
1155  }
1156 
1157  /* for libc, locale comes from datcollate and datctype */
1158  if (dblocprovider == COLLPROVIDER_LIBC)
1159  dblocale = NULL;
1160 
1161  /*
1162  * Check that the new encoding and locale settings match the source
1163  * database. We insist on this because we simply copy the source data ---
1164  * any non-ASCII data would be wrongly encoded, and any indexes sorted
1165  * according to the source locale would be wrong.
1166  *
1167  * However, we assume that template0 doesn't contain any non-ASCII data
1168  * nor any indexes that depend on collation or ctype, so template0 can be
1169  * used as template for creating a database with any encoding or locale.
1170  */
1171  if (strcmp(dbtemplate, "template0") != 0)
1172  {
1173  if (encoding != src_encoding)
1174  ereport(ERROR,
1175  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1176  errmsg("new encoding (%s) is incompatible with the encoding of the template database (%s)",
1178  pg_encoding_to_char(src_encoding)),
1179  errhint("Use the same encoding as in the template database, or use template0 as template.")));
1180 
1181  if (strcmp(dbcollate, src_collate) != 0)
1182  ereport(ERROR,
1183  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1184  errmsg("new collation (%s) is incompatible with the collation of the template database (%s)",
1185  dbcollate, src_collate),
1186  errhint("Use the same collation as in the template database, or use template0 as template.")));
1187 
1188  if (strcmp(dbctype, src_ctype) != 0)
1189  ereport(ERROR,
1190  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1191  errmsg("new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database (%s)",
1192  dbctype, src_ctype),
1193  errhint("Use the same LC_CTYPE as in the template database, or use template0 as template.")));
1194 
1195  if (dblocprovider != src_locprovider)
1196  ereport(ERROR,
1197  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1198  errmsg("new locale provider (%s) does not match locale provider of the template database (%s)",
1199  collprovider_name(dblocprovider), collprovider_name(src_locprovider)),
1200  errhint("Use the same locale provider as in the template database, or use template0 as template.")));
1201 
1202  if (dblocprovider == COLLPROVIDER_ICU)
1203  {
1204  char *val1;
1205  char *val2;
1206 
1207  Assert(dblocale);
1208  Assert(src_locale);
1209  if (strcmp(dblocale, src_locale) != 0)
1210  ereport(ERROR,
1211  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1212  errmsg("new ICU locale (%s) is incompatible with the ICU locale of the template database (%s)",
1213  dblocale, src_locale),
1214  errhint("Use the same ICU locale as in the template database, or use template0 as template.")));
1215 
1216  val1 = dbicurules;
1217  if (!val1)
1218  val1 = "";
1219  val2 = src_icurules;
1220  if (!val2)
1221  val2 = "";
1222  if (strcmp(val1, val2) != 0)
1223  ereport(ERROR,
1224  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1225  errmsg("new ICU collation rules (%s) are incompatible with the ICU collation rules of the template database (%s)",
1226  val1, val2),
1227  errhint("Use the same ICU collation rules as in the template database, or use template0 as template.")));
1228  }
1229  }
1230 
1231  /*
1232  * If we got a collation version for the template database, check that it
1233  * matches the actual OS collation version. Otherwise error; the user
1234  * needs to fix the template database first. Don't complain if a
1235  * collation version was specified explicitly as a statement option; that
1236  * is used by pg_upgrade to reproduce the old state exactly.
1237  *
1238  * (If the template database has no collation version, then either the
1239  * platform/provider does not support collation versioning, or it's
1240  * template0, for which we stipulate that it does not contain
1241  * collation-using objects.)
1242  */
1243  if (src_collversion && !collversionEl)
1244  {
1245  char *actual_versionstr;
1246  const char *locale;
1247 
1248  if (dblocprovider == COLLPROVIDER_LIBC)
1249  locale = dbcollate;
1250  else
1251  locale = dblocale;
1252 
1253  actual_versionstr = get_collation_actual_version(dblocprovider, locale);
1254  if (!actual_versionstr)
1255  ereport(ERROR,
1256  (errmsg("template database \"%s\" has a collation version, but no actual collation version could be determined",
1257  dbtemplate)));
1258 
1259  if (strcmp(actual_versionstr, src_collversion) != 0)
1260  ereport(ERROR,
1261  (errmsg("template database \"%s\" has a collation version mismatch",
1262  dbtemplate),
1263  errdetail("The template database was created using collation version %s, "
1264  "but the operating system provides version %s.",
1265  src_collversion, actual_versionstr),
1266  errhint("Rebuild all objects in the template database that use the default collation and run "
1267  "ALTER DATABASE %s REFRESH COLLATION VERSION, "
1268  "or build PostgreSQL with the right library version.",
1269  quote_identifier(dbtemplate))));
1270  }
1271 
1272  if (dbcollversion == NULL)
1273  dbcollversion = src_collversion;
1274 
1275  /*
1276  * Normally, we copy the collation version from the template database.
1277  * This last resort only applies if the template database does not have a
1278  * collation version, which is normally only the case for template0.
1279  */
1280  if (dbcollversion == NULL)
1281  {
1282  const char *locale;
1283 
1284  if (dblocprovider == COLLPROVIDER_LIBC)
1285  locale = dbcollate;
1286  else
1287  locale = dblocale;
1288 
1289  dbcollversion = get_collation_actual_version(dblocprovider, locale);
1290  }
1291 
1292  /* Resolve default tablespace for new database */
1293  if (tablespacenameEl && tablespacenameEl->arg)
1294  {
1295  char *tablespacename;
1296  AclResult aclresult;
1297 
1298  tablespacename = defGetString(tablespacenameEl);
1299  dst_deftablespace = get_tablespace_oid(tablespacename, false);
1300  /* check permissions */
1301  aclresult = object_aclcheck(TableSpaceRelationId, dst_deftablespace, GetUserId(),
1302  ACL_CREATE);
1303  if (aclresult != ACLCHECK_OK)
1304  aclcheck_error(aclresult, OBJECT_TABLESPACE,
1305  tablespacename);
1306 
1307  /* pg_global must never be the default tablespace */
1308  if (dst_deftablespace == GLOBALTABLESPACE_OID)
1309  ereport(ERROR,
1310  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1311  errmsg("pg_global cannot be used as default tablespace")));
1312 
1313  /*
1314  * If we are trying to change the default tablespace of the template,
1315  * we require that the template not have any files in the new default
1316  * tablespace. This is necessary because otherwise the copied
1317  * database would contain pg_class rows that refer to its default
1318  * tablespace both explicitly (by OID) and implicitly (as zero), which
1319  * would cause problems. For example another CREATE DATABASE using
1320  * the copied database as template, and trying to change its default
1321  * tablespace again, would yield outright incorrect results (it would
1322  * improperly move tables to the new default tablespace that should
1323  * stay in the same tablespace).
1324  */
1325  if (dst_deftablespace != src_deftablespace)
1326  {
1327  char *srcpath;
1328  struct stat st;
1329 
1330  srcpath = GetDatabasePath(src_dboid, dst_deftablespace);
1331 
1332  if (stat(srcpath, &st) == 0 &&
1333  S_ISDIR(st.st_mode) &&
1334  !directory_is_empty(srcpath))
1335  ereport(ERROR,
1336  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1337  errmsg("cannot assign new default tablespace \"%s\"",
1338  tablespacename),
1339  errdetail("There is a conflict because database \"%s\" already has some tables in this tablespace.",
1340  dbtemplate)));
1341  pfree(srcpath);
1342  }
1343  }
1344  else
1345  {
1346  /* Use template database's default tablespace */
1347  dst_deftablespace = src_deftablespace;
1348  /* Note there is no additional permission check in this path */
1349  }
1350 
1351  /*
1352  * If built with appropriate switch, whine when regression-testing
1353  * conventions for database names are violated. But don't complain during
1354  * initdb.
1355  */
1356 #ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
1357  if (IsUnderPostmaster && strstr(dbname, "regression") == NULL)
1358  elog(WARNING, "databases created by regression test cases should have names including \"regression\"");
1359 #endif
1360 
1361  /*
1362  * Check for db name conflict. This is just to give a more friendly error
1363  * message than "unique index violation". There's a race condition but
1364  * we're willing to accept the less friendly message in that case.
1365  */
1366  if (OidIsValid(get_database_oid(dbname, true)))
1367  ereport(ERROR,
1368  (errcode(ERRCODE_DUPLICATE_DATABASE),
1369  errmsg("database \"%s\" already exists", dbname)));
1370 
1371  /*
1372  * The source DB can't have any active backends, except this one
1373  * (exception is to allow CREATE DB while connected to template1).
1374  * Otherwise we might copy inconsistent data.
1375  *
1376  * This should be last among the basic error checks, because it involves
1377  * potential waiting; we may as well throw an error first if we're gonna
1378  * throw one.
1379  */
1380  if (CountOtherDBBackends(src_dboid, &notherbackends, &npreparedxacts))
1381  ereport(ERROR,
1382  (errcode(ERRCODE_OBJECT_IN_USE),
1383  errmsg("source database \"%s\" is being accessed by other users",
1384  dbtemplate),
1385  errdetail_busy_db(notherbackends, npreparedxacts)));
1386 
1387  /*
1388  * Select an OID for the new database, checking that it doesn't have a
1389  * filename conflict with anything already existing in the tablespace
1390  * directories.
1391  */
1392  pg_database_rel = table_open(DatabaseRelationId, RowExclusiveLock);
1393 
1394  /*
1395  * If database OID is configured, check if the OID is already in use or
1396  * data directory already exists.
1397  */
1398  if (OidIsValid(dboid))
1399  {
1400  char *existing_dbname = get_database_name(dboid);
1401 
1402  if (existing_dbname != NULL)
1403  ereport(ERROR,
1404  (errcode(ERRCODE_INVALID_PARAMETER_VALUE)),
1405  errmsg("database OID %u is already in use by database \"%s\"",
1406  dboid, existing_dbname));
1407 
1408  if (check_db_file_conflict(dboid))
1409  ereport(ERROR,
1410  (errcode(ERRCODE_INVALID_PARAMETER_VALUE)),
1411  errmsg("data directory with the specified OID %u already exists", dboid));
1412  }
1413  else
1414  {
1415  /* Select an OID for the new database if is not explicitly configured. */
1416  do
1417  {
1418  dboid = GetNewOidWithIndex(pg_database_rel, DatabaseOidIndexId,
1419  Anum_pg_database_oid);
1420  } while (check_db_file_conflict(dboid));
1421  }
1422 
1423  /*
1424  * Insert a new tuple into pg_database. This establishes our ownership of
1425  * the new database name (anyone else trying to insert the same name will
1426  * block on the unique index, and fail after we commit).
1427  */
1428 
1429  Assert((dblocprovider != COLLPROVIDER_LIBC && dblocale) ||
1430  (dblocprovider == COLLPROVIDER_LIBC && !dblocale));
1431 
1432  /* Form tuple */
1433  new_record[Anum_pg_database_oid - 1] = ObjectIdGetDatum(dboid);
1434  new_record[Anum_pg_database_datname - 1] =
1436  new_record[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(datdba);
1437  new_record[Anum_pg_database_encoding - 1] = Int32GetDatum(encoding);
1438  new_record[Anum_pg_database_datlocprovider - 1] = CharGetDatum(dblocprovider);
1439  new_record[Anum_pg_database_datistemplate - 1] = BoolGetDatum(dbistemplate);
1440  new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(dballowconnections);
1441  new_record[Anum_pg_database_dathasloginevt - 1] = BoolGetDatum(src_hasloginevt);
1442  new_record[Anum_pg_database_datconnlimit - 1] = Int32GetDatum(dbconnlimit);
1443  new_record[Anum_pg_database_datfrozenxid - 1] = TransactionIdGetDatum(src_frozenxid);
1444  new_record[Anum_pg_database_datminmxid - 1] = TransactionIdGetDatum(src_minmxid);
1445  new_record[Anum_pg_database_dattablespace - 1] = ObjectIdGetDatum(dst_deftablespace);
1446  new_record[Anum_pg_database_datcollate - 1] = CStringGetTextDatum(dbcollate);
1447  new_record[Anum_pg_database_datctype - 1] = CStringGetTextDatum(dbctype);
1448  if (dblocale)
1449  new_record[Anum_pg_database_datlocale - 1] = CStringGetTextDatum(dblocale);
1450  else
1451  new_record_nulls[Anum_pg_database_datlocale - 1] = true;
1452  if (dbicurules)
1453  new_record[Anum_pg_database_daticurules - 1] = CStringGetTextDatum(dbicurules);
1454  else
1455  new_record_nulls[Anum_pg_database_daticurules - 1] = true;
1456  if (dbcollversion)
1457  new_record[Anum_pg_database_datcollversion - 1] = CStringGetTextDatum(dbcollversion);
1458  else
1459  new_record_nulls[Anum_pg_database_datcollversion - 1] = true;
1460 
1461  /*
1462  * We deliberately set datacl to default (NULL), rather than copying it
1463  * from the template database. Copying it would be a bad idea when the
1464  * owner is not the same as the template's owner.
1465  */
1466  new_record_nulls[Anum_pg_database_datacl - 1] = true;
1467 
1468  tuple = heap_form_tuple(RelationGetDescr(pg_database_rel),
1469  new_record, new_record_nulls);
1470 
1471  CatalogTupleInsert(pg_database_rel, tuple);
1472 
1473  /*
1474  * Now generate additional catalog entries associated with the new DB
1475  */
1476 
1477  /* Register owner dependency */
1478  recordDependencyOnOwner(DatabaseRelationId, dboid, datdba);
1479 
1480  /* Create pg_shdepend entries for objects within database */
1481  copyTemplateDependencies(src_dboid, dboid);
1482 
1483  /* Post creation hook for new database */
1484  InvokeObjectPostCreateHook(DatabaseRelationId, dboid, 0);
1485 
1486  /*
1487  * If we're going to be reading data for the to-be-created database into
1488  * shared_buffers, take a lock on it. Nobody should know that this
1489  * database exists yet, but it's good to maintain the invariant that an
1490  * AccessExclusiveLock on the database is sufficient to drop all of its
1491  * buffers without worrying about more being read later.
1492  *
1493  * Note that we need to do this before entering the
1494  * PG_ENSURE_ERROR_CLEANUP block below, because createdb_failure_callback
1495  * expects this lock to be held already.
1496  */
1497  if (dbstrategy == CREATEDB_WAL_LOG)
1498  LockSharedObject(DatabaseRelationId, dboid, 0, AccessShareLock);
1499 
1500  /*
1501  * Once we start copying subdirectories, we need to be able to clean 'em
1502  * up if we fail. Use an ENSURE block to make sure this happens. (This
1503  * is not a 100% solution, because of the possibility of failure during
1504  * transaction commit after we leave this routine, but it should handle
1505  * most scenarios.)
1506  */
1507  fparms.src_dboid = src_dboid;
1508  fparms.dest_dboid = dboid;
1509  fparms.strategy = dbstrategy;
1510 
1512  PointerGetDatum(&fparms));
1513  {
1514  /*
1515  * If the user has asked to create a database with WAL_LOG strategy
1516  * then call CreateDatabaseUsingWalLog, which will copy the database
1517  * at the block level and it will WAL log each copied block.
1518  * Otherwise, call CreateDatabaseUsingFileCopy that will copy the
1519  * database file by file.
1520  */
1521  if (dbstrategy == CREATEDB_WAL_LOG)
1522  CreateDatabaseUsingWalLog(src_dboid, dboid, src_deftablespace,
1523  dst_deftablespace);
1524  else
1525  CreateDatabaseUsingFileCopy(src_dboid, dboid, src_deftablespace,
1526  dst_deftablespace);
1527 
1528  /*
1529  * Close pg_database, but keep lock till commit.
1530  */
1531  table_close(pg_database_rel, NoLock);
1532 
1533  /*
1534  * Force synchronous commit, thus minimizing the window between
1535  * creation of the database files and committal of the transaction. If
1536  * we crash before committing, we'll have a DB that's taking up disk
1537  * space but is not in pg_database, which is not good.
1538  */
1539  ForceSyncCommit();
1540  }
1542  PointerGetDatum(&fparms));
1543 
1544  return dboid;
1545 }
Oid get_role_oid(const char *rolname, bool missing_ok)
Definition: acl.c:5554
AclResult
Definition: acl.h:182
@ ACLCHECK_OK
Definition: acl.h:183
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition: aclchk.c:3810
bool directory_is_empty(const char *path)
Definition: tablespace.c:853
Oid get_tablespace_oid(const char *tablespacename, bool missing_ok)
Definition: tablespace.c:1426
#define Assert(condition)
Definition: c.h:837
TransactionId MultiXactId
Definition: c.h:641
uint32 TransactionId
Definition: c.h:631
#define OidIsValid(objectId)
Definition: c.h:754
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:419
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3187
CreateDBStrategy
Definition: dbcommands.c:83
@ CREATEDB_FILE_COPY
Definition: dbcommands.c:85
@ CREATEDB_WAL_LOG
Definition: dbcommands.c:84
static void CreateDatabaseUsingWalLog(Oid src_dboid, Oid dst_dboid, Oid src_tsid, Oid dst_tsid)
Definition: dbcommands.c:148
void check_encoding_locale_matches(int encoding, const char *collate, const char *ctype)
Definition: dbcommands.c:1570
static int errdetail_busy_db(int notherbackends, int npreparedxacts)
Definition: dbcommands.c:3110
static bool check_db_file_conflict(Oid db_id)
Definition: dbcommands.c:3067
static void CreateDatabaseUsingFileCopy(Oid src_dboid, Oid dst_dboid, Oid src_tsid, Oid dst_tsid)
Definition: dbcommands.c:550
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)
Definition: dbcommands.c:2794
static void createdb_failure_callback(int code, Datum arg)
Definition: dbcommands.c:1608
bool database_is_invalid_oid(Oid dboid)
Definition: dbcommands.c:3221
Oid defGetObjectId(DefElem *def)
Definition: define.c:219
#define WARNING
Definition: elog.h:36
bool is_encoding_supported_by_icu(int encoding)
Definition: encnames.c:461
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:641
bool IsBinaryUpgrade
Definition: globals.c:120
bool IsUnderPostmaster
Definition: globals.c:119
bool allowSystemTableMods
Definition: globals.c:129
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1116
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:233
static char * locale
Definition: initdb.c:140
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:47
#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)
Definition: ipc.h:52
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1072
#define ShareLock
Definition: lockdefs.h:40
void pfree(void *pointer)
Definition: mcxt.c:1521
#define InvalidMultiXactId
Definition: multixact.h:24
Datum namein(PG_FUNCTION_ARGS)
Definition: name.c:48
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:173
@ OBJECT_TABLESPACE
Definition: parsenodes.h:2310
#define ACL_CREATE
Definition: parsenodes.h:85
int icu_validation_level
Definition: pg_locale.c:124
void icu_validate_locale(const char *loc_str)
Definition: pg_locale.c:1920
char * icu_language_tag(const char *loc_str, int elevel)
Definition: pg_locale.c:1862
const char * builtin_validate_locale(int encoding, const char *locale)
Definition: pg_locale.c:1824
bool check_locale(int category, const char *locale, char **canonname)
Definition: pg_locale.c:304
void copyTemplateDependencies(Oid templateDbId, Oid newDbId)
Definition: pg_shdepend.c:895
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:168
#define PG_VALID_BE_ENCODING(_enc)
Definition: pg_wchar.h:281
#define pg_valid_server_encoding
Definition: pg_wchar.h:631
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
static Datum TransactionIdGetDatum(TransactionId X)
Definition: postgres.h:272
static Datum CharGetDatum(char X)
Definition: postgres.h:122
bool CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared)
Definition: procarray.c:3754
char * GetDatabasePath(Oid dbOid, Oid spcOid)
Definition: relpath.c:110
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:12868
Definition: value.h:29
CreateDBStrategy strategy
Definition: dbcommands.c:92
#define InvalidTransactionId
Definition: transam.h:31
#define FirstNormalObjectId
Definition: transam.h:197
#define stat
Definition: win32_port.h:284
#define S_ISDIR(m)
Definition: win32_port.h:325
void ForceSyncCommit(void)
Definition: xact.c:1151

References AccessShareLock, ACL_CREATE, aclcheck_error(), ACLCHECK_OK, allowSystemTableMods, DefElem::arg, Assert, BoolGetDatum(), builtin_validate_locale(), CatalogTupleInsert(), CharGetDatum(), check_can_set_role(), check_db_file_conflict(), check_encoding_locale_matches(), check_locale(), copyTemplateDependencies(), CountOtherDBBackends(), CreateDatabaseUsingFileCopy(), CreateDatabaseUsingWalLog(), createdb_failure_callback(), CREATEDB_FILE_COPY, CREATEDB_WAL_LOG, CStringGetDatum(), CStringGetTextDatum, database_is_invalid_oid(), DATCONNLIMIT_UNLIMITED, dbname, defGetBoolean(), defGetInt32(), defGetObjectId(), defGetString(), DefElem::defname, createdb_failure_params::dest_dboid, DirectFunctionCall1, directory_is_empty(), elog, encoding, ereport, errcode(), errdetail(), errdetail_busy_db(), errhint(), errmsg(), ERROR, errorConflictingDefElem(), FirstNormalObjectId, ForceSyncCommit(), get_collation_actual_version(), get_database_name(), get_database_oid(), get_db_info(), get_role_oid(), get_tablespace_oid(), GetDatabasePath(), GetNewOidWithIndex(), GetUserId(), have_createdb_privilege(), heap_form_tuple(), icu_language_tag(), icu_validate_locale(), icu_validation_level, Int32GetDatum(), InvalidMultiXactId, InvalidOid, InvalidTransactionId, InvokeObjectPostCreateHook, is_encoding_supported_by_icu(), IsA, IsBinaryUpgrade, IsUnderPostmaster, lfirst, locale, DefElem::location, LockSharedObject(), namein(), NoLock, NOTICE, object_aclcheck(), object_ownercheck(), OBJECT_TABLESPACE, ObjectIdGetDatum(), OidIsValid, parser_errposition(), pfree(), pg_encoding_to_char, PG_END_ENSURE_ERROR_CLEANUP, PG_ENSURE_ERROR_CLEANUP, pg_strcasecmp(), PG_VALID_BE_ENCODING, pg_valid_server_encoding, PointerGetDatum(), quote_identifier(), recordDependencyOnOwner(), RelationGetDescr, RowExclusiveLock, S_ISDIR, ShareLock, createdb_failure_params::src_dboid, stat::st_mode, stat, stmt, createdb_failure_params::strategy, table_close(), table_open(), TransactionIdGetDatum(), and WARNING.

Referenced by CreateRole(), main(), and standard_ProcessUtility().

◆ DropDatabase()

void DropDatabase ( ParseState pstate,
DropdbStmt stmt 
)

Definition at line 2316 of file dbcommands.c.

2317 {
2318  bool force = false;
2319  ListCell *lc;
2320 
2321  foreach(lc, stmt->options)
2322  {
2323  DefElem *opt = (DefElem *) lfirst(lc);
2324 
2325  if (strcmp(opt->defname, "force") == 0)
2326  force = true;
2327  else
2328  ereport(ERROR,
2329  (errcode(ERRCODE_SYNTAX_ERROR),
2330  errmsg("unrecognized DROP DATABASE option \"%s\"", opt->defname),
2331  parser_errposition(pstate, opt->location)));
2332  }
2333 
2334  dropdb(stmt->dbname, stmt->missing_ok, force);
2335 }
void dropdb(const char *dbname, bool missing_ok, bool force)
Definition: dbcommands.c:1647

References DefElem::defname, dropdb(), ereport, errcode(), errmsg(), ERROR, lfirst, DefElem::location, parser_errposition(), and stmt.

Referenced by standard_ProcessUtility().

◆ dropdb()

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

Definition at line 1647 of file dbcommands.c.

1648 {
1649  Oid db_id;
1650  bool db_istemplate;
1651  Relation pgdbrel;
1652  HeapTuple tup;
1653  ScanKeyData scankey;
1654  void *inplace_state;
1655  Form_pg_database datform;
1656  int notherbackends;
1657  int npreparedxacts;
1658  int nslots,
1659  nslots_active;
1660  int nsubscriptions;
1661 
1662  /*
1663  * Look up the target database's OID, and get exclusive lock on it. We
1664  * need this to ensure that no new backend starts up in the target
1665  * database while we are deleting it (see postinit.c), and that no one is
1666  * using it as a CREATE DATABASE template or trying to delete it for
1667  * themselves.
1668  */
1669  pgdbrel = table_open(DatabaseRelationId, RowExclusiveLock);
1670 
1671  if (!get_db_info(dbname, AccessExclusiveLock, &db_id, NULL, NULL,
1672  &db_istemplate, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
1673  {
1674  if (!missing_ok)
1675  {
1676  ereport(ERROR,
1677  (errcode(ERRCODE_UNDEFINED_DATABASE),
1678  errmsg("database \"%s\" does not exist", dbname)));
1679  }
1680  else
1681  {
1682  /* Close pg_database, release the lock, since we changed nothing */
1683  table_close(pgdbrel, RowExclusiveLock);
1684  ereport(NOTICE,
1685  (errmsg("database \"%s\" does not exist, skipping",
1686  dbname)));
1687  return;
1688  }
1689  }
1690 
1691  /*
1692  * Permission checks
1693  */
1694  if (!object_ownercheck(DatabaseRelationId, db_id, GetUserId()))
1696  dbname);
1697 
1698  /* DROP hook for the database being removed */
1699  InvokeObjectDropHook(DatabaseRelationId, db_id, 0);
1700 
1701  /*
1702  * Disallow dropping a DB that is marked istemplate. This is just to
1703  * prevent people from accidentally dropping template0 or template1; they
1704  * can do so if they're really determined ...
1705  */
1706  if (db_istemplate)
1707  ereport(ERROR,
1708  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1709  errmsg("cannot drop a template database")));
1710 
1711  /* Obviously can't drop my own database */
1712  if (db_id == MyDatabaseId)
1713  ereport(ERROR,
1714  (errcode(ERRCODE_OBJECT_IN_USE),
1715  errmsg("cannot drop the currently open database")));
1716 
1717  /*
1718  * Check whether there are active logical slots that refer to the
1719  * to-be-dropped database. The database lock we are holding prevents the
1720  * creation of new slots using the database or existing slots becoming
1721  * active.
1722  */
1723  (void) ReplicationSlotsCountDBSlots(db_id, &nslots, &nslots_active);
1724  if (nslots_active)
1725  {
1726  ereport(ERROR,
1727  (errcode(ERRCODE_OBJECT_IN_USE),
1728  errmsg("database \"%s\" is used by an active logical replication slot",
1729  dbname),
1730  errdetail_plural("There is %d active slot.",
1731  "There are %d active slots.",
1732  nslots_active, nslots_active)));
1733  }
1734 
1735  /*
1736  * Check if there are subscriptions defined in the target database.
1737  *
1738  * We can't drop them automatically because they might be holding
1739  * resources in other databases/instances.
1740  */
1741  if ((nsubscriptions = CountDBSubscriptions(db_id)) > 0)
1742  ereport(ERROR,
1743  (errcode(ERRCODE_OBJECT_IN_USE),
1744  errmsg("database \"%s\" is being used by logical replication subscription",
1745  dbname),
1746  errdetail_plural("There is %d subscription.",
1747  "There are %d subscriptions.",
1748  nsubscriptions, nsubscriptions)));
1749 
1750 
1751  /*
1752  * Attempt to terminate all existing connections to the target database if
1753  * the user has requested to do so.
1754  */
1755  if (force)
1756  TerminateOtherDBBackends(db_id);
1757 
1758  /*
1759  * Check for other backends in the target database. (Because we hold the
1760  * database lock, no new ones can start after this.)
1761  *
1762  * As in CREATE DATABASE, check this after other error conditions.
1763  */
1764  if (CountOtherDBBackends(db_id, &notherbackends, &npreparedxacts))
1765  ereport(ERROR,
1766  (errcode(ERRCODE_OBJECT_IN_USE),
1767  errmsg("database \"%s\" is being accessed by other users",
1768  dbname),
1769  errdetail_busy_db(notherbackends, npreparedxacts)));
1770 
1771  /*
1772  * Delete any comments or security labels associated with the database.
1773  */
1774  DeleteSharedComments(db_id, DatabaseRelationId);
1775  DeleteSharedSecurityLabel(db_id, DatabaseRelationId);
1776 
1777  /*
1778  * Remove settings associated with this database
1779  */
1780  DropSetting(db_id, InvalidOid);
1781 
1782  /*
1783  * Remove shared dependency references for the database.
1784  */
1785  dropDatabaseDependencies(db_id);
1786 
1787  /*
1788  * Tell the cumulative stats system to forget it immediately, too.
1789  */
1790  pgstat_drop_database(db_id);
1791 
1792  /*
1793  * Except for the deletion of the catalog row, subsequent actions are not
1794  * transactional (consider DropDatabaseBuffers() discarding modified
1795  * buffers). But we might crash or get interrupted below. To prevent
1796  * accesses to a database with invalid contents, mark the database as
1797  * invalid using an in-place update.
1798  *
1799  * We need to flush the WAL before continuing, to guarantee the
1800  * modification is durable before performing irreversible filesystem
1801  * operations.
1802  */
1803  ScanKeyInit(&scankey,
1804  Anum_pg_database_datname,
1805  BTEqualStrategyNumber, F_NAMEEQ,
1807  systable_inplace_update_begin(pgdbrel, DatabaseNameIndexId, true,
1808  NULL, 1, &scankey, &tup, &inplace_state);
1809  if (!HeapTupleIsValid(tup))
1810  elog(ERROR, "cache lookup failed for database %u", db_id);
1811  datform = (Form_pg_database) GETSTRUCT(tup);
1812  datform->datconnlimit = DATCONNLIMIT_INVALID_DB;
1813  systable_inplace_update_finish(inplace_state, tup);
1815 
1816  /*
1817  * Also delete the tuple - transactionally. If this transaction commits,
1818  * the row will be gone, but if we fail, dropdb() can be invoked again.
1819  */
1820  CatalogTupleDelete(pgdbrel, &tup->t_self);
1821  heap_freetuple(tup);
1822 
1823  /*
1824  * Drop db-specific replication slots.
1825  */
1827 
1828  /*
1829  * Drop pages for this database that are in the shared buffer cache. This
1830  * is important to ensure that no remaining backend tries to write out a
1831  * dirty buffer to the dead database later...
1832  */
1833  DropDatabaseBuffers(db_id);
1834 
1835  /*
1836  * Tell checkpointer to forget any pending fsync and unlink requests for
1837  * files in the database; else the fsyncs will fail at next checkpoint, or
1838  * worse, it will delete files that belong to a newly created database
1839  * with the same OID.
1840  */
1842 
1843  /*
1844  * Force a checkpoint to make sure the checkpointer has received the
1845  * message sent by ForgetDatabaseSyncRequests.
1846  */
1848 
1849  /* Close all smgr fds in all backends. */
1851 
1852  /*
1853  * Remove all tablespace subdirs belonging to the database.
1854  */
1855  remove_dbtablespaces(db_id);
1856 
1857  /*
1858  * Close pg_database, but keep lock till commit.
1859  */
1860  table_close(pgdbrel, NoLock);
1861 
1862  /*
1863  * Force synchronous commit, thus minimizing the window between removal of
1864  * the database files and committal of the transaction. If we crash before
1865  * committing, we'll have a DB that's gone on disk but still there
1866  * according to pg_database, which is not good.
1867  */
1868  ForceSyncCommit();
1869 }
void DropDatabaseBuffers(Oid dbid)
Definition: bufmgr.c:4386
void RequestCheckpoint(int flags)
Definition: checkpointer.c:952
void DeleteSharedComments(Oid oid, Oid classoid)
Definition: comment.c:374
static void remove_dbtablespaces(Oid db_id)
Definition: dbcommands.c:2977
int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1295
void systable_inplace_update_begin(Relation relation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, const ScanKeyData *key, HeapTuple *oldtupcopy, void **state)
Definition: genam.c:806
void systable_inplace_update_finish(void *state, HeapTuple tuple)
Definition: genam.c:882
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:365
#define AccessExclusiveLock
Definition: lockdefs.h:43
void ForgetDatabaseSyncRequests(Oid dbid)
Definition: md.c:1449
#define InvokeObjectDropHook(classId, objectId, subId)
Definition: objectaccess.h:182
#define DATCONNLIMIT_INVALID_DB
Definition: pg_database.h:124
void DropSetting(Oid databaseid, Oid roleid)
void dropDatabaseDependencies(Oid databaseId)
Definition: pg_shdepend.c:999
int CountDBSubscriptions(Oid dbid)
void pgstat_drop_database(Oid databaseid)
void TerminateOtherDBBackends(Oid databaseId)
Definition: procarray.c:3832
void WaitForProcSignalBarrier(uint64 generation)
Definition: procsignal.c:421
uint64 EmitProcSignalBarrier(ProcSignalBarrierType type)
Definition: procsignal.c:353
@ PROCSIGNAL_BARRIER_SMGRRELEASE
Definition: procsignal.h:56
void DeleteSharedSecurityLabel(Oid objectId, Oid classId)
Definition: seclabel.c:491
bool ReplicationSlotsCountDBSlots(Oid dboid, int *nslots, int *nactive)
Definition: slot.c:1240
void ReplicationSlotsDropDBSlots(Oid dboid)
Definition: slot.c:1298
XLogRecPtr XactLastRecEnd
Definition: xlog.c:254
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2802
#define CHECKPOINT_FORCE
Definition: xlog.h:142
#define CHECKPOINT_WAIT
Definition: xlog.h:145
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:141

References AccessExclusiveLock, aclcheck_error(), ACLCHECK_NOT_OWNER, BTEqualStrategyNumber, CatalogTupleDelete(), CHECKPOINT_FORCE, CHECKPOINT_IMMEDIATE, CHECKPOINT_WAIT, CountDBSubscriptions(), CountOtherDBBackends(), CStringGetDatum(), DATCONNLIMIT_INVALID_DB, dbname, DeleteSharedComments(), DeleteSharedSecurityLabel(), DropDatabaseBuffers(), dropDatabaseDependencies(), DropSetting(), elog, EmitProcSignalBarrier(), ereport, errcode(), errdetail_busy_db(), errdetail_plural(), errmsg(), ERROR, ForceSyncCommit(), ForgetDatabaseSyncRequests(), get_db_info(), GETSTRUCT, GetUserId(), heap_freetuple(), HeapTupleIsValid, InvalidOid, InvokeObjectDropHook, MyDatabaseId, NoLock, NOTICE, OBJECT_DATABASE, object_ownercheck(), pgstat_drop_database(), PROCSIGNAL_BARRIER_SMGRRELEASE, remove_dbtablespaces(), ReplicationSlotsCountDBSlots(), ReplicationSlotsDropDBSlots(), RequestCheckpoint(), RowExclusiveLock, ScanKeyInit(), systable_inplace_update_begin(), systable_inplace_update_finish(), HeapTupleData::t_self, table_close(), table_open(), TerminateOtherDBBackends(), WaitForProcSignalBarrier(), XactLastRecEnd, and XLogFlush().

Referenced by DropDatabase().

◆ get_database_name()

char* get_database_name ( Oid  dbid)

Definition at line 3187 of file dbcommands.c.

3188 {
3189  HeapTuple dbtuple;
3190  char *result;
3191 
3192  dbtuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(dbid));
3193  if (HeapTupleIsValid(dbtuple))
3194  {
3195  result = pstrdup(NameStr(((Form_pg_database) GETSTRUCT(dbtuple))->datname));
3196  ReleaseSysCache(dbtuple);
3197  }
3198  else
3199  result = NULL;
3200 
3201  return result;
3202 }
#define NameStr(name)
Definition: c.h:725
char * pstrdup(const char *in)
Definition: mcxt.c:1696
NameData datname
Definition: pg_database.h:35
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221

References datname, GETSTRUCT, HeapTupleIsValid, NameStr, ObjectIdGetDatum(), pstrdup(), ReleaseSysCache(), and SearchSysCache1().

Referenced by AfterTriggerSetState(), AlterObjectRename_internal(), AlterPublicationOwner_internal(), AlterSchemaOwner_internal(), AlterSubscriptionOwner_internal(), calculate_database_size(), createdb(), CreatePublication(), CreateSchemaCommand(), CreateSubscription(), current_database(), database_to_xml_internal(), DeconstructQualifiedName(), do_analyze_rel(), do_autovacuum(), exec_object_restorecon(), ExpandColumnRefStar(), GetNewMultiXactId(), GetNewTransactionId(), getObjectDescription(), getObjectIdentityParts(), heap_vacuum_rel(), IdentifySystem(), InitTempTableNamespace(), map_sql_catalog_to_xmlschema_types(), map_sql_schema_to_xmlschema_types(), map_sql_table_to_xmlschema(), map_sql_type_to_xml_name(), perform_work_item(), RangeVarGetAndCheckCreationNamespace(), RangeVarGetCreationNamespace(), RangeVarGetRelidExtended(), ReindexMultipleTables(), RenameSchema(), SetMultiXactIdLimit(), SetTransactionIdLimit(), shdepLockAndCheckObject(), TerminateOtherDBBackends(), and transformColumnRef().

◆ get_database_oid()

Oid get_database_oid ( const char *  dbname,
bool  missing_ok 
)

Definition at line 3140 of file dbcommands.c.

3141 {
3142  Relation pg_database;
3143  ScanKeyData entry[1];
3144  SysScanDesc scan;
3145  HeapTuple dbtuple;
3146  Oid oid;
3147 
3148  /*
3149  * There's no syscache for pg_database indexed by name, so we must look
3150  * the hard way.
3151  */
3152  pg_database = table_open(DatabaseRelationId, AccessShareLock);
3153  ScanKeyInit(&entry[0],
3154  Anum_pg_database_datname,
3155  BTEqualStrategyNumber, F_NAMEEQ,
3157  scan = systable_beginscan(pg_database, DatabaseNameIndexId, true,
3158  NULL, 1, entry);
3159 
3160  dbtuple = systable_getnext(scan);
3161 
3162  /* We assume that there can be at most one matching tuple */
3163  if (HeapTupleIsValid(dbtuple))
3164  oid = ((Form_pg_database) GETSTRUCT(dbtuple))->oid;
3165  else
3166  oid = InvalidOid;
3167 
3168  systable_endscan(scan);
3169  table_close(pg_database, AccessShareLock);
3170 
3171  if (!OidIsValid(oid) && !missing_ok)
3172  ereport(ERROR,
3173  (errcode(ERRCODE_UNDEFINED_DATABASE),
3174  errmsg("database \"%s\" does not exist",
3175  dbname)));
3176 
3177  return oid;
3178 }

References AccessShareLock, BTEqualStrategyNumber, CStringGetDatum(), dbname, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, InvalidOid, OidIsValid, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by AlterDatabaseSet(), AlterRoleSet(), CommentObject(), convert_database_name(), createdb(), get_object_address_unqualified(), pg_database_size_name(), RenameDatabase(), sepgsql_database_post_create(), synchronize_slots(), and worker_spi_launch().

◆ have_createdb_privilege()

bool have_createdb_privilege ( void  )

Definition at line 2952 of file dbcommands.c.

2953 {
2954  bool result = false;
2955  HeapTuple utup;
2956 
2957  /* Superusers can always do everything */
2958  if (superuser())
2959  return true;
2960 
2961  utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(GetUserId()));
2962  if (HeapTupleIsValid(utup))
2963  {
2964  result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreatedb;
2965  ReleaseSysCache(utup);
2966  }
2967  return result;
2968 }
FormData_pg_authid * Form_pg_authid
Definition: pg_authid.h:56
bool rolcreatedb
Definition: pg_authid.h:38

References GETSTRUCT, GetUserId(), HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), rolcreatedb, SearchSysCache1(), and superuser().

Referenced by AlterDatabaseOwner(), AlterRole(), createdb(), CreateRole(), and RenameDatabase().

◆ RenameDatabase()

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

Definition at line 1876 of file dbcommands.c.

1877 {
1878  Oid db_id;
1879  HeapTuple newtup;
1880  ItemPointerData otid;
1881  Relation rel;
1882  int notherbackends;
1883  int npreparedxacts;
1884  ObjectAddress address;
1885 
1886  /*
1887  * Look up the target database's OID, and get exclusive lock on it. We
1888  * need this for the same reasons as DROP DATABASE.
1889  */
1890  rel = table_open(DatabaseRelationId, RowExclusiveLock);
1891 
1892  if (!get_db_info(oldname, AccessExclusiveLock, &db_id, NULL, NULL, NULL,
1893  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
1894  ereport(ERROR,
1895  (errcode(ERRCODE_UNDEFINED_DATABASE),
1896  errmsg("database \"%s\" does not exist", oldname)));
1897 
1898  /* must be owner */
1899  if (!object_ownercheck(DatabaseRelationId, db_id, GetUserId()))
1901  oldname);
1902 
1903  /* must have createdb rights */
1904  if (!have_createdb_privilege())
1905  ereport(ERROR,
1906  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1907  errmsg("permission denied to rename database")));
1908 
1909  /*
1910  * If built with appropriate switch, whine when regression-testing
1911  * conventions for database names are violated.
1912  */
1913 #ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
1914  if (strstr(newname, "regression") == NULL)
1915  elog(WARNING, "databases created by regression test cases should have names including \"regression\"");
1916 #endif
1917 
1918  /*
1919  * Make sure the new name doesn't exist. See notes for same error in
1920  * CREATE DATABASE.
1921  */
1922  if (OidIsValid(get_database_oid(newname, true)))
1923  ereport(ERROR,
1924  (errcode(ERRCODE_DUPLICATE_DATABASE),
1925  errmsg("database \"%s\" already exists", newname)));
1926 
1927  /*
1928  * XXX Client applications probably store the current database somewhere,
1929  * so renaming it could cause confusion. On the other hand, there may not
1930  * be an actual problem besides a little confusion, so think about this
1931  * and decide.
1932  */
1933  if (db_id == MyDatabaseId)
1934  ereport(ERROR,
1935  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1936  errmsg("current database cannot be renamed")));
1937 
1938  /*
1939  * Make sure the database does not have active sessions. This is the same
1940  * concern as above, but applied to other sessions.
1941  *
1942  * As in CREATE DATABASE, check this after other error conditions.
1943  */
1944  if (CountOtherDBBackends(db_id, &notherbackends, &npreparedxacts))
1945  ereport(ERROR,
1946  (errcode(ERRCODE_OBJECT_IN_USE),
1947  errmsg("database \"%s\" is being accessed by other users",
1948  oldname),
1949  errdetail_busy_db(notherbackends, npreparedxacts)));
1950 
1951  /* rename */
1952  newtup = SearchSysCacheLockedCopy1(DATABASEOID, ObjectIdGetDatum(db_id));
1953  if (!HeapTupleIsValid(newtup))
1954  elog(ERROR, "cache lookup failed for database %u", db_id);
1955  otid = newtup->t_self;
1956  namestrcpy(&(((Form_pg_database) GETSTRUCT(newtup))->datname), newname);
1957  CatalogTupleUpdate(rel, &otid, newtup);
1958  UnlockTuple(rel, &otid, InplaceUpdateTupleLock);
1959 
1960  InvokeObjectPostAlterHook(DatabaseRelationId, db_id, 0);
1961 
1962  ObjectAddressSet(address, DatabaseRelationId, db_id);
1963 
1964  /*
1965  * Close pg_database, but keep lock till commit.
1966  */
1967  table_close(rel, NoLock);
1968 
1969  return address;
1970 }
void namestrcpy(Name name, const char *str)
Definition: name.c:233
HeapTuple SearchSysCacheLockedCopy1(int cacheId, Datum key1)
Definition: syscache.c:404

References AccessExclusiveLock, aclcheck_error(), ACLCHECK_NOT_OWNER, CatalogTupleUpdate(), CountOtherDBBackends(), datname, elog, ereport, errcode(), errdetail_busy_db(), errmsg(), ERROR, get_database_oid(), get_db_info(), GETSTRUCT, GetUserId(), have_createdb_privilege(), HeapTupleIsValid, InplaceUpdateTupleLock, InvokeObjectPostAlterHook, MyDatabaseId, namestrcpy(), NoLock, OBJECT_DATABASE, object_ownercheck(), ObjectAddressSet, ObjectIdGetDatum(), OidIsValid, RowExclusiveLock, SearchSysCacheLockedCopy1(), HeapTupleData::t_self, table_close(), table_open(), UnlockTuple(), and WARNING.

Referenced by ExecRenameStmt().