Hi,

On an assertion-enabled build, `pg_restore_extended_stats()` triggers an assertion failure in check_all_expr_argnames_valid() when an expression statistics object contains an unknown JSON key with an array value

```
CREATE TABLE t (i INT);
CREATE STATISTICS t_stats ON (i + 1) FROM t;
SELECT pg_catalog.pg_restore_extended_stats(
    'schemaname', 'public',
    'relname', 't',
    'statistics_schemaname', 'public',
    'statistics_name', 't_stats',
    'inherited', false,
    'exprs', '[{"unknown": []}]'::jsonb
);

server closed the connection unexpectedly
    This probably means the server terminated abnormally
    before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
The connection to the server was lost. Attempting reset: Failed.
```

Logs
```
[506971] WARNING:  argument "exprs" has type text, expected type jsonb
TRAP: failed Assert("jitok == WJB_VALUE"), File: "extended_stats_funcs.c", Line: 950, PID: 506971 postgres: postgres postgres [local] SELECT(ExceptionalCondition+0x6f) [0x5bf2098a799f] postgres: postgres postgres [local] SELECT(pg_restore_extended_stats+0x2180) [0x5bf2096d5390]
postgres: postgres postgres [local] SELECT(+0x3a50d0) [0x5bf2095110d0]
postgres: postgres postgres [local] SELECT(+0x3e581a) [0x5bf20955181a]
postgres: postgres postgres [local] SELECT(standard_ExecutorRun+0x18a) [0x5bf2095155ea]
postgres: postgres postgres [local] SELECT(+0x5ca6f8) [0x5bf2097366f8]
postgres: postgres postgres [local] SELECT(PortalRun+0x24e) [0x5bf20973812e]
postgres: postgres postgres [local] SELECT(+0x5c7837) [0x5bf209733837]
postgres: postgres postgres [local] SELECT(PostgresMain+0x17d3) [0x5bf2097354a3] postgres: postgres postgres [local] SELECT(BackendMain+0x53) [0x5bf20972f143] postgres: postgres postgres [local] SELECT(postmaster_child_launch+0x103) [0x5bf209669bb3]
postgres: postgres postgres [local] SELECT(+0x501924) [0x5bf20966d924]
postgres: postgres postgres [local] SELECT(PostmasterMain+0xd6b) [0x5bf20966f45b]
postgres: postgres postgres [local] SELECT(main+0x1d8) [0x5bf2092febb8]
/usr/lib/x86_64-linux-gnu/libc.so.6(+0x2a601) [0x7adbd022a601]
/usr/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x88) [0x7adbd022a718]
postgres: postgres postgres [local] SELECT(_start+0x25) [0x5bf2092fef25]
[506931] LOG:  client backend (PID 506971) was terminated by signal 6: Aborted [506931] DETAIL:  Failed process was running: SELECT pg_catalog.pg_restore_extended_stats(
       'schemaname', 'public',
       'relname', 'test_expr_stats',
       'statistics_schemaname', 'public',
       'statistics_name', 'test_expr_stats_s',
       'inherited', false,
       'exprs', '[{"unknown": []}]'::jsonb
   );
```


The fix passes skipNested = true when reading a value. This function only validates the keys of the outer object, so it should consume each value as a single WJB_VALUE token rather than descend into nested containers.

Does anyone see any issues with this fix, or suggest a different approach?

--
Best regards,
Ilia Evdokimov,
Tantor Labs LLC,
https://tantorlabs.com/
From 7e853d530b902621c8e307609627361e80a9617f Mon Sep 17 00:00:00 2001
From: Evdokimov Ilia <[email protected]>
Date: Mon, 2 Nov 2026 22:12:10 +0300
Subject: [PATCH v1] Fix iteration over nested JSON values in expression
 statistics import

---
 src/backend/statistics/extended_stats_funcs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/backend/statistics/extended_stats_funcs.c b/src/backend/statistics/extended_stats_funcs.c
index 00b8dbe3366..ee7099e6b80 100644
--- a/src/backend/statistics/extended_stats_funcs.c
+++ b/src/backend/statistics/extended_stats_funcs.c
@@ -946,7 +946,7 @@ check_all_expr_argnames_valid(JsonbContainer *cont, AttrNumber exprnum)
 		Assert(jkey.type == jbvString);
 
 		/* A value must follow the key */
-		jitok = JsonbIteratorNext(&jbit, &jval, false);
+		jitok = JsonbIteratorNext(&jbit, &jval, true);
 		Assert(jitok == WJB_VALUE);
 
 		/*
-- 
2.53.0

Reply via email to