diff --git a/internal/management/controller/common.go b/internal/management/controller/common.go index 0212ee2a70..c0d87aeb97 100644 --- a/internal/management/controller/common.go +++ b/internal/management/controller/common.go @@ -23,6 +23,7 @@ import ( "maps" "slices" + "github.com/jackc/pgx/v5" "github.com/lib/pq" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -95,13 +96,14 @@ func getClusterFromInstance( } func toPostgresParameters(parameters map[string]string) string { - keys := slices.Sorted(maps.Keys(parameters)) + if len(parameters) == 0 { + return "" + } b := new(bytes.Buffer) - for _, key := range keys { - // TODO(armru): should we sanitize the key? + for _, key := range slices.Sorted(maps.Keys(parameters)) { // TODO(armru): any alternative to pg.QuoteLiteral? - _, _ = fmt.Fprintf(b, "%s = %s, ", key, pq.QuoteLiteral(parameters[key])) + _, _ = fmt.Fprintf(b, "%s = %s, ", pgx.Identifier{key}.Sanitize(), pq.QuoteLiteral(parameters[key])) } // pruning last 2 chars `, ` diff --git a/internal/management/controller/publication_controller_sql_test.go b/internal/management/controller/publication_controller_sql_test.go index 1ede219832..ec1b2192f6 100644 --- a/internal/management/controller/publication_controller_sql_test.go +++ b/internal/management/controller/publication_controller_sql_test.go @@ -113,7 +113,7 @@ var _ = Describe("publication sql", func() { } sqls := toPublicationAlterSQL(obj) - Expect(sqls).To(ContainElement(`ALTER PUBLICATION "test_pub" SET (param1 = 'value1', param2 = 'value2')`)) + Expect(sqls).To(ContainElement(`ALTER PUBLICATION "test_pub" SET ("param1" = 'value1', "param2" = 'value2')`)) }) It("returns empty SQL list when no alterations are needed", func() { @@ -191,7 +191,7 @@ var _ = Describe("publication sql", func() { sqls := toPublicationCreateSQL(obj) Expect(sqls).To(ContainElement( - `CREATE PUBLICATION "test_pub" FOR TABLES IN SCHEMA "public" WITH (param1 = 'value1', param2 = 'value2')`, + `CREATE PUBLICATION "test_pub" FOR TABLES IN SCHEMA "public" WITH ("param1" = 'value1', "param2" = 'value2')`, )) }) }) diff --git a/internal/management/controller/subscription_controller_sql_test.go b/internal/management/controller/subscription_controller_sql_test.go index 0c1f663263..bd3bcd5049 100644 --- a/internal/management/controller/subscription_controller_sql_test.go +++ b/internal/management/controller/subscription_controller_sql_test.go @@ -102,7 +102,7 @@ var _ = Describe("subscription sql", func() { sqls := toSubscriptionCreateSQL(obj, connString) expectedElement := `CREATE SUBSCRIPTION "test_sub" ` + `CONNECTION 'host=localhost user=test dbname=test' ` + - `PUBLICATION "test_pub" WITH (param1 = 'value1', param2 = 'value2')` + `PUBLICATION "test_pub" WITH ("param1" = 'value1', "param2" = 'value2')` Expect(sqls).To(ContainElement(expectedElement)) }) @@ -182,7 +182,7 @@ var _ = Describe("subscription sql", func() { sqls := toSubscriptionAlterSQL(obj, connString) Expect(sqls).To(ContainElement(`ALTER SUBSCRIPTION "test_sub" SET PUBLICATION "test_pub"`)) Expect(sqls).To(ContainElement(`ALTER SUBSCRIPTION "test_sub" CONNECTION 'host=localhost user=test dbname=test'`)) - Expect(sqls).To(ContainElement(`ALTER SUBSCRIPTION "test_sub" SET (param1 = 'value1', param2 = 'value2')`)) + Expect(sqls).To(ContainElement(`ALTER SUBSCRIPTION "test_sub" SET ("param1" = 'value1', "param2" = 'value2')`)) }) It("returns correct SQL for altering subscription with no owner or parameters", func() { diff --git a/internal/management/controller/subscription_controller_test.go b/internal/management/controller/subscription_controller_test.go index c2d8b147bf..901ab93f61 100644 --- a/internal/management/controller/subscription_controller_test.go +++ b/internal/management/controller/subscription_controller_test.go @@ -27,6 +27,6 @@ var _ = Describe("Conversion of PG parameters from map to string of key/value pa "a": "1", "b": "2", } res := toPostgresParameters(m) - Expect(res).To(Equal(`a = '1', b = '2'`)) + Expect(res).To(Equal(`"a" = '1', "b" = '2'`)) }) })