-
Notifications
You must be signed in to change notification settings - Fork 0
Enhance functions for operator-free environments like Supabase #103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
eddaece
feat: order_by function to remove need to wrap as ore
tobyhede 9c8b996
chore:
tobyhede 85f9c12
docs: document working without operators for supabase
tobyhede a53446f
fix: Drop test table
tobyhede 8fa121c
docs: Link to GitHub issue tracking Supabase support for custom opera…
auxesis 0118d07
docs: be more specific about how EQL is organised
auxesis 8060626
docs: highlight technical terms
auxesis b8a2fd8
docs: make it clearer that the following example demonstrates how to …
auxesis d1cb685
docs: syntax highlight SQL code blocks
auxesis 439f1cb
docs: line per sentence, to improve maintainability
auxesis 4c4a0b1
docs: highlight technical terms
auxesis 26c7377
docs: link to supporting documentation
auxesis 60b848e
docs: reword for clarity
auxesis 1505695
build: ensure all SQL files trigger tests
auxesis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# Supabase | ||
|
||
|
||
## No operators, no problems | ||
|
||
Supabase does not support custom operators. | ||
The EQL operator functions can be used in this situation. | ||
|
||
PostgreSQL operators are essentially an alias for the equivalent function, so the implementation and behaviour remains the same. | ||
auxesis marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
| Operator | Function | Example | | ||
| -------- | -------------------------------------------------- | ----------------------------------------------------------------- | | ||
| `=` | `eql_v1.eq(eql_v1_encrypted, eql_v1_encrypted)` | `SELECT * FROM users WHERE eql_v1.eq(encrypted_email, $1)`<br> | | ||
| `<>` | `eql_v1.neq(eql_v1_encrypted, eql_v1_encrypted)` | `SELECT * FROM users WHERE eql_v1.neq(encrypted_email, $1)`<br> | | ||
| `<` | `eql_v1.lt(eql_v1_encrypted, eql_v1_encrypted)` | `SELECT * FROM users WHERE eql_v1.lt(encrypted_email, $1)`<br> | | ||
| `<=` | `eql_v1.lte(eql_v1_encrypted, eql_v1_encrypted)` | `SELECT * FROM users WHERE eql_v1.lte(encrypted_email, $1)`<br> | | ||
| `>` | `eql_v1.gt(eql_v1_encrypted, eql_v1_encrypted)` | `SELECT * FROM users WHERE eql_v1.gt(encrypted_email, $1)`<br> | | ||
| `>=` | `eql_v1.gte(eql_v1_encrypted, eql_v1_encrypted)` | `SELECT * FROM users WHERE eql_v1.gte(encrypted_email, $1)`<br> | | ||
| `~~` | `eql_v1.like(eql_v1_encrypted, eql_v1_encrypted)` | `SELECT * FROM users WHERE eql_v1.like(encrypted_email, $1)`<br> | | ||
| `~~*` | `eql_v1.ilike(eql_v1_encrypted, eql_v1_encrypted)` | `SELECT * FROM users WHERE eql_v1.ilike(encrypted_email, $1)`<br> | | ||
| `LIKE` | `eql_v1.like(eql_v1_encrypted, eql_v1_encrypted)` | `SELECT * FROM users WHERE eql_v1.like(encrypted_email, $1)`<br> | | ||
| `ILIKE` | `eql_v1.ilike(eql_v1_encrypted, eql_v1_encrypted)` | `SELECT * FROM users WHERE eql_v1.ilike(encrypted_email, $1)`<br> | | ||
|
||
### Example SQL Statements | ||
|
||
#### Equality `=` | ||
|
||
|
||
**Operator** | ||
``` | ||
SELECT * FROM users WHERE encrypted_email = $1 | ||
``` | ||
|
||
**Function** | ||
``` | ||
SELECT * FROM users WHERE eql_v1.eq(encrypted_email, $1) | ||
``` | ||
|
||
|
||
#### Like & ILIKE `~~, ~~*` | ||
|
||
|
||
**Operator** | ||
``` | ||
SELECT * FROM users WHERE encrypted_email LIKE $1 | ||
``` | ||
|
||
**Function** | ||
``` | ||
SELECT * FROM users WHERE eql_v1.like(encrypted_email, $1) | ||
``` | ||
|
||
#### Case Sensitivity | ||
|
||
The EQL `eql_v1.like` and `eql_v1.ilike` functions are equivalent. | ||
|
||
The behaviour of the "match" index term that is used by the encrypted `LIKE` operators is slightly different to default PostgreSQL. Case sensitivity is determined by the index term configuration. A match index term can be configured to enable case sensitive searches. The data is encrypted based on the configuration. The like operation is always the same, and the data is different. The different operators are kept to preserve the semantics of SQL statements in client applications. | ||
auxesis marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
|
||
### Order By | ||
auxesis marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Ordering requires wrapping the ordered column in the `eql_v1.order_by` function. | ||
auxesis marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
``` | ||
SELECT * FROM users ORDER BY eql_v1.order_by(encrypted_created_at) DESC | ||
``` | ||
|
||
PostgreSQL uses operators when handling `ORDER BY` operations. The `eql_v1.order_by` function behaves in | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
-- REQUIRE: src/encrypted/types.sql | ||
-- REQUIRE: src/ore/types.sql | ||
-- REQUIRE: src/ore/functions.sql | ||
-- REQUIRE: src/ore/operators.sql | ||
-- REQUIRE: src/ore_cllw_u64_8/types.sql | ||
-- REQUIRE: src/ore_cllw_u64_8/functions.sql | ||
-- REQUIRE: src/ore_cllw_u64_8/operators.sql | ||
|
||
-- order_by function for ordering when operators are not available. | ||
-- | ||
-- There are multiple index terms that provide equality comparisons | ||
-- - ore_cllw_u64_8 | ||
-- - ore_cllw_var_8 | ||
-- - ore_64_8_v1 | ||
-- | ||
-- We check these index terms in this order and use the first one that exists for both parameters | ||
-- | ||
-- | ||
|
||
-- DROP FUNCTION IF EXISTS eql_v1.order_by(a eql_v1_encrypted, b eql_v1_encrypted); | ||
|
||
CREATE FUNCTION eql_v1.order_by(a eql_v1_encrypted) | ||
RETURNS eql_v1.ore_64_8_v1 | ||
IMMUTABLE STRICT PARALLEL SAFE | ||
AS $$ | ||
BEGIN | ||
BEGIN | ||
RETURN eql_v1.ore_64_8_v1(a); | ||
EXCEPTION WHEN OTHERS THEN | ||
-- PERFORM eql_v1.log('No ore_64_8_v1 index'); | ||
END; | ||
|
||
RETURN false; | ||
END; | ||
$$ LANGUAGE plpgsql; | ||
|
||
-- TODO: make this work | ||
-- fails with jsonb format issue, which I think is due to the type casting | ||
-- | ||
CREATE FUNCTION eql_v1.order_by_any(a anyelement) | ||
RETURNS anyelement | ||
IMMUTABLE STRICT PARALLEL SAFE | ||
AS $$ | ||
DECLARE | ||
e eql_v1_encrypted; | ||
result ALIAS FOR $0; | ||
BEGIN | ||
|
||
e := a::eql_v1_encrypted; | ||
|
||
BEGIN | ||
result := eql_v1.ore_cllw_u64_8(e); | ||
EXCEPTION WHEN OTHERS THEN | ||
-- PERFORM eql_v1.log('No ore_cllw_u64_8 index'); | ||
END; | ||
|
||
BEGIN | ||
result := eql_v1.ore_cllw_var_8(e); | ||
EXCEPTION WHEN OTHERS THEN | ||
-- PERFORM eql_v1.log('No ore_cllw_u64_8 index'); | ||
END; | ||
|
||
BEGIN | ||
result := eql_v1.ore_64_8_v1(e); | ||
EXCEPTION WHEN OTHERS THEN | ||
-- PERFORM eql_v1.log('No ore_64_8_v1 index'); | ||
END; | ||
|
||
RETURN result; | ||
END; | ||
$$ LANGUAGE plpgsql; | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
\set ON_ERROR_STOP on | ||
|
||
-- | ||
-- ORE - ORDER BY ore_64_8_v1(eql_v1_encrypted) | ||
-- | ||
DO $$ | ||
DECLARE | ||
e eql_v1_encrypted; | ||
ore_term eql_v1_encrypted; | ||
BEGIN | ||
SELECT ore.e FROM ore WHERE id = 42 INTO ore_term; | ||
|
||
PERFORM assert_count( | ||
'ORDER BY eql_v1.order_by(e) DESC', | ||
format('SELECT id FROM ore WHERE e < %L ORDER BY eql_v1.order_by(e) DESC', ore_term), | ||
41); | ||
|
||
PERFORM assert_result( | ||
'ORDER BY eql_v1.order_by(e) DESC returns correct record', | ||
format('SELECT id FROM ore WHERE e < %L ORDER BY eql_v1.order_by(e) DESC LIMIT 1', ore_term), | ||
'41'); | ||
|
||
PERFORM assert_result( | ||
'ORDER BY eql_v1.order_by(e) ASC', | ||
format('SELECT id FROM ore WHERE e < %L ORDER BY eql_v1.order_by(e) ASC LIMIT 1', ore_term), | ||
'1'); | ||
END; | ||
$$ LANGUAGE plpgsql; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.