Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions internal/repo/tag_common/tag_common_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ package tag_common

import (
"context"
"fmt"
"strconv"
"strings"

Expand Down Expand Up @@ -171,10 +170,20 @@ func (tr *tagCommonRepo) GetTagPage(ctx context.Context, page, pageSize int, tag
session := tr.data.DB.Context(ctx)

if len(tag.SlugName) > 0 {
// Both sides lowered, so the search is case-insensitive.
//
// This previously read LOWER(%s) formatted against the *search term*,
// which put the function name into the value: the query became
// slug_name LIKE '%LOWER(coco)%' and could never match. Only the
// display_name clause did anything, and that is case-sensitive on
// Postgres, so typing a tag in lower case -- which is how tags are
// written and therefore how anyone types them -- returned nothing at all
// and read as "no such tag".
search := searchTermForTag(tag.SlugName)
mainTagCond := builder.And(
builder.Or(
builder.Like{"slug_name", fmt.Sprintf("LOWER(%s)", tag.SlugName)},
builder.Like{"display_name", tag.SlugName},
builder.Like{"LOWER(slug_name)", search},
builder.Like{"LOWER(display_name)", search},
),
builder.Eq{"main_tag_id": 0},
)
Expand Down Expand Up @@ -293,3 +302,10 @@ func (tr *tagCommonRepo) UpdateTagsAttribute(ctx context.Context, tags []string,
}
return
}

// searchTermForTag normalises a tag search term. Lowering it here, and lowering
// the columns in the query, is what makes the search case-insensitive: tags are
// written in lower case, so that is how people type them.
func searchTermForTag(term string) string {
return strings.ToLower(strings.TrimSpace(term))
}
17 changes: 17 additions & 0 deletions internal/repo/tag_common/tagsearch_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package tag_common

import "testing"

// The bug: the search term was formatted into LOWER(%s), which put the function
// name into the value rather than applying it to the column, so the query became
// slug_name LIKE '%LOWER(coco)%' and matched nothing. Only display_name did any
// work, and that is case-sensitive on Postgres -- so typing a tag the way tags
// are actually written returned "no such tag".
func TestSearchTermIsLoweredNotWrapped(t *testing.T) {
for _, in := range []string{"Coco", "COCO", "coco"} {
got := searchTermForTag(in)
if got != "coco" {
t.Errorf("searchTermForTag(%q) = %q, want %q", in, got, "coco")
}
}
}