diff --git a/server/store/proposal_recovery_sql.go b/server/store/proposal_recovery_sql.go index a19006c2..22903caf 100644 --- a/server/store/proposal_recovery_sql.go +++ b/server/store/proposal_recovery_sql.go @@ -18,7 +18,8 @@ WHERE proposal_id = $1 AND state = 'OPEN' AND expires_at <= $2` const ProposalParticipantExpireSQL = `UPDATE proposal_participants SET response = 'TIMED_OUT', responded_at = $2 -WHERE proposal_id = $1 AND response = 'PENDING'` +WHERE proposal_id = $1 AND response = 'PENDING' + AND EXISTS (SELECT 1 FROM proposals WHERE proposals.proposal_id = proposal_participants.proposal_id AND proposals.expires_at <= $2)` const ProposalRecoverySelectSQL = `SELECT proposal_id, playlist, state, revision, expires_at FROM proposals diff --git a/server/store/proposal_recovery_sql_test.go b/server/store/proposal_recovery_sql_test.go index 90286dc6..13e2281a 100644 --- a/server/store/proposal_recovery_sql_test.go +++ b/server/store/proposal_recovery_sql_test.go @@ -8,7 +8,7 @@ import ( func TestProposalRecoverySQLBindsParticipantAndExpiresAtReadBoundary(t *testing.T) { for query, fragments := range map[string][]string{ ProposalExpireSQL: {"state = 'OPEN'", "expires_at <= $2", "revision = revision + 1"}, - ProposalParticipantExpireSQL: {"response = 'PENDING'", "response = 'TIMED_OUT'"}, + ProposalParticipantExpireSQL: {"response = 'PENDING'", "response = 'TIMED_OUT'", "proposals.expires_at <= $2"}, ProposalRecoverySelectSQL: {"proposal_id = $1", "player_id = $2", "EXISTS"}, ProposalParticipantsSelectSQL: {"proposal_id = $1", "ORDER BY player_id"}, ProposalResponseIdempotencyInsertSQL: {"ON CONFLICT (scope, idempotency_key) DO NOTHING", "payload_digest"},