Commit 424f11f2 authored by Steven's avatar Steven

fix(store): fix PostgreSQL tag filtering type inference error

Resolves issue where tag filtering in PostgreSQL databases failed with "operator does not exist: jsonb ~~ unknown" error. The hierarchical tag filtering feature introduced in commit 5e47f25b generated SQL with implicit type placeholders that PostgreSQL couldn't infer.

The fix explicitly casts the LIKE comparison placeholder to text (::text) in the PostgreSQL dialect, ensuring proper type resolution for the query parameter.

Fixes #5275

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: 's avatarClaude <noreply@anthropic.com>
parent 68c17469
......@@ -352,7 +352,7 @@ func (r *renderer) renderTagInList(values []ValueExpr) (renderResult, error) {
case DialectPostgres:
// Support hierarchical tags: match exact tag OR tags with this prefix
exactMatch := fmt.Sprintf("%s @> jsonb_build_array(%s::json)", jsonArrayExpr(r.dialect, field), r.addArg(fmt.Sprintf(`"%s"`, str)))
prefixMatch := fmt.Sprintf("%s::text LIKE %s", jsonArrayExpr(r.dialect, field), r.addArg(fmt.Sprintf(`%%"%s/%%`, str)))
prefixMatch := fmt.Sprintf("%s::text LIKE %s::text", jsonArrayExpr(r.dialect, field), r.addArg(fmt.Sprintf(`%%"%s/%%`, str)))
expr := fmt.Sprintf("(%s OR %s)", exactMatch, prefixMatch)
conditions = append(conditions, expr)
default:
......
......@@ -18,12 +18,12 @@ func TestConvertExprToSQL(t *testing.T) {
}{
{
filter: `tag in ["tag1", "tag2"]`,
want: "((memo.payload->'tags' @> jsonb_build_array($1::json) OR memo.payload->'tags'::text LIKE $2) OR (memo.payload->'tags' @> jsonb_build_array($3::json) OR memo.payload->'tags'::text LIKE $4))",
want: "((memo.payload->'tags' @> jsonb_build_array($1::json) OR memo.payload->'tags'::text LIKE $2::text) OR (memo.payload->'tags' @> jsonb_build_array($3::json) OR memo.payload->'tags'::text LIKE $4::text))",
args: []any{`"tag1"`, `%"tag1/%`, `"tag2"`, `%"tag2/%`},
},
{
filter: `!(tag in ["tag1", "tag2"])`,
want: "NOT (((memo.payload->'tags' @> jsonb_build_array($1::json) OR memo.payload->'tags'::text LIKE $2) OR (memo.payload->'tags' @> jsonb_build_array($3::json) OR memo.payload->'tags'::text LIKE $4)))",
want: "NOT (((memo.payload->'tags' @> jsonb_build_array($1::json) OR memo.payload->'tags'::text LIKE $2::text) OR (memo.payload->'tags' @> jsonb_build_array($3::json) OR memo.payload->'tags'::text LIKE $4::text)))",
args: []any{`"tag1"`, `%"tag1/%`, `"tag2"`, `%"tag2/%`},
},
{
......@@ -43,7 +43,7 @@ func TestConvertExprToSQL(t *testing.T) {
},
{
filter: `tag in ['tag1'] || content.contains('hello')`,
want: "((memo.payload->'tags' @> jsonb_build_array($1::json) OR memo.payload->'tags'::text LIKE $2) OR memo.content ILIKE $3)",
want: "((memo.payload->'tags' @> jsonb_build_array($1::json) OR memo.payload->'tags'::text LIKE $2::text) OR memo.content ILIKE $3)",
args: []any{`"tag1"`, `%"tag1/%`, "%hello%"},
},
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment