Skip to content
Merged
Show file tree
Hide file tree
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
53 changes: 53 additions & 0 deletions packages/core/postgrest-js/src/PostgrestFilterBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type FilterOperator =
| 'like'
| 'ilike'
| 'is'
| 'isdistinct'
| 'in'
| 'cs'
| 'cd'
Expand All @@ -25,6 +26,8 @@ type FilterOperator =
| 'plfts'
| 'phfts'
| 'wfts'
| 'match'
| 'imatch'

export type IsStringOperator<Path extends string> = Path extends `${string}->>${string}`
? true
Expand Down Expand Up @@ -273,6 +276,34 @@ export default class PostgrestFilterBuilder<
return this
}

regexMatch<ColumnName extends string & keyof Row>(column: ColumnName, pattern: string): this
regexMatch(column: string, pattern: string): this
/**
* Match only rows where `column` matches the PostgreSQL regex `pattern`
* case-sensitively (using the `~` operator).
*
* @param column - The column to filter on
* @param pattern - The PostgreSQL regular expression pattern to match with
*/
regexMatch(column: string, pattern: string): this {
this.url.searchParams.append(column, `match.${pattern}`)
return this
}

regexIMatch<ColumnName extends string & keyof Row>(column: ColumnName, pattern: string): this
regexIMatch(column: string, pattern: string): this
/**
* Match only rows where `column` matches the PostgreSQL regex `pattern`
* case-insensitively (using the `~*` operator).
*
* @param column - The column to filter on
* @param pattern - The PostgreSQL regular expression pattern to match with
*/
regexIMatch(column: string, pattern: string): this {
this.url.searchParams.append(column, `imatch.${pattern}`)
return this
}

is<ColumnName extends string & keyof Row>(
column: ColumnName,
value: Row[ColumnName] & (boolean | null)
Expand All @@ -295,6 +326,28 @@ export default class PostgrestFilterBuilder<
return this
}

/**
* Match only rows where `column` IS DISTINCT FROM `value`.
*
* Unlike `.neq()`, this treats `NULL` as a comparable value. Two `NULL` values
* are considered equal (not distinct), and comparing `NULL` with any non-NULL
* value returns true (distinct).
*
* @param column - The column to filter on
* @param value - The value to filter with
*/
isDistinct<ColumnName extends string>(
column: ColumnName,
value: ResolveFilterValue<Schema, Row, ColumnName> extends never
? unknown
: ResolveFilterValue<Schema, Row, ColumnName> extends infer ResolvedFilterValue
? ResolvedFilterValue
: never
): this {
this.url.searchParams.append(column, `isdistinct.${value}`)
return this
}

/**
* Match only rows where `column` is included in the `values` array.
*
Expand Down
51 changes: 51 additions & 0 deletions packages/core/postgrest-js/test/filters.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -778,3 +778,54 @@ test('filter on rpc', async () => {
}
`)
})

test('isDistinct', async () => {
const res = await postgrest.from('users').select('username').isDistinct('status', 'ONLINE')
expect(res).toMatchInlineSnapshot(`
{
"count": null,
"data": [
{
"username": "kiwicopple",
},
],
"error": null,
"status": 200,
"statusText": "OK",
}
`)
})

test('regexMatch', async () => {
const res = await postgrest.from('users').select('username').regexMatch('username', '^sup')
expect(res).toMatchInlineSnapshot(`
{
"count": null,
"data": [
{
"username": "supabot",
},
],
"error": null,
"status": 200,
"statusText": "OK",
}
`)
})

test('regexIMatch', async () => {
const res = await postgrest.from('users').select('username').regexIMatch('username', '^SUP')
expect(res).toMatchInlineSnapshot(`
{
"count": null,
"data": [
{
"username": "supabot",
},
],
"error": null,
"status": 200,
"statusText": "OK",
}
`)
})
Loading