Adds additional alter database propagation support (#7253)

DESCRIPTION: Adds database connection limit, rename and set tablespace
propagation
In this PR, below statement propagations are added

alter database <database_name> with allow_connections = <boolean_value>;
alter database <database_name> rename to <database_name2>;
alter database <database_name> set TABLESPACE <table_space_name>

---------

Co-authored-by: Jelte Fennema-Nio <github-tech@jeltef.nl>
Co-authored-by: Jelte Fennema-Nio <jelte.fennema@microsoft.com>
Co-authored-by: Onur Tirtir <onurcantirtir@gmail.com>
testassert
Gürkan İndibay 2023-12-26 14:55:04 +03:00 committed by GitHub
parent b877d606c7
commit 181b8ab6d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 324 additions and 88 deletions

View File

@ -192,6 +192,25 @@ PreprocessGrantOnDatabaseStmt(Node *node, const char *queryString,
} }
/*
* IsSetTablespaceStatement returns true if the statement is a SET TABLESPACE statement,
* false otherwise.
*/
static bool
IsSetTablespaceStatement(AlterDatabaseStmt *stmt)
{
DefElem *def = NULL;
foreach_ptr(def, stmt->options)
{
if (strcmp(def->defname, "tablespace") == 0)
{
return true;
}
}
return false;
}
/* /*
* PreprocessAlterDatabaseStmt is executed before the statement is applied to the local * PreprocessAlterDatabaseStmt is executed before the statement is applied to the local
* postgres instance. * postgres instance.
@ -203,22 +222,38 @@ List *
PreprocessAlterDatabaseStmt(Node *node, const char *queryString, PreprocessAlterDatabaseStmt(Node *node, const char *queryString,
ProcessUtilityContext processUtilityContext) ProcessUtilityContext processUtilityContext)
{ {
if (!ShouldPropagate()) bool missingOk = false;
AlterDatabaseStmt *stmt = castNode(AlterDatabaseStmt, node);
ObjectAddress *dbAddress = GetDatabaseAddressFromDatabaseName(stmt->dbname,
missingOk);
if (!ShouldPropagate() || !IsAnyObjectDistributed(list_make1(dbAddress)))
{ {
return NIL; return NIL;
} }
AlterDatabaseStmt *stmt = castNode(AlterDatabaseStmt, node);
EnsureCoordinator(); EnsureCoordinator();
char *sql = DeparseTreeNode((Node *) stmt); char *sql = DeparseTreeNode((Node *) stmt);
List *commands = list_make3(DISABLE_DDL_PROPAGATION, List *commands = list_make3(DISABLE_DDL_PROPAGATION,
(void *) sql, sql,
ENABLE_DDL_PROPAGATION); ENABLE_DDL_PROPAGATION);
if (IsSetTablespaceStatement(stmt))
{
/*
* Set tablespace does not work inside a transaction.Therefore, we need to use
* NontransactionalNodeDDLTask to run the command on the workers outside
* the transaction block.
*/
return NontransactionalNodeDDLTaskList(NON_COORDINATOR_NODES, commands);
}
else
{
return NodeDDLTaskList(NON_COORDINATOR_NODES, commands); return NodeDDLTaskList(NON_COORDINATOR_NODES, commands);
}
} }
@ -256,6 +291,36 @@ PreprocessAlterDatabaseRefreshCollStmt(Node *node, const char *queryString,
#endif #endif
/*
* PreprocessAlterDatabaseRenameStmt is executed before the statement is applied to the local
* postgres instance. In this stage we prepare ALTER DATABASE RENAME statement to be run on
* all workers.
*/
List *
PostprocessAlterDatabaseRenameStmt(Node *node, const char *queryString)
{
bool missingOk = false;
RenameStmt *stmt = castNode(RenameStmt, node);
ObjectAddress *dbAddress = GetDatabaseAddressFromDatabaseName(stmt->newname,
missingOk);
if (!ShouldPropagate() || !IsAnyObjectDistributed(list_make1(dbAddress)))
{
return NIL;
}
EnsureCoordinator();
char *sql = DeparseTreeNode((Node *) stmt);
List *commands = list_make3(DISABLE_DDL_PROPAGATION,
(void *) sql,
ENABLE_DDL_PROPAGATION);
return NodeDDLTaskList(NON_COORDINATOR_NODES, commands);
}
/* /*
* PreprocessAlterDatabaseSetStmt is executed before the statement is applied to the local * PreprocessAlterDatabaseSetStmt is executed before the statement is applied to the local
* postgres instance. * postgres instance.

View File

@ -522,6 +522,16 @@ static DistributeObjectOps Database_Set = {
.markDistributed = false, .markDistributed = false,
}; };
static DistributeObjectOps Database_Rename = {
.deparse = DeparseAlterDatabaseRenameStmt,
.qualify = NULL,
.preprocess = NULL,
.postprocess = PostprocessAlterDatabaseRenameStmt,
.objectType = OBJECT_DATABASE,
.operationType = DIST_OPS_ALTER,
.address = NULL,
.markDistributed = false,
};
static DistributeObjectOps Domain_Alter = { static DistributeObjectOps Domain_Alter = {
.deparse = DeparseAlterDomainStmt, .deparse = DeparseAlterDomainStmt,
@ -2087,6 +2097,11 @@ GetDistributeObjectOps(Node *node)
return &Collation_Rename; return &Collation_Rename;
} }
case OBJECT_DATABASE:
{
return &Database_Rename;
}
case OBJECT_DOMAIN: case OBJECT_DOMAIN:
{ {
return &Domain_Rename; return &Domain_Rename;

View File

@ -30,12 +30,14 @@
static void AppendAlterDatabaseOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt); static void AppendAlterDatabaseOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt);
static void AppendAlterDatabaseSetStmt(StringInfo buf, AlterDatabaseSetStmt *stmt); static void AppendAlterDatabaseSetStmt(StringInfo buf, AlterDatabaseSetStmt *stmt);
static void AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt); static void AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt);
static void AppendDefElemConnLimit(StringInfo buf, DefElem *def);
static void AppendCreateDatabaseStmt(StringInfo buf, CreatedbStmt *stmt); static void AppendCreateDatabaseStmt(StringInfo buf, CreatedbStmt *stmt);
static void AppendDropDatabaseStmt(StringInfo buf, DropdbStmt *stmt); static void AppendDropDatabaseStmt(StringInfo buf, DropdbStmt *stmt);
static void AppendGrantOnDatabaseStmt(StringInfo buf, GrantStmt *stmt); static void AppendGrantOnDatabaseStmt(StringInfo buf, GrantStmt *stmt);
static void AppendBasicAlterDatabaseOptions(StringInfo buf, AlterDatabaseStmt *stmt);
static void AppendGrantDatabases(StringInfo buf, GrantStmt *stmt);
static void AppendAlterDatabaseSetTablespace(StringInfo buf, DefElem *def, char *dbname);
const DefElemOptionFormat create_database_option_formats[] = { const DefElemOptionFormat createDatabaseOptionFormats[] = {
{ "owner", " OWNER %s", OPTION_FORMAT_STRING }, { "owner", " OWNER %s", OPTION_FORMAT_STRING },
{ "template", " TEMPLATE %s", OPTION_FORMAT_STRING }, { "template", " TEMPLATE %s", OPTION_FORMAT_STRING },
{ "encoding", " ENCODING %s", OPTION_FORMAT_LITERAL_CSTR }, { "encoding", " ENCODING %s", OPTION_FORMAT_LITERAL_CSTR },
@ -53,6 +55,14 @@ const DefElemOptionFormat create_database_option_formats[] = {
{ "is_template", " IS_TEMPLATE %s", OPTION_FORMAT_BOOLEAN } { "is_template", " IS_TEMPLATE %s", OPTION_FORMAT_BOOLEAN }
}; };
const DefElemOptionFormat alterDatabaseOptionFormats[] = {
{ "is_template", " IS_TEMPLATE %s", OPTION_FORMAT_BOOLEAN },
{ "allow_connections", " ALLOW_CONNECTIONS %s", OPTION_FORMAT_BOOLEAN },
{ "connection_limit", " CONNECTION LIMIT %d", OPTION_FORMAT_INTEGER },
};
char * char *
DeparseAlterDatabaseOwnerStmt(Node *node) DeparseAlterDatabaseOwnerStmt(Node *node)
{ {
@ -112,48 +122,63 @@ AppendGrantOnDatabaseStmt(StringInfo buf, GrantStmt *stmt)
static void static void
AppendDefElemConnLimit(StringInfo buf, DefElem *def) AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt)
{ {
appendStringInfo(buf, " CONNECTION LIMIT %ld", (long int) defGetNumeric(def)); if (list_length(stmt->options) == 0)
{
elog(ERROR, "got unexpected number of options for ALTER DATABASE");
}
if (stmt->options)
{
DefElem *firstOption = linitial(stmt->options);
if (strcmp(firstOption->defname, "tablespace") == 0)
{
AppendAlterDatabaseSetTablespace(buf, firstOption, stmt->dbname);
/* SET tablespace cannot be combined with other options */
return;
}
appendStringInfo(buf, "ALTER DATABASE %s WITH",
quote_identifier(stmt->dbname));
AppendBasicAlterDatabaseOptions(buf, stmt);
}
appendStringInfo(buf, ";");
} }
static void static void
AppendAlterDatabaseStmt(StringInfo buf, AlterDatabaseStmt *stmt) AppendAlterDatabaseSetTablespace(StringInfo buf, DefElem *def, char *dbname)
{ {
appendStringInfo(buf, "ALTER DATABASE %s ", quote_identifier(stmt->dbname)); appendStringInfo(buf,
"ALTER DATABASE %s SET TABLESPACE %s",
quote_identifier(dbname), quote_identifier(defGetString(def)));
}
if (stmt->options)
{
ListCell *cell = NULL;
appendStringInfo(buf, "WITH ");
foreach(cell, stmt->options)
{
DefElem *def = castNode(DefElem, lfirst(cell));
if (strcmp(def->defname, "is_template") == 0)
{
appendStringInfo(buf, "IS_TEMPLATE %s",
quote_literal_cstr(strVal(def->arg)));
}
else if (strcmp(def->defname, "connection_limit") == 0)
{
AppendDefElemConnLimit(buf, def);
}
else if (strcmp(def->defname, "allow_connections") == 0)
{
ereport(ERROR,
errmsg("ALLOW_CONNECTIONS is not supported"));
}
else
{
ereport(ERROR,
errmsg("unrecognized ALTER DATABASE option: %s",
def->defname));
}
}
}
appendStringInfo(buf, ";"); /*
* AppendBasicAlterDatabaseOptions appends basic ALTER DATABASE options to a string buffer.
* Basic options are those that can be appended to the ALTER DATABASE statement
* after the "WITH" keyword.(i.e. ALLOW_CONNECTIONS, CONNECTION LIMIT, IS_TEMPLATE)
* For example, the tablespace option is not a basic option since it is defined via SET keyword.
*
* This function takes a string buffer and an AlterDatabaseStmt as input.
* It appends the basic options to the string buffer.
*
*/
static void
AppendBasicAlterDatabaseOptions(StringInfo buf, AlterDatabaseStmt *stmt)
{
DefElem *def = NULL;
foreach_ptr(def, stmt->options)
{
DefElemOptionToStatement(buf, def, alterDatabaseOptionFormats, lengthof(
alterDatabaseOptionFormats));
}
} }
@ -216,6 +241,22 @@ AppendAlterDatabaseSetStmt(StringInfo buf, AlterDatabaseSetStmt *stmt)
} }
char *
DeparseAlterDatabaseRenameStmt(Node *node)
{
RenameStmt *stmt = (RenameStmt *) node;
StringInfoData str;
initStringInfo(&str);
appendStringInfo(&str, "ALTER DATABASE %s RENAME TO %s",
quote_identifier(stmt->subname),
quote_identifier(stmt->newname));
return str.data;
}
char * char *
DeparseAlterDatabaseSetStmt(Node *node) DeparseAlterDatabaseSetStmt(Node *node)
{ {
@ -246,8 +287,8 @@ AppendCreateDatabaseStmt(StringInfo buf, CreatedbStmt *stmt)
DefElem *option = NULL; DefElem *option = NULL;
foreach_ptr(option, stmt->options) foreach_ptr(option, stmt->options)
{ {
DefElemOptionToStatement(buf, option, create_database_option_formats, DefElemOptionToStatement(buf, option, createDatabaseOptionFormats,
lengthof(create_database_option_formats)); lengthof(createDatabaseOptionFormats));
} }
} }

