diff --git a/pkg/util/config/config_test.go b/pkg/util/config/config_test.go index f6e2c374c..d5d5730c5 100644 --- a/pkg/util/config/config_test.go +++ b/pkg/util/config/config_test.go @@ -1,13 +1,13 @@ package config import ( - "testing" - "reflect" "fmt" + "reflect" + "testing" ) var getMapPairsFromStringTest = []struct { - in string + in string expected []string err error }{ @@ -15,7 +15,7 @@ var getMapPairsFromStringTest = []struct { {`log_statement:none, search_path:'"$user", public'`, []string{"log_statement:none", `search_path:'"$user", public'`}, nil}, {`search_path:'"$user"`, nil, fmt.Errorf("unclosed quote starting at position 13")}, {"", []string{""}, nil}, - {",,log_statement:all ,", []string{"","","log_statement:all", ""}, nil}, + {",,log_statement:all ,", []string{"", "", "log_statement:all", ""}, nil}, } func TestGetMapPairsFromString(t *testing.T) { @@ -29,4 +29,3 @@ func TestGetMapPairsFromString(t *testing.T) { } } } - diff --git a/pkg/util/config/util.go b/pkg/util/config/util.go index e07001381..05a956c3e 100644 --- a/pkg/util/config/util.go +++ b/pkg/util/config/util.go @@ -169,10 +169,10 @@ func processField(value string, field reflect.Value) error { return nil } - type parserState int + const ( - Plain parserState = iota + Plain parserState = iota DoubleQuoted SingleQuoted ) @@ -180,12 +180,12 @@ const ( // Split the pair candidates by commas not located inside open quotes // Escape characters are not supported for simplicity, as we don't // expect to find them inside the map values for our use cases -func getMapPairsFromString(value string) (pairs []string , err error) { +func getMapPairsFromString(value string) (pairs []string, err error) { pairs = make([]string, 0) state := Plain var start, quote int - for i, ch := range(strings.Split(value, "")) { + for i, ch := range strings.Split(value, "") { if ch == `"` { if state == Plain { state = DoubleQuoted @@ -205,12 +205,12 @@ func getMapPairsFromString(value string) (pairs []string , err error) { } } if ch == "," && state == Plain { - pairs = append(pairs, strings.Trim(value[start:i]," \t")) + pairs = append(pairs, strings.Trim(value[start:i], " \t")) start = i + 1 } } if state != Plain { - err = fmt.Errorf("unclosed quote starting at position %d", quote + 1) + err = fmt.Errorf("unclosed quote starting at position %d", quote+1) pairs = nil } else { pairs = append(pairs, strings.Trim(value[start:], " \t")) diff --git a/pkg/util/users/users.go b/pkg/util/users/users.go index f4e41e8e8..1f83706fe 100644 --- a/pkg/util/users/users.go +++ b/pkg/util/users/users.go @@ -173,8 +173,8 @@ func produceAlterStmt(user spec.PgUser) string { func produceAlterRoleSetStmts(user spec.PgUser) []string { result := make([]string, 0) result = append(result, fmt.Sprintf(alterRoleResetAllSQL, user.Name)) - for key, value := range user.Parameters { - result = append(result, fmt.Sprintf(alterRoleSetSQL, user.Name, key, quoteValue(value))) + for name, value := range user.Parameters { + result = append(result, fmt.Sprintf(alterRoleSetSQL, user.Name, name, quoteParameterValue(name, value))) } return result } @@ -193,10 +193,25 @@ func quoteMemberList(user spec.PgUser) string { } // quoteVal quotes values to be used at ALTER ROLE SET param = value if necessary -func quoteValue(val string) string { - if (strings.HasPrefix(val, `"`) && strings.HasSuffix(val, `"`)) || - (strings.HasPrefix(val, `'`) && strings.HasSuffix(val, `'`)) { +func quoteParameterValue(name, val string) string { + start := val[0] + end := val[len(val)-1] + if name == "search_path" { + // strip single quotes from the search_path. Those are required in the YAML configuration + // to quote values containing commas, as otherwise NewFromMap would treat each comma-separated + // part of such string as a separate map entry. However, a search_path is interpreted as a list + // only if it is not quoted, otherwise it is treated as a single value. Therefore, we strip + // single quotes here. Note that you can still use double quotes in order to escape schemas + // containing spaces (but something more complex, like double quotes inside double quotes or spaces + // in the schema name would break the parsing code in the operator.) + if start == '\'' && end == '\'' { + return fmt.Sprintf("%s", val[1:len(val)-1]) + } else { + return val + } + } + if (start == '"' && end == '"') || (start == '\'' && end == '\'') { return val } - return fmt.Sprintf(`"%s"`, strings.Trim(val, " ")) + return fmt.Sprintf(`'%s'`, strings.Trim(val, " ")) }