apache / apache/age

age_to*list functions crash the server (SIGSEGV) on array-shaped SQL literals

Open
#2,563 0 comments 0 reactions 0 assignees View on GitHub
bug
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, run (no data required):

```sql
LOAD 'age';
SET search_path = ag_catalog, public;
SELECT ag_catalog.age_tobooleanlist('[true]');
```

All four `age_to*list` functions crash deterministically on array-shaped literal arguments (12 shapes verified):

| Statement | Result |
|---|---|
| `age_tobooleanlist('[true]')`, `('[null]')`, `('[true, null, false]')` | SIGSEGV |
| `age_tofloatlist('[true]')`, `('[1]')`, `('[null]')` | SIGSEGV |
| `age_tointegerlist('[true]')`, `('[null]')` | SIGSEGV |
| `age_tostringlist('[true]')`, `('[null]')`, `('[1, null, "a"]')` | SIGSEGV |

Other array shapes (`'[1]'`, `'["a"]'`, `'[1.5]'` for the mismatched functions) give a bogus `ERROR: toBooleanList() argument must resolve to a list or null` instead — same root cause, non-crashing bit pattern.

### Expected behavior

The Cypher equivalents work correctly and define the expected behavior:

```sql
SELECT * FROM cypher('g', $$ RETURN toBooleanList([true]) $$) AS (r agtype);
-- r = [true]
```

The SQL form should either return the same result or raise a clean error; it must never crash the backend.

### Actual behavior

```
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 14030) was terminated by signal 11: Segmentation fault
LOG: all server processes terminated; reinitializing
```

Root cause (in `src/backend/utils/adt/agtype.c`): type confusion at the SQL boundary. For `VARIADIC "any"` functions, PostgreSQL resolves an unknown-type literal to `text` (verified with the same-signature builtin `json_build_array('[true]')` → `["[true]"]`), i.e. the function receives a `text[]` (ArrayType) datum, not agtype. The C functions read the argument with `AG_GET_ARG_AGTYPE_P(0)` without ever checking `get_fn_expr_argtype()`, so the `text[]` datum is reinterpreted as an agtype container. Depending on the literal's byte pattern the garbage either passes the `AGT_ROOT_IS_ARRAY` root check and crashes while iterating elements (the 12 shapes above), or fails it and produces the bogus `argument must resolve to a list or null` error (`'[1]'`, `'["a"]'`, `'[1.5]'`). Passing an explicit `::agtype` cast works correctly — `age_tobooleanlist('[true]'::agtype)` returns `[true]` — and the explicit `VARIADIC ARRAY[...]` form hits the same reinterpretation. `EXPLAIN (VERBOSE)` of a crashing call also crashes the backend.

Cypher is safe: literal lists are built through `agtype_build_list` (null elements get real value slots) and the transform passes a typed agtype expression, so the C code never sees a text[]; the PREPARE/EXECUTE parameter path was verified safe as well. Trigger surface = AGE's public SQL API (shared-instance DoS, same class as the `?` crash).

Contributor guide

Open the contributing guide

Research direction

Start in src/backend/utils/adt/agtype.c, at the age_to*list functions and their AG_GET_ARG_AGTYPE_P argument handling; compare the received argument type with get_fn_expr_argtype(). Run the listed SQL reproducer, including the explicit ::agtype form. Done means array-shaped literals no longer crash the PostgreSQL backend and either return the expected list or raise a clean error.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, postgresql
Domain
backend-api-design, databases, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.