View File

@ -244,6 +244,8 @@ extern List * DropDatabaseStmtObjectAddress(Node *node, bool missingOk,
bool isPostprocess); bool isPostprocess);
extern List * CreateDatabaseStmtObjectAddress(Node *node, bool missingOk, extern List * CreateDatabaseStmtObjectAddress(Node *node, bool missingOk,
bool isPostprocess); bool isPostprocess);
extern List * GenerateGrantDatabaseCommandList(void);
extern List * PostprocessAlterDatabaseRenameStmt(Node *node, const char *queryString);
extern void EnsureSupportedCreateDatabaseCommand(CreatedbStmt *stmt); extern void EnsureSupportedCreateDatabaseCommand(CreatedbStmt *stmt);
extern char * CreateDatabaseDDLCommand(Oid dbId); extern char * CreateDatabaseDDLCommand(Oid dbId);

View File

@ -251,6 +251,7 @@ extern char * DeparseAlterDatabaseRefreshCollStmt(Node *node);
extern char * DeparseAlterDatabaseSetStmt(Node *node); extern char * DeparseAlterDatabaseSetStmt(Node *node);
extern char * DeparseCreateDatabaseStmt(Node *node); extern char * DeparseCreateDatabaseStmt(Node *node);
extern char * DeparseDropDatabaseStmt(Node *node); extern char * DeparseDropDatabaseStmt(Node *node);
extern char * DeparseAlterDatabaseRenameStmt(Node *node);
/* forward declaration for deparse_publication_stmts.c */ /* forward declaration for deparse_publication_stmts.c */

