Fix bug: alter database shouldn't propagate for undistributed database (#7777)

Before this fix, the following would happen for a database that is not
distributed:

```sql
CREATE DATABASE db_to_test;
NOTICE:  Citus partially supports CREATE DATABASE for distributed databases
DETAIL:  Citus does not propagate CREATE DATABASE command to workers
HINT:  You can manually create a database and its extensions on workers.

ALTER DATABASE db_to_test with CONNECTION LIMIT 100;
NOTICE:  issuing ALTER DATABASE db_to_test WITH  CONNECTION LIMIT 100;
DETAIL:  on server postgres@localhost:57638 connectionId: 2
NOTICE:  issuing ALTER DATABASE db_to_test WITH  CONNECTION LIMIT 100;
DETAIL:  on server postgres@localhost:57637 connectionId: 1
ERROR:  database "db_to_test" does not exist
```

With this fix, we also take care of
https://github.com/citusdata/citus/issues/7763

Fixes #7763
pull/7769/head
Naisila Puka 2024-12-05 13:47:51 +03:00 committed by GitHub
parent 30a75eadf1
commit 90d76e8097
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 3 deletions

View File

@ -24,6 +24,7 @@
#include "distributed/commands.h"
#include "distributed/commands/utility_hook.h"
#include "distributed/deparser.h"
#include "distributed/metadata/distobject.h"
#include "distributed/metadata_sync.h"
#include "distributed/metadata_utility.h"
#include "distributed/multi_executor.h"
@ -32,6 +33,8 @@
static AlterOwnerStmt * RecreateAlterDatabaseOwnerStmt(Oid databaseOid);
static Oid get_database_owner(Oid db_oid);
static ObjectAddress * GetDatabaseAddressFromDatabaseName(char *databaseName,
bool missingOk);
List * PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext);
@ -161,13 +164,15 @@ List *
PreprocessAlterDatabaseStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext)
{
if (!ShouldPropagate())
AlterDatabaseStmt *stmt = castNode(AlterDatabaseStmt, node);
bool missingOk = false;
ObjectAddress *dbAddress = GetDatabaseAddressFromDatabaseName(stmt->dbname,
missingOk);
if (!ShouldPropagate() || !IsAnyObjectDistributed(list_make1(dbAddress)))
{
return NIL;
}
AlterDatabaseStmt *stmt = castNode(AlterDatabaseStmt, node);
EnsureCoordinator();
char *sql = DeparseTreeNode((Node *) stmt);
@ -213,3 +218,17 @@ PreprocessAlterDatabaseRefreshCollStmt(Node *node, const char *queryString,
#endif
/*
* GetDatabaseAddressFromDatabaseName gets the database name and returns the ObjectAddress
* of the database.
*/
static ObjectAddress *
GetDatabaseAddressFromDatabaseName(char *databaseName, bool missingOk)
{
Oid databaseOid = get_database_oid(databaseName, missingOk);
ObjectAddress *dbObjectAddress = palloc0(sizeof(ObjectAddress));
ObjectAddressSet(*dbObjectAddress, DatabaseRelationId, databaseOid);
return dbObjectAddress;
}

View File

@ -33,4 +33,11 @@ DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
-- this statement will get error since we don't have a multiple database support for now
alter database regression rename to regression2;
ERROR: current database cannot be renamed
-- this database is not distributed so we will not see any remote commands
CREATE DATABASE db_to_test;
NOTICE: Citus partially supports CREATE DATABASE for distributed databases
DETAIL: Citus does not propagate CREATE DATABASE command to workers
HINT: You can manually create a database and its extensions on workers.
alter database db_to_test with CONNECTION LIMIT 100;
DROP DATABASE db_to_test;
set citus.log_remote_commands = false;

View File

@ -15,4 +15,9 @@ alter database regression with IS_TEMPLATE false;
-- this statement will get error since we don't have a multiple database support for now
alter database regression rename to regression2;
-- this database is not distributed so we will not see any remote commands
CREATE DATABASE db_to_test;
alter database db_to_test with CONNECTION LIMIT 100;
DROP DATABASE db_to_test;
set citus.log_remote_commands = false;