Escape extension name in extension command propagation (#3218)

pull/3224/head
Onur TIRTIR 2019-11-24 12:16:10 +03:00 committed by GitHub
parent 99164398bf
commit bef32624c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 91 additions and 7 deletions

View File

@ -85,10 +85,11 @@ DeparseCreateExtensionStmt(CreateExtensionStmt *createExtensionStmt)
static void static void
AppendCreateExtensionStmt(StringInfo buf, CreateExtensionStmt *createExtensionStmt) AppendCreateExtensionStmt(StringInfo buf, CreateExtensionStmt *createExtensionStmt)
{ {
const char *extensionName = createExtensionStmt->extname;
List *optionsList = createExtensionStmt->options; List *optionsList = createExtensionStmt->options;
const char *extensionName = createExtensionStmt->extname;
extensionName = quote_identifier(extensionName);
/* /*
* We fetch "new_version", "schema" and "cascade" options from * We fetch "new_version", "schema" and "cascade" options from
* optionList as we will append "IF NOT EXISTS" clause regardless of * optionList as we will append "IF NOT EXISTS" clause regardless of
@ -157,10 +158,11 @@ DeparseAlterExtensionStmt(AlterExtensionStmt *alterExtensionStmt)
static void static void
AppendAlterExtensionStmt(StringInfo buf, AlterExtensionStmt *alterExtensionStmt) AppendAlterExtensionStmt(StringInfo buf, AlterExtensionStmt *alterExtensionStmt)
{ {
const char *extensionName = alterExtensionStmt->extname;
List *optionsList = alterExtensionStmt->options; List *optionsList = alterExtensionStmt->options;
const char *extensionName = alterExtensionStmt->extname;
extensionName = quote_identifier(extensionName);
Value *newVersionValue = GetExtensionOption(optionsList, "new_version"); Value *newVersionValue = GetExtensionOption(optionsList, "new_version");
appendStringInfo(buf, "ALTER EXTENSION %s UPDATE ", extensionName); appendStringInfo(buf, "ALTER EXTENSION %s UPDATE ", extensionName);
@ -233,6 +235,7 @@ AppendExtensionNameList(StringInfo str, List *objects)
foreach(objectCell, objects) foreach(objectCell, objects)
{ {
const char *extensionName = strVal(lfirst(objectCell)); const char *extensionName = strVal(lfirst(objectCell));
extensionName = quote_identifier(extensionName);
if (objectCell != list_head(objects)) if (objectCell != list_head(objects))
{ {
@ -273,6 +276,11 @@ AppendAlterExtensionSchemaStmt(StringInfo buf,
Assert(alterExtensionSchemaStmt->objectType == OBJECT_EXTENSION); Assert(alterExtensionSchemaStmt->objectType == OBJECT_EXTENSION);
const char *extensionName = strVal(alterExtensionSchemaStmt->object); 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, appendStringInfo(buf, "ALTER EXTENSION %s SET SCHEMA %s;", extensionName,
quote_identifier(alterExtensionSchemaStmt->newschema)); newSchemaName);
} }

View File

@ -183,7 +183,7 @@ SELECT create_reference_table('ref_table_2');
(1 row) (1 row)
-- and add the other node -- 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 NOTICE: Replicating reference table "ref_table_2" to the node localhost:57638
?column? ?column?
---------- ----------
@ -385,6 +385,54 @@ SELECT run_command_on_workers($$SELECT count(*) FROM pg_extension WHERE extname
(localhost,57638,t,2) (localhost,57638,t,2)
(2 rows) (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 -- drop the schema and all the objects
SET client_min_messages TO WARNING; SET client_min_messages TO WARNING;
DROP SCHEMA "extension'test" CASCADE; DROP SCHEMA "extension'test" CASCADE;

View File

@ -111,7 +111,7 @@ CREATE TABLE ref_table_2 (x seg);
SELECT create_reference_table('ref_table_2'); SELECT create_reference_table('ref_table_2');
-- and add the other node -- 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 -- 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'$$); 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 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')$$); 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 -- drop the schema and all the objects
SET client_min_messages TO WARNING; SET client_min_messages TO WARNING;
DROP SCHEMA "extension'test" CASCADE; DROP SCHEMA "extension'test" CASCADE;