Skip to content
Open
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
9 changes: 9 additions & 0 deletions internal/store/postgres/org_tokens_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"fmt"
"strings"

"github.com/doug-martin/goqu/v9"
"github.com/jmoiron/sqlx"
Expand Down Expand Up @@ -166,6 +167,14 @@ func (r OrgTokensRepository) addFilter(query *goqu.SelectDataset, filter rql.Fil
case "like", "notlike":
value := "%" + filter.Value.(string) + "%"
return query.Where(goqu.Ex{field: goqu.Op{filter.Operator: value}}), nil
case "in", "notin":
values := make([]string, 0)
for _, v := range strings.Split(filter.Value.(string), ",") {
if trimmed := strings.TrimSpace(v); trimmed != "" {
values = append(values, trimmed)
}
}
return query.Where(goqu.Ex{field: goqu.Op{filter.Operator: values}}), nil
Comment on lines +170 to +177
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

goqu v9 In with string slice on integer column prepared statement postgres operator does not exist integer = text

💡 Result:

Root cause: you’re generating a SQL comparison where Postgres sees an integer column on one side and a text/varchar parameter on the other. In Postgres this triggers “operator does not exist: integer = text” (same pattern as integer vs text/varying errors) because there is no matching operator for those types without an explicit cast.[1][2] In goqu v9, build an IN clause using a slice whose element type matches the integer column type (e.g., []int64). goqu will render "col" IN (...) with those values.[3] What to do 1) Pass integer-typed slice values - Good: goqu.Ex{"id": []int64{1, 2, 3}}. - Bad: goqu.Ex{"id": []string{"1","2"}} (produces text parameters, leading to integer-vs-text operator errors at execution time).[1][2] 2) If your values are strings, convert them before building the query - Convert []string -> []int64 (e.g., with strconv.ParseInt) and pass the resulting []int64 slice to goqu. 3) If you can’t change the types, cast explicitly in SQL - goqu supports raw SQL fragments via goqu.L(...), which is commonly used when you need explicit casts.[4] Example (working shape) - goqu.Dialect("postgres").From("test").Where(goqu.Ex{"baz": []int64{1,2,3}}) produces ("baz" IN (1, 2, 3)), and in prepared mode it uses $1..$N placeholders with args of the right integer type.[3] If you paste your exact goqu snippet (how you build the slice and which column you target), I can rewrite it into the correct v9 code for your case.

Citations:


Restore a type-safe cast for in/notin on integer amount filters

The current refactor builds values as strings and generates amount IN ($1, $2)-style comparisons without casting, which in Postgres commonly fails with operator does not exist: integer = text when the column is integer and the bound parameters are text. This aligns with why addSearch casts columns (including amount) to TEXT.

🛠️ Proposed fix restoring the TEXT cast
 	case "in", "notin":
 		values := make([]string, 0)
 		for _, v := range strings.Split(filter.Value.(string), ",") {
 			if trimmed := strings.TrimSpace(v); trimmed != "" {
 				values = append(values, trimmed)
 			}
 		}
-		return query.Where(goqu.Ex{field: goqu.Op{filter.Operator: values}}), nil
+		castField := goqu.Cast(goqu.I(field), "TEXT")
+		if filter.Operator == "in" {
+			return query.Where(castField.In(values)), nil
+		}
+		return query.Where(castField.NotIn(values)), nil

default:
return query.Where(goqu.Ex{field: goqu.Op{filter.Operator: filter.Value}}), nil
}
Expand Down
Loading