diff --git a/store/searchtest/post_layer.go b/store/searchtest/post_layer.go index 1d03edf7f7..5bfa05a781 100644 --- a/store/searchtest/post_layer.go +++ b/store/searchtest/post_layer.go @@ -35,9 +35,16 @@ var searchPostStoreTests = []searchTest{ Tags: []string{EnginePostgres, EngineMySql, EngineElasticSearch}, }, { + // Postgres supports search with and without quotes Name: "Should be able to search for email addresses with or without quotes", Fn: testSearchEmailAddresses, - Tags: []string{EngineElasticSearch}, + Tags: []string{EnginePostgres, EngineElasticSearch}, + }, + { + // MySql supports search with quotes only + Name: "Should be able to search for email addresses with quotes", + Fn: testSearchEmailAddressesWithQuotes, + Tags: []string{EngineMySql}, }, { Name: "Should be able to search when markdown underscores are applied", @@ -242,11 +249,6 @@ var searchPostStoreTests = []searchTest{ Fn: testSlashShouldNotBeCharSeparator, Tags: []string{EngineMySql, EngineElasticSearch}, }, - { - Name: "Should be able to search emails without quoting them", - Fn: testSearchEmailsWithoutQuotes, - Tags: []string{EngineElasticSearch}, - }, { Name: "Should be able to search in comments", Fn: testSupportSearchInComments, @@ -366,9 +368,9 @@ func testSearchExactPhraseInQuotes(t *testing.T, th *SearchTestHelper) { } func testSearchEmailAddresses(t *testing.T, th *SearchTestHelper) { - p1, err := th.createPost(th.User.Id, th.ChannelBasic.Id, "test email test@test.com", "", model.PostTypeDefault, 0, false) + p1, err := th.createPost(th.User.Id, th.ChannelBasic.Id, "email test@test.com", "", model.PostTypeDefault, 0, false) require.NoError(t, err) - _, err = th.createPost(th.User.Id, th.ChannelBasic.Id, "test email test2@test.com", "", model.PostTypeDefault, 0, false) + _, err = th.createPost(th.User.Id, th.ChannelBasic.Id, "email test2@test.com", "", model.PostTypeDefault, 0, false) require.NoError(t, err) defer th.deleteUserPosts(th.User.Id) @@ -391,6 +393,21 @@ func testSearchEmailAddresses(t *testing.T, th *SearchTestHelper) { }) } +func testSearchEmailAddressesWithQuotes(t *testing.T, th *SearchTestHelper) { + p1, err := th.createPost(th.User.Id, th.ChannelBasic.Id, "email test@test.com", "", model.PostTypeDefault, 0, false) + require.NoError(t, err) + _, err = th.createPost(th.User.Id, th.ChannelBasic.Id, "email test2@test.com", "", model.PostTypeDefault, 0, false) + require.NoError(t, err) + defer th.deleteUserPosts(th.User.Id) + + params := &model.SearchParams{Terms: "\"test@test.com\""} + results, err := th.Store.Post().SearchPostsForUser([]*model.SearchParams{params}, th.User.Id, th.Team.Id, 0, 20) + require.NoError(t, err) + + require.Len(t, results.Posts, 1) + th.checkPostInSearchResults(t, p1.Id, results.Posts) +} + func testSearchMarkdownUnderscores(t *testing.T, th *SearchTestHelper) { p1, err := th.createPost(th.User.Id, th.ChannelBasic.Id, "_start middle end_ _another_", "", model.PostTypeDefault, 0, false) require.NoError(t, err) @@ -1769,21 +1786,6 @@ func testSlashShouldNotBeCharSeparator(t *testing.T, th *SearchTestHelper) { th.checkPostInSearchResults(t, p1.Id, results.Posts) } -func testSearchEmailsWithoutQuotes(t *testing.T, th *SearchTestHelper) { - p1, err := th.createPost(th.User.Id, th.ChannelBasic.Id, "message test@test.com", "", model.PostTypeDefault, 0, false) - require.NoError(t, err) - _, err = th.createPost(th.User.Id, th.ChannelBasic.Id, "message test2@test.com", "", model.PostTypeDefault, 0, false) - require.NoError(t, err) - defer th.deleteUserPosts(th.User.Id) - - params := &model.SearchParams{Terms: "test@test.com"} - results, err := th.Store.Post().SearchPostsForUser([]*model.SearchParams{params}, th.User.Id, th.Team.Id, 0, 20) - require.NoError(t, err) - - require.Len(t, results.Posts, 1) - th.checkPostInSearchResults(t, p1.Id, results.Posts) -} - func testSupportSearchInComments(t *testing.T, th *SearchTestHelper) { p1, err := th.createPost(th.User.Id, th.ChannelBasic.Id, "message test@test.com", "", model.PostTypeDefault, 0, false) require.NoError(t, err) diff --git a/store/sqlstore/file_info_store.go b/store/sqlstore/file_info_store.go index 47d847b9d1..49403e4d98 100644 --- a/store/sqlstore/file_info_store.go +++ b/store/sqlstore/file_info_store.go @@ -606,8 +606,7 @@ func (fs SqlFileInfoStore) Search(paramsList []*model.SearchParams, userId, team terms := params.Terms excludedTerms := params.ExcludedTerms - // these chars have special meaning and can be treated as spaces - for _, c := range specialSearchChar { + for _, c := range fs.specialSearchChars() { terms = strings.Replace(terms, c, " ", -1) excludedTerms = strings.Replace(excludedTerms, c, " ", -1) } diff --git a/store/sqlstore/post_store.go b/store/sqlstore/post_store.go index 127e566861..5afdddac63 100644 --- a/store/sqlstore/post_store.go +++ b/store/sqlstore/post_store.go @@ -1788,18 +1788,6 @@ func (s *SqlPostStore) getParentsPostsPostgreSQL(channelId string, offset int, l return posts, nil } -var specialSearchChar = []string{ - "<", - ">", - "+", - "-", - "(", - ")", - "~", - "@", - ":", -} - // GetNthRecentPostTime returns the CreateAt time of the nth most recent post. func (s *SqlPostStore) GetNthRecentPostTime(n int64) (int64, error) { if n <= 0 { @@ -1989,8 +1977,7 @@ func (s *SqlPostStore) search(teamId string, userId string, params *model.Search } } - // these chars have special meaning and can be treated as spaces - for _, c := range specialSearchChar { + for _, c := range s.specialSearchChars() { terms = strings.Replace(terms, c, " ", -1) excludedTerms = strings.Replace(excludedTerms, c, " ", -1) } diff --git a/store/sqlstore/store.go b/store/sqlstore/store.go index 71f9598ed0..2730ece664 100644 --- a/store/sqlstore/store.go +++ b/store/sqlstore/store.go @@ -335,6 +335,28 @@ func (ss *SqlStore) DriverName() string { return *ss.settings.DriverName } +// specialSearchChars have special meaning and can be treated as spaces +func (ss *SqlStore) specialSearchChars() []string { + chars := []string{ + "<", + ">", + "+", + "-", + "(", + ")", + "~", + ":", + } + + // Postgres can handle "@" without any errors + // Also helps postgres in enabling search for EmailAddresses + if ss.DriverName() != model.DatabaseDriverPostgres { + chars = append(chars, "@") + } + + return chars +} + // computeBinaryParam returns whether the data source uses binary_parameters // when using Postgres func (ss *SqlStore) computeBinaryParam() (bool, error) {