diff --git a/cmd/initialise/verify_zitadel.go b/cmd/initialise/verify_zitadel.go index 5dbfd2b056..a9422550de 100644 --- a/cmd/initialise/verify_zitadel.go +++ b/cmd/initialise/verify_zitadel.go @@ -31,16 +31,18 @@ Prereqesits: - cockroachdb with user and database `, RunE: func(cmd *cobra.Command, args []string) error { - config := new(Config) - if err := viper.Unmarshal(config); err != nil { - return err - } + config := MustNewConfig(viper.GetViper()) return verifyZitadel(config.Database) }, } } func VerifyZitadel(db *sql.DB, config database.Config) error { + err := ReadStmts(config.Type()) + if err != nil { + return err + } + if err := exec(db, fmt.Sprintf(createSystemStmt, config.Username()), nil); err != nil { return err } @@ -73,10 +75,12 @@ func VerifyZitadel(db *sql.DB, config database.Config) error { func verifyZitadel(config database.Config) error { logging.WithFields("database", config.Database()).Info("verify zitadel") + db, err := database.Connect(config, false) if err != nil { return err } + if err := VerifyZitadel(db, config); err != nil { return nil } diff --git a/cmd/setup/config.go b/cmd/setup/config.go index 06093002bb..2977eeb48d 100644 --- a/cmd/setup/config.go +++ b/cmd/setup/config.go @@ -14,6 +14,7 @@ import ( "github.com/zitadel/zitadel/internal/config/systemdefaults" "github.com/zitadel/zitadel/internal/crypto" "github.com/zitadel/zitadel/internal/database" + "github.com/zitadel/zitadel/internal/id" ) type Config struct { @@ -26,6 +27,7 @@ type Config struct { Log *logging.Config EncryptionKeys *encryptionKeyConfig DefaultInstance command.InstanceSetup + Machine *id.Config } func MustNewConfig(v *viper.Viper) *Config { @@ -44,6 +46,8 @@ func MustNewConfig(v *viper.Viper) *Config { err = config.Log.SetLogger() logging.OnError(err).Fatal("unable to set logger") + id.Configure(config.Machine) + return config } diff --git a/internal/database/cockroach/config.go b/internal/database/cockroach/config.go index 3fd0badfa2..fc5abf4579 100644 --- a/internal/database/cockroach/config.go +++ b/internal/database/cockroach/config.go @@ -42,8 +42,9 @@ func (c *Config) MatchName(name string) bool { func (c *Config) Decode(configs []interface{}) (dialect.Connector, error) { decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ - DecodeHook: mapstructure.StringToTimeDurationHookFunc(), - Result: c, + DecodeHook: mapstructure.StringToTimeDurationHookFunc(), + WeaklyTypedInput: true, + Result: c, }) if err != nil { return nil, err diff --git a/internal/database/postgres/config.go b/internal/database/postgres/config.go index 653cb20440..03aa17755e 100644 --- a/internal/database/postgres/config.go +++ b/internal/database/postgres/config.go @@ -41,8 +41,9 @@ func (c *Config) MatchName(name string) bool { func (c *Config) Decode(configs []interface{}) (dialect.Connector, error) { decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ - DecodeHook: mapstructure.StringToTimeDurationHookFunc(), - Result: c, + DecodeHook: mapstructure.StringToTimeDurationHookFunc(), + WeaklyTypedInput: true, + Result: c, }) if err != nil { return nil, err diff --git a/internal/eventstore/handler/crdb/handler_stmt.go b/internal/eventstore/handler/crdb/handler_stmt.go index b8fe8ad88f..4c858ac3b4 100644 --- a/internal/eventstore/handler/crdb/handler_stmt.go +++ b/internal/eventstore/handler/crdb/handler_stmt.go @@ -112,7 +112,7 @@ func (h *StatementHandler) SearchQuery(ctx context.Context, instanceIDs []string return queryBuilder, h.bulkLimit, nil } -//Update implements handler.Update +// Update implements handler.Update func (h *StatementHandler) Update(ctx context.Context, stmts []*handler.Statement, reduce handler.Reduce) (index int, err error) { if len(stmts) == 0 { return -1, nil @@ -248,8 +248,8 @@ stmts: return lastSuccessfulIdx } -//executeStmt handles sql statements -//an error is returned if the statement could not be inserted properly +// executeStmt handles sql statements +// an error is returned if the statement could not be inserted properly func (h *StatementHandler) executeStmt(tx *sql.Tx, stmt *handler.Statement) error { if stmt.IsNoop() { return nil diff --git a/internal/eventstore/handler/crdb/statement.go b/internal/eventstore/handler/crdb/statement.go index 8f0235fd63..1549289bc0 100644 --- a/internal/eventstore/handler/crdb/statement.go +++ b/internal/eventstore/handler/crdb/statement.go @@ -72,8 +72,17 @@ func NewUpsertStatement(event eventstore.Event, conflictCols []handler.Column, v } q := func(config execConfig) string { + var updateStmt string + // the postgres standard does not allow to update a single column using a multi-column update + // discussion: https://www.postgresql.org/message-id/17451.1509381766%40sss.pgh.pa.us + // see Compatibility in https://www.postgresql.org/docs/current/sql-update.html + if len(updateCols) == 1 && !strings.HasPrefix(updateVals[0], "SELECT") { + updateStmt = "UPDATE SET " + updateCols[0] + " = " + updateVals[0] + } else { + updateStmt = "UPDATE SET (" + strings.Join(updateCols, ", ") + ") = (" + strings.Join(updateVals, ", ") + ")" + } return "INSERT INTO " + config.tableName + " (" + strings.Join(cols, ", ") + ") VALUES (" + strings.Join(params, ", ") + ")" + - " ON CONFLICT (" + strings.Join(conflictTarget, ", ") + ") DO UPDATE SET (" + strings.Join(updateCols, ", ") + ") = (" + strings.Join(updateVals, ", ") + ")" + " ON CONFLICT (" + strings.Join(conflictTarget, ", ") + ") DO " + updateStmt } return &handler.Statement{ @@ -130,6 +139,12 @@ func NewUpdateStatement(event eventstore.Event, values []handler.Column, conditi } q := func(config execConfig) string { + // the postgres standard does not allow to update a single column using a multi-column update + // discussion: https://www.postgresql.org/message-id/17451.1509381766%40sss.pgh.pa.us + // see Compatibility in https://www.postgresql.org/docs/current/sql-update.html + if len(cols) == 1 && !strings.HasPrefix(params[0], "SELECT") { + return "UPDATE " + config.tableName + " SET " + cols[0] + " = " + params[0] + " WHERE " + strings.Join(wheres, " AND ") + } return "UPDATE " + config.tableName + " SET (" + strings.Join(cols, ", ") + ") = (" + strings.Join(params, ", ") + ") WHERE " + strings.Join(wheres, " AND ") } diff --git a/internal/eventstore/handler/crdb/statement_test.go b/internal/eventstore/handler/crdb/statement_test.go index f8fe6a8427..efc2704936 100644 --- a/internal/eventstore/handler/crdb/statement_test.go +++ b/internal/eventstore/handler/crdb/statement_test.go @@ -282,7 +282,53 @@ func TestNewUpsertStatement(t *testing.T) { }, }, { - name: "correct", + name: "correct UPDATE multi col", + args: args{ + table: "my_table", + event: &testEvent{ + aggregateType: "agg", + sequence: 1, + previousSequence: 0, + }, + conflictCols: []handler.Column{ + handler.NewCol("col1", nil), + }, + values: []handler.Column{ + { + Name: "col1", + Value: "val", + }, + { + Name: "col2", + Value: "val", + }, + { + Name: "col3", + Value: "val", + }, + }, + }, + want: want{ + table: "my_table", + aggregateType: "agg", + sequence: 1, + previousSequence: 1, + executer: &wantExecuter{ + params: []params{ + { + query: "INSERT INTO my_table (col1, col2, col3) VALUES ($1, $2, $3) ON CONFLICT (col1) DO UPDATE SET (col2, col3) = (EXCLUDED.col2, EXCLUDED.col3)", + args: []interface{}{"val", "val", "val"}, + }, + }, + shouldExecute: true, + }, + isErr: func(err error) bool { + return err == nil + }, + }, + }, + { + name: "correct UPDATE single col", args: args{ table: "my_table", event: &testEvent{ @@ -312,7 +358,7 @@ func TestNewUpsertStatement(t *testing.T) { executer: &wantExecuter{ params: []params{ { - query: "INSERT INTO my_table (col1, col2) VALUES ($1, $2) ON CONFLICT (col1) DO UPDATE SET (col2) = (EXCLUDED.col2)", + query: "INSERT INTO my_table (col1, col2) VALUES ($1, $2) ON CONFLICT (col1) DO UPDATE SET col2 = EXCLUDED.col2", args: []interface{}{"val", "val"}, }, }, @@ -454,7 +500,7 @@ func TestNewUpdateStatement(t *testing.T) { }, }, { - name: "correct", + name: "correct single column", args: args{ table: "my_table", event: &testEvent{ @@ -483,7 +529,7 @@ func TestNewUpdateStatement(t *testing.T) { executer: &wantExecuter{ params: []params{ { - query: "UPDATE my_table SET (col1) = ($1) WHERE (col2 = $2)", + query: "UPDATE my_table SET col1 = $1 WHERE (col2 = $2)", args: []interface{}{"val", 1}, }, }, @@ -494,6 +540,51 @@ func TestNewUpdateStatement(t *testing.T) { }, }, }, + { + name: "correct multi column", + args: args{ + table: "my_table", + event: &testEvent{ + aggregateType: "agg", + sequence: 1, + previousSequence: 0, + }, + values: []handler.Column{ + { + Name: "col1", + Value: "val", + }, + { + Name: "col3", + Value: "val5", + }, + }, + conditions: []handler.Condition{ + { + Name: "col2", + Value: 1, + }, + }, + }, + want: want{ + table: "my_table", + aggregateType: "agg", + sequence: 1, + previousSequence: 1, + executer: &wantExecuter{ + params: []params{ + { + query: "UPDATE my_table SET (col1, col3) = ($1, $2) WHERE (col2 = $3)", + args: []interface{}{"val", "val5", 1}, + }, + }, + shouldExecute: true, + }, + isErr: func(err error) bool { + return err == nil + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -808,11 +899,11 @@ func TestNewMultiStatement(t *testing.T) { args: []interface{}{1}, }, { - query: "INSERT INTO my_table (col1, col2) VALUES ($1, $2) ON CONFLICT (col1) DO UPDATE SET (col2) = (EXCLUDED.col2)", + query: "INSERT INTO my_table (col1, col2) VALUES ($1, $2) ON CONFLICT (col1) DO UPDATE SET col2 = EXCLUDED.col2", args: []interface{}{1, 2}, }, { - query: "UPDATE my_table SET (col1) = ($1) WHERE (col1 = $2)", + query: "UPDATE my_table SET col1 = $1 WHERE (col1 = $2)", args: []interface{}{1, 1}, }, }, diff --git a/internal/query/projection/app_test.go b/internal/query/projection/app_test.go index ed5d4db707..d9d282883f 100644 --- a/internal/query/projection/app_test.go +++ b/internal/query/projection/app_test.go @@ -351,7 +351,7 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.apps2_api_configs SET (client_secret) = ($1) WHERE (app_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.apps2_api_configs SET client_secret = $1 WHERE (app_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ anyArg{}, "app-id", @@ -552,7 +552,7 @@ func TestAppProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.apps2_oidc_configs SET (client_secret) = ($1) WHERE (app_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.apps2_oidc_configs SET client_secret = $1 WHERE (app_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ anyArg{}, "app-id", diff --git a/internal/query/projection/authn_key_test.go b/internal/query/projection/authn_key_test.go index 238421c1c3..49b43d034e 100644 --- a/internal/query/projection/authn_key_test.go +++ b/internal/query/projection/authn_key_test.go @@ -161,7 +161,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.authn_keys SET (enabled) = ($1) WHERE (object_id = $2)", + expectedStmt: "UPDATE projections.authn_keys SET enabled = $1 WHERE (object_id = $2)", expectedArgs: []interface{}{ false, "appId", @@ -189,7 +189,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.authn_keys SET (enabled) = ($1) WHERE (object_id = $2)", + expectedStmt: "UPDATE projections.authn_keys SET enabled = $1 WHERE (object_id = $2)", expectedArgs: []interface{}{ true, "appId", @@ -264,7 +264,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.authn_keys SET (enabled) = ($1) WHERE (object_id = $2)", + expectedStmt: "UPDATE projections.authn_keys SET enabled = $1 WHERE (object_id = $2)", expectedArgs: []interface{}{ false, "appId", @@ -292,7 +292,7 @@ func TestAuthNKeyProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.authn_keys SET (enabled) = ($1) WHERE (object_id = $2)", + expectedStmt: "UPDATE projections.authn_keys SET enabled = $1 WHERE (object_id = $2)", expectedArgs: []interface{}{ true, "appId", diff --git a/internal/query/projection/login_name_test.go b/internal/query/projection/login_name_test.go index 2781127043..2cc97006ec 100644 --- a/internal/query/projection/login_name_test.go +++ b/internal/query/projection/login_name_test.go @@ -165,7 +165,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.login_names_users SET (user_name) = ($1) WHERE (id = $2)", + expectedStmt: "UPDATE projections.login_names_users SET user_name = $1 WHERE (id = $2)", expectedArgs: []interface{}{ "changed", "agg-id", @@ -195,7 +195,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.login_names_users SET (user_name) = ($1) WHERE (id = $2)", + expectedStmt: "UPDATE projections.login_names_users SET user_name = $1 WHERE (id = $2)", expectedArgs: []interface{}{ "claimed", "agg-id", @@ -257,7 +257,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.login_names_policies SET (must_be_domain) = ($1) WHERE (resource_owner = $2)", + expectedStmt: "UPDATE projections.login_names_policies SET must_be_domain = $1 WHERE (resource_owner = $2)", expectedArgs: []interface{}{ false, "ro-id", @@ -395,7 +395,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.login_names_domains SET (is_primary) = ($1) WHERE (resource_owner = $2) AND (is_primary = $3)", + expectedStmt: "UPDATE projections.login_names_domains SET is_primary = $1 WHERE (resource_owner = $2) AND (is_primary = $3)", expectedArgs: []interface{}{ false, "ro-id", @@ -403,7 +403,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE projections.login_names_domains SET (is_primary) = ($1) WHERE (name = $2) AND (resource_owner = $3)", + expectedStmt: "UPDATE projections.login_names_domains SET is_primary = $1 WHERE (name = $2) AND (resource_owner = $3)", expectedArgs: []interface{}{ true, "primary", @@ -466,7 +466,7 @@ func TestLoginNameProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.login_names_policies SET (must_be_domain) = ($1) WHERE (resource_owner = $2)", + expectedStmt: "UPDATE projections.login_names_policies SET must_be_domain = $1 WHERE (resource_owner = $2)", expectedArgs: []interface{}{ false, "ro-id", diff --git a/internal/query/projection/sms_test.go b/internal/query/projection/sms_test.go index b9f8304723..e492aff93c 100644 --- a/internal/query/projection/sms_test.go +++ b/internal/query/projection/sms_test.go @@ -150,7 +150,7 @@ func TestSMSProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.sms_configs_twilio SET (token) = ($1) WHERE (sms_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.sms_configs_twilio SET token = $1 WHERE (sms_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ &crypto.CryptoValue{ CryptoType: crypto.TypeEncryption, diff --git a/internal/query/projection/user_grant_test.go b/internal/query/projection/user_grant_test.go index 38ac4c4751..2d960e5eab 100644 --- a/internal/query/projection/user_grant_test.go +++ b/internal/query/projection/user_grant_test.go @@ -342,7 +342,7 @@ func TestUserGrantProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.user_grants2 SET (roles) = (array_remove(roles, $1)) WHERE (project_id = $2)", + expectedStmt: "UPDATE projections.user_grants2 SET roles = array_remove(roles, $1) WHERE (project_id = $2)", expectedArgs: []interface{}{ "key", "agg-id", diff --git a/internal/query/projection/user_test.go b/internal/query/projection/user_test.go index 8d7e0d9934..e7846a258d 100644 --- a/internal/query/projection/user_test.go +++ b/internal/query/projection/user_test.go @@ -450,7 +450,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.users3 SET (state) = ($1) WHERE (id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3 SET state = $1 WHERE (id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ domain.UserStateInitial, "agg-id", @@ -479,7 +479,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.users3 SET (state) = ($1) WHERE (id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3 SET state = $1 WHERE (id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ domain.UserStateInitial, "agg-id", @@ -508,7 +508,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.users3 SET (state) = ($1) WHERE (id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3 SET state = $1 WHERE (id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ domain.UserStateActive, "agg-id", @@ -537,7 +537,7 @@ func TestUserProjection_reduces(t *testing.T) { executer: &testExecuter{ executions: []execution{ { - expectedStmt: "UPDATE projections.users3 SET (state) = ($1) WHERE (id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3 SET state = $1 WHERE (id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ domain.UserStateActive, "agg-id", @@ -904,7 +904,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE projections.users3_notifications SET (last_phone) = ($1) WHERE (user_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3_notifications SET last_phone = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ &sql.NullString{String: "+41 00 000 00 00", Valid: true}, "agg-id", @@ -953,7 +953,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE projections.users3_notifications SET (last_phone) = ($1) WHERE (user_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3_notifications SET last_phone = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ &sql.NullString{String: "+41 00 000 00 00", Valid: true}, "agg-id", @@ -1087,7 +1087,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE projections.users3_humans SET (is_phone_verified) = ($1) WHERE (user_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3_humans SET is_phone_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ true, "agg-id", @@ -1132,7 +1132,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE projections.users3_humans SET (is_phone_verified) = ($1) WHERE (user_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3_humans SET is_phone_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ true, "agg-id", @@ -1188,7 +1188,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE projections.users3_notifications SET (last_email) = ($1) WHERE (user_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3_notifications SET last_email = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ &sql.NullString{String: "email@zitadel.com", Valid: true}, "agg-id", @@ -1237,7 +1237,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE projections.users3_notifications SET (last_email) = ($1) WHERE (user_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3_notifications SET last_email = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ &sql.NullString{String: "email@zitadel.com", Valid: true}, "agg-id", @@ -1275,7 +1275,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE projections.users3_humans SET (is_email_verified) = ($1) WHERE (user_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3_humans SET is_email_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ true, "agg-id", @@ -1320,7 +1320,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE projections.users3_humans SET (is_email_verified) = ($1) WHERE (user_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3_humans SET is_email_verified = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ true, "agg-id", @@ -1367,7 +1367,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE projections.users3_humans SET (avatar_key) = ($1) WHERE (user_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3_humans SET avatar_key = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ "users/agg-id/avatar", "agg-id", @@ -1405,7 +1405,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE projections.users3_humans SET (avatar_key) = ($1) WHERE (user_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3_humans SET avatar_key = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ nil, "agg-id", @@ -1582,7 +1582,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE projections.users3_machines SET (name) = ($1) WHERE (user_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3_machines SET name = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ "machine-name", "agg-id", @@ -1622,7 +1622,7 @@ func TestUserProjection_reduces(t *testing.T) { }, }, { - expectedStmt: "UPDATE projections.users3_machines SET (description) = ($1) WHERE (user_id = $2) AND (instance_id = $3)", + expectedStmt: "UPDATE projections.users3_machines SET description = $1 WHERE (user_id = $2) AND (instance_id = $3)", expectedArgs: []interface{}{ "description", "agg-id",