View File

@ -1,19 +1,14 @@
set citus.log_remote_commands = true; set citus.log_remote_commands = true;
set citus.grep_remote_commands = '%ALTER DATABASE%'; set citus.grep_remote_commands = '%ALTER DATABASE%';
-- since ALLOW_CONNECTIONS alter option should be executed in a different database
-- and since we don't have a multiple database support for now,
-- this statement will get error
alter database regression ALLOW_CONNECTIONS false;
ERROR: ALLOW_CONNECTIONS is not supported
alter database regression with CONNECTION LIMIT 100; alter database regression with CONNECTION LIMIT 100;
NOTICE: issuing ALTER DATABASE regression WITH CONNECTION LIMIT 100; NOTICE: issuing ALTER DATABASE regression WITH CONNECTION LIMIT 100;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing ALTER DATABASE regression WITH CONNECTION LIMIT 100; NOTICE: issuing ALTER DATABASE regression WITH CONNECTION LIMIT 100;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
alter database regression with IS_TEMPLATE true CONNECTION LIMIT 50; alter database regression with IS_TEMPLATE true CONNECTION LIMIT 50;
NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE 'true' CONNECTION LIMIT 50; NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE true CONNECTION LIMIT 50;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE 'true' CONNECTION LIMIT 50; NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE true CONNECTION LIMIT 50;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
alter database regression with CONNECTION LIMIT -1; alter database regression with CONNECTION LIMIT -1;
NOTICE: issuing ALTER DATABASE regression WITH CONNECTION LIMIT -1; NOTICE: issuing ALTER DATABASE regression WITH CONNECTION LIMIT -1;
@ -21,18 +16,15 @@ DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing ALTER DATABASE regression WITH CONNECTION LIMIT -1; NOTICE: issuing ALTER DATABASE regression WITH CONNECTION LIMIT -1;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
alter database regression with IS_TEMPLATE true; alter database regression with IS_TEMPLATE true;
NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE 'true'; NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE true;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE 'true'; NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE true;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
alter database regression with IS_TEMPLATE false; alter database regression with IS_TEMPLATE false;
NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE 'false'; NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE false;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE 'false'; NOTICE: issuing ALTER DATABASE regression WITH IS_TEMPLATE false;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx 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
alter database regression set default_transaction_read_only = true; alter database regression set default_transaction_read_only = true;
NOTICE: issuing ALTER DATABASE regression SET default_transaction_read_only = 'true' NOTICE: issuing ALTER DATABASE regression SET default_transaction_read_only = 'true'
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
@ -147,4 +139,86 @@ NOTICE: issuing ALTER DATABASE regression RESET lock_timeout
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing ALTER DATABASE regression RESET lock_timeout NOTICE: issuing ALTER DATABASE regression RESET lock_timeout
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
set citus.enable_create_database_propagation=on;
create database "regression!'2";
alter database "regression!'2" with CONNECTION LIMIT 100;
NOTICE: issuing ALTER DATABASE "regression!'2" WITH CONNECTION LIMIT 100;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing ALTER DATABASE "regression!'2" WITH CONNECTION LIMIT 100;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
alter database "regression!'2" with IS_TEMPLATE true CONNECTION LIMIT 50;
NOTICE: issuing ALTER DATABASE "regression!'2" WITH IS_TEMPLATE true CONNECTION LIMIT 50;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing ALTER DATABASE "regression!'2" WITH IS_TEMPLATE true CONNECTION LIMIT 50;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
alter database "regression!'2" with IS_TEMPLATE false;
NOTICE: issuing ALTER DATABASE "regression!'2" WITH IS_TEMPLATE false;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing ALTER DATABASE "regression!'2" WITH IS_TEMPLATE false;
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
\set alter_db_tablespace :abs_srcdir '/tmp_check/ts3'
CREATE TABLESPACE alter_db_tablespace LOCATION :'alter_db_tablespace';
\c - - - :worker_1_port
\set alter_db_tablespace :abs_srcdir '/tmp_check/ts4'
CREATE TABLESPACE alter_db_tablespace LOCATION :'alter_db_tablespace';
\c - - - :worker_2_port
\set alter_db_tablespace :abs_srcdir '/tmp_check/ts5'
CREATE TABLESPACE alter_db_tablespace LOCATION :'alter_db_tablespace';
\c - - - :master_port
set citus.log_remote_commands = true;
set citus.grep_remote_commands = '%ALTER DATABASE%';
alter database "regression!'2" set TABLESPACE alter_db_tablespace;
NOTICE: issuing ALTER DATABASE "regression!'2" SET TABLESPACE alter_db_tablespace
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing ALTER DATABASE "regression!'2" SET TABLESPACE alter_db_tablespace
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
set citus.enable_create_database_propagation=on;
alter database "regression!'2" rename to regression3;
NOTICE: issuing ALTER DATABASE "regression!'2" RENAME TO regression3
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing ALTER DATABASE "regression!'2" RENAME TO regression3
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
-- check that the local database rename and alter comnmand is not propagated
set citus.enable_create_database_propagation=off;
CREATE database local_regression;
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 local_regression with CONNECTION LIMIT 100;
alter DATABASE local_regression rename to local_regression2;
drop database local_regression2;
set citus.enable_create_database_propagation=on;
drop database regression3;
create database "regression!'4";
SELECT result FROM run_command_on_all_nodes(
$$
ALTER TABLESPACE alter_db_tablespace RENAME TO "ts-needs\!escape"
$$
);
result
---------------------------------------------------------------------
ALTER TABLESPACE
ALTER TABLESPACE
ALTER TABLESPACE
(3 rows)
alter database "regression!'4" set TABLESPACE "ts-needs\!escape";
NOTICE: issuing ALTER DATABASE "regression!'4" SET TABLESPACE "ts-needs\!escape"
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing ALTER DATABASE "regression!'4" SET TABLESPACE "ts-needs\!escape"
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
drop database "regression!'4";
set citus.log_remote_commands = false; set citus.log_remote_commands = false;
set citus.enable_create_database_propagation=off;
SELECT result FROM run_command_on_all_nodes(
$$
drop tablespace "ts-needs\!escape"
$$
);
result
---------------------------------------------------------------------
DROP TABLESPACE
DROP TABLESPACE
DROP TABLESPACE
(3 rows)

