The ? (exists) operator crashes the server (SIGSEGV) on an agtype-null left operand
- Dominant language
- C
- Stars
- 4.8k
- Forks
- 523
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 9
Description
**AGE Version:** apache/age master @ cfd3b634 (2026-08-14), extension 1.8.0, on PostgreSQL 18.6
**Installation Method:** Docker
**API:** SQL (psql)
### Steps to reproduce
1. On a fresh database, load the extension and run (no data required):
```sql
LOAD 'age';
SET search_path = ag_catalog, public;
SELECT 'null'::agtype ? '"a"'::agtype AS r;
```
The second form `SELECT 'null'::agtype ? 'null'::agtype;` crashes identically.
### Expected behavior
The `?` operator tests top-level key/element existence; for a non-entity left operand it should return `false` or raise a clean client-side error. Its siblings already behave correctly for the same input:
```
SELECT 'null'::agtype ?| '["a"]'::agtype; -- ERROR: scalar object must be a vertex or edge
SELECT 'null'::agtype ?& '["a"]'::agtype; -- ERROR: scalar object must be a vertex or edge
```
Other scalar left operands of `?` also work: `'1'`, `'true'`, `'1.5'`, `'"s"'`, `'{}'`, `'[]'` all return `f` without error.
### Actual behavior
The client connection drops and the whole PostgreSQL instance restarts (all backends are terminated):
```
psql: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
psql: error: connection to server was lost
```
Server log (docker logs):
```
LOG: client backend (PID 9073) was terminated by signal 11: Segmentation fault
LOG: all server processes terminated; reinitializing
```
Root cause: in `agtype_exists_agtype` (`src/backend/utils/adt/agtype_ops.c:1325`), for a scalar-rooted input the code calls `extract_entity_properties(agt, false)`, which returns `NULL` when the scalar is `AGTV_NULL` (`agtype.c:12432-12434`); the result is then passed to `agtype_value_to_agtype()`, which dereferences the NULL pointer.
Not reachable from Cypher: a Cypher `NULL` is normalized to SQL NULL and the strict `?` function short-circuits before entering the C code (verified). The trigger surface is AGE's public SQL API — any user able to run SQL with the extension loaded can crash the shared instance.
Contributor guide
Research direction
Start with agtype_exists_agtype in src/backend/utils/adt/agtype_ops.c around line 1325, then read extract_entity_properties in agtype.c around lines 12432-12434 and reproduce the SQL queries from the issue in PostgreSQL. Done means the agtype-null left operand no longer causes SIGSEGV or a server restart, while the operator returns false or a clean client-side error; verify the sibling operators remain correct.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, postgresql
- Domain
- backend-api-design, databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100