diff --git a/src/backend/distributed/deparser/deparse_extension_stmts.c b/src/backend/distributed/deparser/deparse_extension_stmts.c index dc19f753d..c25b6395e 100644 --- a/src/backend/distributed/deparser/deparse_extension_stmts.c +++ b/src/backend/distributed/deparser/deparse_extension_stmts.c @@ -85,10 +85,11 @@ DeparseCreateExtensionStmt(CreateExtensionStmt *createExtensionStmt) static void AppendCreateExtensionStmt(StringInfo buf, CreateExtensionStmt *createExtensionStmt) { - const char *extensionName = createExtensionStmt->extname; - List *optionsList = createExtensionStmt->options; + const char *extensionName = createExtensionStmt->extname; + extensionName = quote_identifier(extensionName); + /* * We fetch "new_version", "schema" and "cascade" options from * optionList as we will append "IF NOT EXISTS" clause regardless of @@ -157,10 +158,11 @@ DeparseAlterExtensionStmt(AlterExtensionStmt *alterExtensionStmt) static void AppendAlterExtensionStmt(StringInfo buf, AlterExtensionStmt *alterExtensionStmt) { - const char *extensionName = alterExtensionStmt->extname; - List *optionsList = alterExtensionStmt->options; + const char *extensionName = alterExtensionStmt->extname; + extensionName = quote_identifier(extensionName); + Value *newVersionValue = GetExtensionOption(optionsList, "new_version"); appendStringInfo(buf, "ALTER EXTENSION %s UPDATE ", extensionName); @@ -233,6 +235,7 @@ AppendExtensionNameList(StringInfo str, List *objects) foreach(objectCell, objects) { const char *extensionName = strVal(lfirst(objectCell)); + extensionName = quote_identifier(extensionName); if (objectCell != list_head(objects)) { @@ -273,6 +276,11 @@ AppendAlterExtensionSchemaStmt(StringInfo buf, Assert(alterExtensionSchemaStmt->objectType == OBJECT_EXTENSION); const char *extensionName = strVal(alterExtensionSchemaStmt->object); + const char *newSchemaName = alterExtensionSchemaStmt->newschema; + + extensionName = quote_identifier(extensionName); + newSchemaName = quote_identifier(newSchemaName); + appendStringInfo(buf, "ALTER EXTENSION %s SET SCHEMA %s;", extensionName, - quote_identifier(alterExtensionSchemaStmt->newschema)); + newSchemaName); } diff --git a/src/test/regress/expected/propagate_extension_commands.out b/src/test/regress/expected/propagate_extension_commands.out index a5c1efaba..86c7799f5 100644 --- a/src/test/regress/expected/propagate_extension_commands.out +++ b/src/test/regress/expected/propagate_extension_commands.out @@ -183,7 +183,7 @@ SELECT create_reference_table('ref_table_2'); (1 row) -- and add the other node -SELECT 1 from master_add_node('localhost', 57638); +SELECT 1 from master_add_node('localhost', :worker_2_port); NOTICE: Replicating reference table "ref_table_2" to the node localhost:57638 ?column? ---------- @@ -385,6 +385,54 @@ SELECT run_command_on_workers($$SELECT count(*) FROM pg_extension WHERE extname (localhost,57638,t,2) (2 rows) +-- test if citus can escape the extension name +CREATE EXTENSION "uuid-ossp"; +-- show that the extension is created on both nodes +SELECT run_command_on_workers($$SELECT count(*) FROM pg_extension WHERE extname = 'uuid-ossp'$$); + run_command_on_workers +------------------------ + (localhost,57637,t,1) + (localhost,57638,t,1) +(2 rows) + +SET client_min_messages TO WARNING; +DROP EXTENSION "uuid-ossp"; +RESET client_min_messages; +-- show that the extension is dropped from both nodes +SELECT run_command_on_workers($$SELECT count(*) FROM pg_extension WHERE extname = 'uuid-ossp'$$); + run_command_on_workers +------------------------ + (localhost,57637,t,0) + (localhost,57638,t,0) +(2 rows) + +-- show that extension recreation on new nodes works also fine with extension names that require escaping +SELECT 1 from master_remove_node('localhost', :worker_2_port); + ?column? +---------- + 1 +(1 row) + +CREATE EXTENSION "uuid-ossp"; +-- and add the other node +SELECT 1 from master_add_node('localhost', :worker_2_port); +NOTICE: Replicating reference table "t3" to the node localhost:57638 + ?column? +---------- + 1 +(1 row) + +-- show that the extension exists on both nodes +SELECT run_command_on_workers($$SELECT count(*) FROM pg_extension WHERE extname = 'uuid-ossp'$$); + run_command_on_workers +------------------------ + (localhost,57637,t,1) + (localhost,57638,t,1) +(2 rows) + +SET client_min_messages TO WARNING; +DROP EXTENSION "uuid-ossp"; +RESET client_min_messages; -- drop the schema and all the objects SET client_min_messages TO WARNING; DROP SCHEMA "extension'test" CASCADE; diff --git a/src/test/regress/sql/propagate_extension_commands.sql b/src/test/regress/sql/propagate_extension_commands.sql index c22ffb601..aa9293da8 100644 --- a/src/test/regress/sql/propagate_extension_commands.sql +++ b/src/test/regress/sql/propagate_extension_commands.sql @@ -111,7 +111,7 @@ CREATE TABLE ref_table_2 (x seg); SELECT create_reference_table('ref_table_2'); -- and add the other node -SELECT 1 from master_add_node('localhost', 57638); +SELECT 1 from master_add_node('localhost', :worker_2_port); -- show that the extension is created on both existing and new node SELECT run_command_on_workers($$SELECT count(extnamespace) FROM pg_extension WHERE extname = 'seg'$$); @@ -229,6 +229,34 @@ SELECT 1 from master_add_node('localhost', :worker_2_port); SELECT count(*) FROM citus.pg_dist_object WHERE objid IN (SELECT oid FROM pg_extension WHERE extname IN ('seg', 'isn')); SELECT run_command_on_workers($$SELECT count(*) FROM pg_extension WHERE extname IN ('seg', 'isn')$$); +-- test if citus can escape the extension name +CREATE EXTENSION "uuid-ossp"; + +-- show that the extension is created on both nodes +SELECT run_command_on_workers($$SELECT count(*) FROM pg_extension WHERE extname = 'uuid-ossp'$$); + +SET client_min_messages TO WARNING; +DROP EXTENSION "uuid-ossp"; +RESET client_min_messages; + +-- show that the extension is dropped from both nodes +SELECT run_command_on_workers($$SELECT count(*) FROM pg_extension WHERE extname = 'uuid-ossp'$$); + +-- show that extension recreation on new nodes works also fine with extension names that require escaping +SELECT 1 from master_remove_node('localhost', :worker_2_port); + +CREATE EXTENSION "uuid-ossp"; + +-- and add the other node +SELECT 1 from master_add_node('localhost', :worker_2_port); + +-- show that the extension exists on both nodes +SELECT run_command_on_workers($$SELECT count(*) FROM pg_extension WHERE extname = 'uuid-ossp'$$); + +SET client_min_messages TO WARNING; +DROP EXTENSION "uuid-ossp"; +RESET client_min_messages; + -- drop the schema and all the objects SET client_min_messages TO WARNING; DROP SCHEMA "extension'test" CASCADE;