MM-67380: COALESCE Drafts.Type to the empty string if NULL (#35109)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions

When the Type column was added to the Drafts table, it did not add a
DEFAULT value, so we need to handle the NULL values for the pre-existing
rows.

Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Alejandro García Montoro 2026-01-29 21:14:56 +01:00 committed by GitHub
parent 7f6a98fd7a
commit 1c1a445a3e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 49 additions and 42 deletions

View file

@ -129,7 +129,7 @@ func (s *SqlDraftStore) GetDraftsForUser(userID, teamID string) ([]*model.Draft,
"Drafts.FileIds",
"Drafts.Props",
"Drafts.Priority",
"Drafts.Type",
"COALESCE(Drafts.Type, '') AS Type",
).
From("Drafts").
InnerJoin("ChannelMembers ON ChannelMembers.ChannelId = Drafts.ChannelId").

View file

@ -369,56 +369,63 @@ func testGetDraftsForUser(t *testing.T, rctx request.CTX, ss store.Store) {
Id: model.NewId(),
}
channel := &model.Channel{
Id: model.NewId(),
newDraftForUser := func(t *testing.T, user *model.User) *model.Draft {
t.Helper()
channel := &model.Channel{
Id: model.NewId(),
}
member := &model.ChannelMember{
ChannelId: channel.Id,
UserId: user.Id,
NotifyProps: model.GetDefaultChannelNotifyProps(),
}
_, err := ss.Channel().SaveMember(rctx, member)
require.NoError(t, err)
draft := &model.Draft{
UserId: user.Id,
ChannelId: channel.Id,
Message: "draft post",
}
insertedDraft, err := ss.Draft().Upsert(draft)
require.NoError(t, err)
return insertedDraft
}
channel2 := &model.Channel{
Id: model.NewId(),
}
member1 := &model.ChannelMember{
ChannelId: channel.Id,
UserId: user.Id,
NotifyProps: model.GetDefaultChannelNotifyProps(),
}
member2 := &model.ChannelMember{
ChannelId: channel2.Id,
UserId: user.Id,
NotifyProps: model.GetDefaultChannelNotifyProps(),
}
_, err := ss.Channel().SaveMember(rctx, member1)
require.NoError(t, err)
_, err = ss.Channel().SaveMember(rctx, member2)
require.NoError(t, err)
draft1 := &model.Draft{
UserId: user.Id,
ChannelId: channel.Id,
Message: "draft1",
}
draft2 := &model.Draft{
UserId: user.Id,
ChannelId: channel2.Id,
Message: "draft2",
}
_, err = ss.Draft().Upsert(draft1)
require.NoError(t, err)
_, err = ss.Draft().Upsert(draft2)
require.NoError(t, err)
t.Run("get drafts", func(t *testing.T) {
t.Cleanup(func() { clearDrafts(t, rctx, ss) })
draft1 := newDraftForUser(t, user)
draft2 := newDraftForUser(t, user)
draftResp, err := ss.Draft().GetDraftsForUser(user.Id, "")
assert.NoError(t, err)
assert.Len(t, draftResp, 2)
assert.ElementsMatch(t, []*model.Draft{draft1, draft2}, draftResp)
})
t.Run("get drafts with Type NULL", func(t *testing.T) {
t.Cleanup(func() { clearDrafts(t, rctx, ss) })
draft := newDraftForUser(t, user)
// Draft().Upsert() correctly handles empty types, so we need to
// manually set Type to NULL
query := "UPDATE Drafts SET Type = NULL WHERE UserId = $1"
_, err := ss.GetInternalMasterDB().Exec(query, user.Id)
require.NoError(t, err)
draftResp, err := ss.Draft().GetDraftsForUser(user.Id, "")
assert.NoError(t, err)
assert.Len(t, draftResp, 1)
assert.ElementsMatch(t, []*model.Draft{draft}, draftResp)
clearDrafts(t, rctx, ss)
})
}
func clearDrafts(t *testing.T, rctx request.CTX, ss store.Store) {