Skip to content

Issue with .not() method handling 'in' operator #1326

Closed
@mnm89

Description

@mnm89

Bug report

  • I confirm this is a bug with Supabase, not with my own application.
  • I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

The .not() method is expected to handle the in operator with an array of values correctly, as per the documentation. If using .filter() works but .not() does not, this suggests there might be a bug or inconsistency in the library.

To Reproduce

const supabase = createClient(SUPABASE_URL, SUPABASE_KEY);

const application_id = 123;
const idsToKeep = ['dd0292b4-1e2a-4544-bc7c-a668ce74008a'];

let query = supabase.from("language_data").delete().eq("application_id", application_id);

// This fails with parsing error
query = query.not("id", "in", idsToKeep);

// This works as expected
query = query.filter("id", "not.in", `(${idsToKeep.join(",")})`);

const { data, error } = await query;
console.log({ data, error });

Expected behavior

.not("id", "in", idsToKeep) should work similarly to .filter("id", "not.in", ...)

Actual Behavior

  code: 'PGRST100',
  details: 'unexpected "d" expecting "("',
  hint: null,
  message: '"failed to parse filter (not.in.dd0292b4-1e2a-4544-bc7c-a668ce74008a)" (line 1, column 8)'

System information

  • OS: macOS
  • Version of supabase-js: 2.47.2
  • Version of Node.js: 20.10.0

Additional context

npm ls @supabase/supabase-js

 ├─┬ @supabase/[email protected]
   └ @supabase/[email protected] deduped
 └── @supabase/[email protected]

node_modules/@supabse/postgres-js/src/PostgrestFilterBuilder.ts

  not<ColumnName extends string & keyof Row>(
    column: ColumnName,
    operator: FilterOperator,
    value: Row[ColumnName]
  ): this
  not(column: string, operator: string, value: unknown): this
  /**
   * Match only rows which doesn't satisfy the filter.
   *
   * Unlike most filters, `opearator` and `value` are used as-is and need to
   * follow [PostgREST
   * syntax](https://postgrest.org/en/stable/api.html#operators). You also need
   * to make sure they are properly sanitized.
   *
   * @param column - The column to filter on
   * @param operator - The operator to be negated to filter with, following
   * PostgREST syntax
   * @param value - The value to filter with, following PostgREST syntax
   */
  not(column: string, operator: string, value: unknown): this {
    this.url.searchParams.append(column, `not.${operator}.${value}`)
    return this
  }

I thinks the .not(...) should handle the array type internally otherwise will not have any difference from the .filter(...).

// this works as well
query.not("id", "in", `(${idsToKeep.join(",")})`);

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions