Skip to content

Correctly cast and handle nulls for order ops #113

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 1 commit into from
May 29, 2025
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
12 changes: 12 additions & 0 deletions src/encrypted/casts.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
CREATE FUNCTION eql_v2.to_encrypted(data jsonb)
RETURNS public.eql_v2_encrypted AS $$
BEGIN
IF data IS NULL THEN
RETURN NULL;
END IF;

RETURN ROW(data)::public.eql_v2_encrypted;
END;
$$ LANGUAGE plpgsql;
Expand All @@ -28,6 +32,10 @@ CREATE CAST (jsonb AS public.eql_v2_encrypted)
CREATE FUNCTION eql_v2.to_encrypted(data text)
RETURNS public.eql_v2_encrypted AS $$
BEGIN
IF data IS NULL THEN
RETURN NULL;
END IF;

RETURN ROW(data::jsonb)::public.eql_v2_encrypted;
END;
$$ LANGUAGE plpgsql;
Expand All @@ -48,6 +56,10 @@ CREATE CAST (text AS public.eql_v2_encrypted)
CREATE FUNCTION eql_v2.to_jsonb(e public.eql_v2_encrypted)
RETURNS jsonb AS $$
BEGIN
IF e IS NULL THEN
RETURN NULL;
END IF;

RETURN e.data;
END;
$$ LANGUAGE plpgsql;
Expand Down
12 changes: 12 additions & 0 deletions src/operators/operator_class.sql
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ AS $$
a_ore := eql_v2.ore_block_u64_8_256(a);
b_ore := eql_v2.ore_block_u64_8_256(b);

IF a_ore IS NULL AND b_ore IS NULL THEN
RETURN 0;
END IF;

IF a_ore IS NULL THEN
RETURN -1;
END IF;

IF b_ore IS NULL THEN
RETURN 1;
END IF;

RETURN eql_v2.compare_ore_array(a_ore.terms, b_ore.terms);
END;
$$ LANGUAGE plpgsql;
Expand Down
74 changes: 73 additions & 1 deletion src/operators/order_by_test.sql
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,76 @@ DECLARE
'43');

END;
$$ LANGUAGE plpgsql;
$$ LANGUAGE plpgsql;


SELECT create_table_with_encrypted();

--
-- ORE - ORDER BY NULL handling
--
DO $$
DECLARE
e eql_v2_encrypted;
ore_term eql_v2_encrypted;
BEGIN

-- Insert records with NULL values
-- record with ID=1 and e=NULL
INSERT INTO encrypted(e) VALUES (NULL::jsonb::eql_v2_encrypted);


-- Pull records from the ore table and insert
SELECT ore.e FROM ore WHERE id = 42 INTO ore_term;
-- record with ID=2 and e=42
INSERT INTO encrypted(e) VALUES (ore_term);


SELECT ore.e FROM ore WHERE id = 3 INTO ore_term;
-- record with ID=3 and e=3
INSERT INTO encrypted(e) VALUES (ore_term);


-- record with ID=4 and e=NULL
INSERT INTO encrypted(e) VALUES (NULL::jsonb::eql_v2_encrypted);

PERFORM assert_result(
'ORDER BY encrypted',
format('SELECT id FROM encrypted ORDER BY e'),
'3');

PERFORM assert_result(
'ORDER BY encrypted ASC',
format('SELECT id FROM encrypted ORDER BY e ASC'),
'3');

PERFORM assert_result(
'ORDER BY eql_v2.order_by(e) ASC NULLS FIRST',
format('SELECT id FROM encrypted ORDER BY e ASC NULLS FIRST'),
'1');

PERFORM assert_result(
'ORDER BY eql_v2.order_by(e) ASC NULLS LAST',
format('SELECT id FROM encrypted ORDER BY e ASC NULLS LAST'),
'3');

-- NULLS FIRST when DESC
PERFORM assert_result(
'ORDER BY encrypted DESC',
format('SELECT id FROM encrypted ORDER BY e DESC'),
'1');

PERFORM assert_result(
'ORDER BY eql_v2.order_by(e) DESC NULLS FIRST',
format('SELECT id FROM encrypted ORDER BY e DESC NULLS FIRST'),
'1');

PERFORM assert_result(
'ORDER BY eql_v2.order_by(e) DESC NULLS LAST',
format('SELECT id FROM encrypted ORDER BY e DESC NULLS LAST'),
'2');

END;
$$ LANGUAGE plpgsql;

PERFORM drop_table_with_encrypted();
4 changes: 4 additions & 0 deletions src/ore_block_u64_8_256/functions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ CREATE FUNCTION eql_v2.ore_block_u64_8_256(val jsonb)
IMMUTABLE STRICT PARALLEL SAFE
AS $$
BEGIN
IF val IS NULL THEN
RETURN NULL;
END IF;

IF val ? 'ob' THEN
RETURN eql_v2.jsonb_array_to_ore_block_u64_8_256(val->'ob');
END IF;
Expand Down
Loading