From effe6a93c959129effdb03131a388180af0946d3 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Fri, 21 Dec 2018 23:08:01 +0200 Subject: [PATCH] Fix quoting when dispatching SAVEPOINT commands. Fixes github issue #6345. Reviewed-by: Daniel Gustafsson --- src/backend/access/transam/xact.c | 7 +++--- src/test/regress/expected/gpdtm_plpgsql.out | 25 +++++++++++++++++++++ src/test/regress/sql/gpdtm_plpgsql.sql | 18 +++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 2901b0ff20..19d4ff9b68 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -61,6 +61,7 @@ #include "utils/memutils.h" #include "utils/relmapper.h" +#include "utils/builtins.h" #include "utils/resource_manager.h" #include "utils/sharedsnapshot.h" #include "access/clog.h" @@ -4578,7 +4579,7 @@ DefineDispatchSavepoint(char *name) { char *cmd; - cmd = psprintf("SAVEPOINT %s", name); + cmd = psprintf("SAVEPOINT %s", quote_identifier(name)); /* * dispatch a DTX command, in the event of an error, this call @@ -4711,7 +4712,7 @@ ReleaseSavepoint(List *options) { char *cmd; - cmd = psprintf("RELEASE SAVEPOINT %s", name); + cmd = psprintf("RELEASE SAVEPOINT %s", quote_identifier(name)); /* * dispatch a DTX command, in the event of an error, this call will @@ -4878,7 +4879,7 @@ DispatchRollbackToSavepoint(char *name) if (!name) elog(ERROR, "could not find savepoint name for ROLLBACK TO SAVEPOINT"); - cmd = psprintf("ROLLBACK TO SAVEPOINT %s", name); + cmd = psprintf("ROLLBACK TO SAVEPOINT %s", quote_identifier(name)); /* * dispatch a DTX command, in the event of an error, this call will diff --git a/src/test/regress/expected/gpdtm_plpgsql.out b/src/test/regress/expected/gpdtm_plpgsql.out index 2e2aa1294d..84cec361a3 100644 --- a/src/test/regress/expected/gpdtm_plpgsql.out +++ b/src/test/regress/expected/gpdtm_plpgsql.out @@ -1013,3 +1013,28 @@ $$ language plpgsql; create table stran_tt as select stran_func(b) from stran_foo; NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'stran_func' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- +-- Check quoting when dispatching savepoints. (Not really PL/pgSQL related, +-- but here for lack of a better place.) +-- +BEGIN; +CREATE TEMPORARY TABLE savepointtest (t text); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 't' as the Greenplum Database data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +INSERT INTO savepointtest VALUES ('before savepoints'); +SAVEPOINT "evil""savepoint1"; +INSERT INTO savepointtest VALUES ('after sp 1'); +SAVEPOINT "evil""savepoint2"; +INSERT INTO savepointtest VALUES ('after sp 2'); +ROLLBACK TO SAVEPOINT "evil""savepoint2"; +RELEASE SAVEPOINT "evil""savepoint1"; +INSERT INTO savepointtest VALUES ('back to top transaction'); +COMMIT; +SELECT * FROM savepointtest; + t +------------------------- + before savepoints + after sp 1 + back to top transaction +(3 rows) + diff --git a/src/test/regress/sql/gpdtm_plpgsql.sql b/src/test/regress/sql/gpdtm_plpgsql.sql index 0b504fbbf1..e7bd10cb79 100644 --- a/src/test/regress/sql/gpdtm_plpgsql.sql +++ b/src/test/regress/sql/gpdtm_plpgsql.sql @@ -372,3 +372,21 @@ end; $$ language plpgsql; create table stran_tt as select stran_func(b) from stran_foo; + + +-- +-- Check quoting when dispatching savepoints. (Not really PL/pgSQL related, +-- but here for lack of a better place.) +-- +BEGIN; +CREATE TEMPORARY TABLE savepointtest (t text); +INSERT INTO savepointtest VALUES ('before savepoints'); +SAVEPOINT "evil""savepoint1"; +INSERT INTO savepointtest VALUES ('after sp 1'); +SAVEPOINT "evil""savepoint2"; +INSERT INTO savepointtest VALUES ('after sp 2'); +ROLLBACK TO SAVEPOINT "evil""savepoint2"; +RELEASE SAVEPOINT "evil""savepoint1"; +INSERT INTO savepointtest VALUES ('back to top transaction'); +COMMIT; +SELECT * FROM savepointtest; -- GitLab