diff --git a/backend/search/main.go b/backend/search/main.go index e3d65760..23a599a1 100644 --- a/backend/search/main.go +++ b/backend/search/main.go @@ -133,6 +133,7 @@ func search(ctx context.Context, conn *pgx.Conn, params SearchParams, cfg Rankin } const rankedSpeechSearchSQL = ` + -- Keep headline options explicit; do not pass empty selectors to ts_headline. WITH query AS ( SELECT plainto_tsquery('english', $1) AS english_query, diff --git a/backend/search/main_test.go b/backend/search/main_test.go index f5e10f45..381ebf59 100644 --- a/backend/search/main_test.go +++ b/backend/search/main_test.go @@ -159,6 +159,24 @@ func TestRankingConfigRejectsInvalidEnv(t *testing.T) { } } +func TestTsHeadlineOptionsHaveNoEmptySelectors(t *testing.T) { + for _, tc := range []struct { + name string + sql string + }{ + {"ranked", rankedSpeechSearchSQL}, + {"legacy", legacySpeechSearchSQL}, + } { + t.Run(tc.name, func(t *testing.T) { + for _, token := range []string{"StartSel=", "StopSel="} { + if strings.Contains(tc.sql, token) { + t.Fatalf("%s SQL unexpectedly contains %q", tc.name, token) + } + } + }) + } +} + func TestRankingSQLDocumentsRequiredComponents(t *testing.T) { required := []string{ "ts_rank",