From 929bc3c5b4f37682585a383aab114af15e515a0a Mon Sep 17 00:00:00 2001 From: Akash Kumar <116457960+akashchamp@users.noreply.github.com> Date: Thu, 8 Oct 2026 00:58:46 +0530 Subject: [PATCH] Fix ? operator crash on an agtype null left operand For a scalar left operand, agtype_exists_agtype() passes the result of extract_entity_properties() straight to agtype_value_to_agtype(). For an agtype null (or an entity whose properties are null) that result is NULL, so the backend dereferences a NULL pointer and the postmaster restarts: SELECT 'null'::agtype ? '"a"'::agtype; Return false when there are no properties to search, the same answer the operator already gives for other non-container scalars such as '1' or '"s"'. Add regression cases to jsonb_operators. Fixes #2562 --- regress/expected/jsonb_operators.out | 12 ++++++++++++ regress/sql/jsonb_operators.sql | 2 ++ src/backend/utils/adt/agtype_ops.c | 10 +++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/regress/expected/jsonb_operators.out b/regress/expected/jsonb_operators.out index 8e2f7a20f..d7d9c18ec 100644 --- a/regress/expected/jsonb_operators.out +++ b/regress/expected/jsonb_operators.out @@ -189,6 +189,18 @@ SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::agtype ? '["e1" f (1 row) +SELECT 'null'::agtype ? '"a"'::agtype; + ?column? +---------- + f +(1 row) + +SELECT 'null'::agtype ? 'null'::agtype; + ?column? +---------- + f +(1 row) + -- errors out SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::agtype ? 'e1'; ERROR: invalid input syntax for type agtype diff --git a/regress/sql/jsonb_operators.sql b/regress/sql/jsonb_operators.sql index 7cf58acd5..86ca2e01a 100644 --- a/regress/sql/jsonb_operators.sql +++ b/regress/sql/jsonb_operators.sql @@ -60,6 +60,8 @@ SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::agtype ? '["n", SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::agtype ? '{"n": null}'; SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::agtype ? '{"n": null, "b": true}'; SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::agtype ? '["e1"]'; +SELECT 'null'::agtype ? '"a"'::agtype; +SELECT 'null'::agtype ? 'null'::agtype; -- errors out SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::agtype ? 'e1'; diff --git a/src/backend/utils/adt/agtype_ops.c b/src/backend/utils/adt/agtype_ops.c index f7f45b467..000f410d2 100644 --- a/src/backend/utils/adt/agtype_ops.c +++ b/src/backend/utils/adt/agtype_ops.c @@ -1322,7 +1322,15 @@ Datum agtype_exists_agtype(PG_FUNCTION_ARGS) if (AGT_ROOT_IS_SCALAR(agt)) { - agt = agtype_value_to_agtype(extract_entity_properties(agt, false)); + agtype_value *properties = extract_entity_properties(agt, false); + + /* an agtype null (or null properties) has no keys to look up */ + if (properties == NULL) + { + PG_RETURN_BOOL(false); + } + + agt = agtype_value_to_agtype(properties); } if (AGT_ROOT_IS_SCALAR(key))