@@ -125,6 +125,20 @@ func (c *Converter) convertFilter(filter map[string]any, paramIndex int) (string
125125 conditions = append (conditions , strings .Join (inner , " " + op + " " ))
126126 }
127127 }
128+ case "$not" :
129+ vv , ok := value .(map [string ]any )
130+ if ! ok {
131+ return "" , nil , fmt .Errorf ("invalid value for $not operator (must be object): %v" , value )
132+ }
133+ innerConditions , innerValues , err := c .convertFilter (vv , paramIndex )
134+ if err != nil {
135+ return "" , nil , err
136+ }
137+ paramIndex += len (innerValues )
138+ // Just putting a NOT around the condition is not enough, a non existing jsonb field will for example
139+ // make the whole inner condition NULL. And NOT NULL is still a falsy value, so we need to check for NULL explicitly.
140+ conditions = append (conditions , fmt .Sprintf ("(NOT COALESCE(%s, FALSE))" , innerConditions ))
141+ values = append (values , innerValues ... )
128142 default :
129143 if ! isValidPostgresIdentifier (key ) {
130144 return "" , nil , fmt .Errorf ("invalid column name: %s" , key )
@@ -148,6 +162,8 @@ func (c *Converter) convertFilter(filter map[string]any, paramIndex int) (string
148162 return "" , nil , fmt .Errorf ("$or as scalar operator not supported" )
149163 case "$and" :
150164 return "" , nil , fmt .Errorf ("$and as scalar operator not supported" )
165+ case "$not" :
166+ return "" , nil , fmt .Errorf ("$not as scalar operator not supported" )
151167 case "$in" :
152168 if ! isScalarSlice (v [operator ]) {
153169 return "" , nil , fmt .Errorf ("invalid value for $in operator (must array of primatives): %v" , v [operator ])
0 commit comments