diff --git a/build/docker/postgres.conf b/build/docker/postgres.conf index 1c2b235647..2e7d3ca0ba 100644 --- a/build/docker/postgres.conf +++ b/build/docker/postgres.conf @@ -2,3 +2,4 @@ max_connections = 300 listen_addresses = '*' fsync = off full_page_writes = off +default_text_search_config = 'pg_catalog.english' \ No newline at end of file diff --git a/store/sqlstore/channel_store.go b/store/sqlstore/channel_store.go index 7ba6eebcfb..4ecfc65915 100644 --- a/store/sqlstore/channel_store.go +++ b/store/sqlstore/channel_store.go @@ -3484,7 +3484,7 @@ func (s SqlChannelStore) buildFulltextClause(term string, searchColumns string) fulltextTerm = strings.Join(splitTerm, " & ") - fulltextClause = fmt.Sprintf("((to_tsvector('english', %s)) @@ to_tsquery('english', :FulltextTerm))", convertMySQLFullTextColumnsToPostgres(searchColumns)) + fulltextClause = fmt.Sprintf("((to_tsvector('%[1]s', %[2]s)) @@ to_tsquery('%[1]s', :FulltextTerm))", s.pgDefaultTextSearchConfig, convertMySQLFullTextColumnsToPostgres(searchColumns)) } else if s.DriverName() == model.DatabaseDriverMysql { splitTerm := strings.Fields(fulltextTerm) for i, t := range strings.Fields(fulltextTerm) { @@ -3525,7 +3525,7 @@ func (s SqlChannelStore) buildFulltextClauseX(term string, searchColumns ...stri // join the search term with & fulltextTerm = strings.Join(splitTerm, " & ") - expr := fmt.Sprintf("((to_tsvector('english', %s)) @@ to_tsquery('english', ?))", strings.Join(searchColumns, " || ' ' || ")) + expr := fmt.Sprintf("((to_tsvector('%[1]s', %[2]s)) @@ to_tsquery('%[1]s', ?))", s.pgDefaultTextSearchConfig, strings.Join(searchColumns, " || ' ' || ")) return sq.Expr(expr, fulltextTerm) } diff --git a/store/sqlstore/file_info_store.go b/store/sqlstore/file_info_store.go index b9eb515992..abbf82e58f 100644 --- a/store/sqlstore/file_info_store.go +++ b/store/sqlstore/file_info_store.go @@ -633,9 +633,9 @@ func (fs SqlFileInfoStore) Search(paramsList []*model.SearchParams, userId, team } query = query.Where(sq.Or{ - sq.Expr("to_tsvector('english', FileInfo.Name) @@ to_tsquery('english', ?)", queryTerms), - sq.Expr("to_tsvector('english', Translate(FileInfo.Name, '.,-', ' ')) @@ to_tsquery('english', ?)", queryTerms), - sq.Expr("to_tsvector('english', FileInfo.Content) @@ to_tsquery('english', ?)", queryTerms), + sq.Expr(fmt.Sprintf("to_tsvector('%[1]s', FileInfo.Name) @@ to_tsquery('%[1]s', ?)", fs.pgDefaultTextSearchConfig), queryTerms), + sq.Expr(fmt.Sprintf("to_tsvector('%[1]s', Translate(FileInfo.Name, '.,-', ' ')) @@ to_tsquery('%[1]s', ?)", fs.pgDefaultTextSearchConfig), queryTerms), + sq.Expr(fmt.Sprintf("to_tsvector('%[1]s', FileInfo.Content) @@ to_tsquery('%[1]s', ?)", fs.pgDefaultTextSearchConfig), queryTerms), }) } else if fs.DriverName() == model.DatabaseDriverMysql { var err error diff --git a/store/sqlstore/post_store.go b/store/sqlstore/post_store.go index cf1bee5176..c2dd8f966f 100644 --- a/store/sqlstore/post_store.go +++ b/store/sqlstore/post_store.go @@ -1919,7 +1919,7 @@ func (s *SqlPostStore) search(teamId string, userId string, params *model.Search termsClause = "(" + strings.Join(strings.Fields(terms), " & ") + ")" + excludeClause } - searchClause := fmt.Sprintf("to_tsvector('english', %s) @@ to_tsquery('english', ?)", searchType) + searchClause := fmt.Sprintf("to_tsvector('%[1]s', %[2]s) @@ to_tsquery('%[1]s', ?)", s.pgDefaultTextSearchConfig, searchType) baseQuery = baseQuery.Where(searchClause, termsClause) } else if s.DriverName() == model.DatabaseDriverMysql { if searchType == "Message" { diff --git a/store/sqlstore/store.go b/store/sqlstore/store.go index 903df4194c..a0804fb4fc 100644 --- a/store/sqlstore/store.go +++ b/store/sqlstore/store.go @@ -131,7 +131,8 @@ type SqlStore struct { licenseMutex sync.RWMutex metrics einterfaces.MetricsInterface - isBinaryParam bool + isBinaryParam bool + pgDefaultTextSearchConfig string } func New(settings model.SqlSettings, metrics einterfaces.MetricsInterface) *SqlStore { @@ -169,6 +170,11 @@ func New(settings model.SqlSettings, metrics einterfaces.MetricsInterface) *SqlS mlog.Fatal("Failed to compute binary param", mlog.Err(err)) } + store.pgDefaultTextSearchConfig, err = store.computeDefaultTextSearchConfig() + if err != nil { + mlog.Fatal("Failed to compute default text search config", mlog.Err(err)) + } + store.stores.team = newSqlTeamStore(store) store.stores.channel = newSqlChannelStore(store, metrics) store.stores.post = newSqlPostStore(store, metrics) @@ -337,6 +343,16 @@ func (ss *SqlStore) computeBinaryParam() (bool, error) { return DSNHasBinaryParam(*ss.settings.DataSource) } +func (ss *SqlStore) computeDefaultTextSearchConfig() (string, error) { + if ss.DriverName() != model.DatabaseDriverPostgres { + return "", nil + } + + var defaultTextSearchConfig string + err := ss.GetMasterX().Get(&defaultTextSearchConfig, `SHOW default_text_search_config`) + return defaultTextSearchConfig, err +} + func (ss *SqlStore) IsBinaryParamEnabled() bool { return ss.isBinaryParam }