Skip to content

Commit

Permalink
Support comparing to null (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
erikdubbelboer authored Jun 15, 2024
1 parent f62bc77 commit e530fd8
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 3 deletions.
15 changes: 15 additions & 0 deletions filter/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,21 @@ func (c *Converter) convertFilter(filter map[string]any, paramIndex int) (string
innerResult = "(" + innerResult + ")"
}
conditions = append(conditions, innerResult)
case nil:
// Comparing a column to NULL needs a different implementation depending on if the column is in JSONB or not.
// JSONB columns are NULL even if they don't exist, so we need to check if the column exists first.
isNestedColumn := c.nestedColumn != ""
for _, exemption := range c.nestedExemptions {
if exemption == key {
isNestedColumn = false
break
}
}
if isNestedColumn {
conditions = append(conditions, fmt.Sprintf("(jsonb_path_match(%s, 'exists($.%s)') AND %s IS NULL)", c.nestedColumn, key, c.columnName(key)))
} else {
conditions = append(conditions, fmt.Sprintf("(%s IS NULL)", c.columnName(key)))
}
default:
if !isScalar(value) {
return "", nil, fmt.Errorf("invalid comparison value (must be a primitive): %v", value)
Expand Down
24 changes: 24 additions & 0 deletions filter/converter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,30 @@ func TestConverter_Convert(t *testing.T) {
nil,
fmt.Errorf("invalid comparison value (must be a primitive): [200 300]"),
},
{
"sql injection",
nil,
`{"\"bla = 1 --": 1}`,
``,
nil,
fmt.Errorf("invalid column name: \"bla = 1 --"),
},
{
"null nornal column",
nil,
`{"name": null}`,
`("name" IS NULL)`,
nil,
nil,
},
{
"null jsonb column",
filter.WithNestedJSONB("meta"),
`{"name": null}`,
`(jsonb_path_match(meta, 'exists($.name)') AND "meta"->>'name' IS NULL)`,
nil,
nil,
},
}

for _, tt := range tests {
Expand Down
1 change: 1 addition & 0 deletions fuzz/fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func FuzzConverter(f *testing.F) {
`{"\"bla = 1 --": 1}`,
`{"$not": {"name": "John"}}`,
`{"name": {"$not": {"$eq": "John"}}}`,
`{"name": null}`,
}
for _, tc := range tcs {
f.Add(tc, true)
Expand Down
12 changes: 9 additions & 3 deletions integration/postgres_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,15 @@ func TestIntegration_BasicOperators(t *testing.T) {
nil,
},
{
"$gt with jsonb column",
`{"guild_id": { "$gt": 40 }}`,
[]int{7, 8, 9, 10},
`column equal to null`,
`{"mount": null}`,
[]int{3, 4},
nil,
},
{
`jsonb equal to null`,
`{"pet": null}`,
[]int{10},
nil,
},
}
Expand Down

0 comments on commit e530fd8

Please sign in to comment.