View File

@ -209,19 +209,7 @@ SELECT result FROM run_command_on_all_nodes(
CREATE USER "role-needs\!escape"; CREATE USER "role-needs\!escape";
CREATE DATABASE "db-needs\!escape" owner "role-needs\!escape" tablespace "ts-needs\!escape"; CREATE DATABASE "db-needs\!escape" owner "role-needs\!escape" tablespace "ts-needs\!escape";
-- Rename it to make check_database_on_all_nodes happy. -- Rename it to make check_database_on_all_nodes happy.
-- Today we don't support ALTER DATABASE .. RENAME TO .., so need to propagate it manually. ALTER DATABASE "db-needs\!escape" RENAME TO db_needs_escape;
SELECT result FROM run_command_on_all_nodes(
$$
ALTER DATABASE "db-needs\!escape" RENAME TO db_needs_escape
$$
);
result
---------------------------------------------------------------------
ALTER DATABASE
ALTER DATABASE
ALTER DATABASE
(3 rows)
SELECT * FROM public.check_database_on_all_nodes('db_needs_escape') ORDER BY node_type; SELECT * FROM public.check_database_on_all_nodes('db_needs_escape') ORDER BY node_type;
node_type | result node_type | result
--------------------------------------------------------------------- ---------------------------------------------------------------------

View File

@ -1,20 +1,12 @@
set citus.log_remote_commands = true; set citus.log_remote_commands = true;
set citus.grep_remote_commands = '%ALTER DATABASE%'; set citus.grep_remote_commands = '%ALTER DATABASE%';
-- since ALLOW_CONNECTIONS alter option should be executed in a different database
-- and since we don't have a multiple database support for now,
-- this statement will get error
alter database regression ALLOW_CONNECTIONS false;
alter database regression with CONNECTION LIMIT 100; alter database regression with CONNECTION LIMIT 100;
alter database regression with IS_TEMPLATE true CONNECTION LIMIT 50; alter database regression with IS_TEMPLATE true CONNECTION LIMIT 50;
alter database regression with CONNECTION LIMIT -1; alter database regression with CONNECTION LIMIT -1;
alter database regression with IS_TEMPLATE true; alter database regression with IS_TEMPLATE true;
alter database regression with IS_TEMPLATE false; 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;
alter database regression set default_transaction_read_only = true; alter database regression set default_transaction_read_only = true;
@ -56,4 +48,66 @@ alter database regression set lock_timeout from current;
alter database regression set lock_timeout to DEFAULT; alter database regression set lock_timeout to DEFAULT;
alter database regression RESET lock_timeout; alter database regression RESET lock_timeout;
set citus.enable_create_database_propagation=on;
create database "regression!'2";
alter database "regression!'2" with CONNECTION LIMIT 100;
alter database "regression!'2" with IS_TEMPLATE true CONNECTION LIMIT 50;
alter database "regression!'2" with IS_TEMPLATE false;
\set alter_db_tablespace :abs_srcdir '/tmp_check/ts3'
CREATE TABLESPACE alter_db_tablespace LOCATION :'alter_db_tablespace';
\c - - - :worker_1_port
\set alter_db_tablespace :abs_srcdir '/tmp_check/ts4'
CREATE TABLESPACE alter_db_tablespace LOCATION :'alter_db_tablespace';
\c - - - :worker_2_port
\set alter_db_tablespace :abs_srcdir '/tmp_check/ts5'
CREATE TABLESPACE alter_db_tablespace LOCATION :'alter_db_tablespace';
\c - - - :master_port
set citus.log_remote_commands = true;
set citus.grep_remote_commands = '%ALTER DATABASE%';
alter database "regression!'2" set TABLESPACE alter_db_tablespace;
set citus.enable_create_database_propagation=on;
alter database "regression!'2" rename to regression3;
-- check that the local database rename and alter comnmand is not propagated
set citus.enable_create_database_propagation=off;
CREATE database local_regression;
alter DATABASE local_regression with CONNECTION LIMIT 100;
alter DATABASE local_regression rename to local_regression2;
drop database local_regression2;
set citus.enable_create_database_propagation=on;
drop database regression3;
create database "regression!'4";
SELECT result FROM run_command_on_all_nodes(
$$
ALTER TABLESPACE alter_db_tablespace RENAME TO "ts-needs\!escape"
$$
);
alter database "regression!'4" set TABLESPACE "ts-needs\!escape";
drop database "regression!'4";
set citus.log_remote_commands = false; set citus.log_remote_commands = false;
set citus.enable_create_database_propagation=off;
SELECT result FROM run_command_on_all_nodes(
$$
drop tablespace "ts-needs\!escape"
$$
);

View File

@ -129,13 +129,8 @@ CREATE USER "role-needs\!escape";
CREATE DATABASE "db-needs\!escape" owner "role-needs\!escape" tablespace "ts-needs\!escape"; CREATE DATABASE "db-needs\!escape" owner "role-needs\!escape" tablespace "ts-needs\!escape";
-- Rename it to make check_database_on_all_nodes happy. -- Rename it to make check_database_on_all_nodes happy.
-- Today we don't support ALTER DATABASE .. RENAME TO .., so need to propagate it manually.
SELECT result FROM run_command_on_all_nodes(
$$
ALTER DATABASE "db-needs\!escape" RENAME TO db_needs_escape
$$
);
ALTER DATABASE "db-needs\!escape" RENAME TO db_needs_escape;
SELECT * FROM public.check_database_on_all_nodes('db_needs_escape') ORDER BY node_type; SELECT * FROM public.check_database_on_all_nodes('db_needs_escape') ORDER BY node_type;
-- test database syncing after node addition -- test database syncing after node addition
@ -541,6 +536,7 @@ REVOKE CONNECT ON DATABASE test_db FROM propagated_role;
DROP DATABASE test_db; DROP DATABASE test_db;
DROP ROLE propagated_role, non_propagated_role; DROP ROLE propagated_role, non_propagated_role;
--clean up resources created by this test --clean up resources created by this test
-- DROP TABLESPACE is not supported, so we need to drop it manually. -- DROP TABLESPACE is not supported, so we need to drop it manually.