diff --git a/internal/pkg/store/postgres/store.go b/internal/pkg/store/postgres/store.go index ad5e1cd..bac7966 100644 --- a/internal/pkg/store/postgres/store.go +++ b/internal/pkg/store/postgres/store.go @@ -422,9 +422,16 @@ func (p pinStore) Create(ctx context.Context, pn *store.Pin) error { if err != nil { return fmt.Errorf("marshal meta: %w", err) } + // pins.origins is NOT NULL DEFAULT '{}'. pgx serialises a nil + // []string as SQL NULL, which would fail the constraint, so coerce + // nil to an empty slice at the boundary. + origins := pn.Origins + if origins == nil { + origins = []string{} + } _, err = p.s.queries().CreatePin(ctx, sqlc.CreatePinParams{ RequestID: pn.RequestID, OrgID: pn.OrgID, Cid: pn.CID, - Name: pn.Name, Meta: meta, Origins: pn.Origins, + Name: pn.Name, Meta: meta, Origins: origins, }) if isUniqueViolation(err) { return store.ErrConflict @@ -550,6 +557,9 @@ func (p pinStore) Replace(ctx context.Context, orgID ids.OrgID, rid ids.PinID, n if err != nil { return nil, err } + if origins == nil { + origins = []string{} + } row, err := p.s.queries().ReplacePin(ctx, sqlc.ReplacePinParams{ RequestID: rid, OrgID: orgID, Cid: newCID, Name: name, Meta: metaBytes, Origins: origins, }) diff --git a/test/rls_integration_test.go b/test/rls_integration_test.go index 373b87a..4365693 100644 --- a/test/rls_integration_test.go +++ b/test/rls_integration_test.go @@ -80,7 +80,10 @@ func txWithOrg(ctx context.Context, pool *pgxpool.Pool, org string, fn func(cont } defer func() { _ = tx.Rollback(ctx) }() if org != "" { - if _, err := tx.Exec(ctx, "SET LOCAL anchorage.org_id = $1", org); err != nil { + // SET LOCAL does not accept bound parameters; use set_config, + // which does, so the org id is never string-concatenated into + // SQL. + if _, err := tx.Exec(ctx, "SELECT set_config('anchorage.org_id', $1, true)", org); err != nil { return err } }