Re: BUG #19491: Segmentation fault triggered by IS NULL
Ayush Tiwari <ayushtiwari.slg01@gmail.com>
From: Ayush Tiwari <ayushtiwari.slg01@gmail.com>
To: 798604270@qq.com, pgsql-bugs@lists.postgresql.org, Álvaro Herrera <alvherre@kurilemu.de>
Date: 2026-05-25T15:12:41Z
Lists: pgsql-bugs
Attachments
- v1-0001-Avoid-NULL-IS-JSON-expressions-after-failed-text-.patch (application/octet-stream) patch v1-0001
Hi,
On Mon, 25 May 2026 at 18:57, PG Bug reporting form <noreply@postgresql.org>
wrote:
> The following bug has been logged on the website:
>
> Bug reference: 19491
> Logged by: Chi Zhang
> Email address: 798604270@qq.com
> PostgreSQL version: 18.4
> Operating system: Ubuntu 24.04
> Description:
>
> Hi,
>
> I found that the following test case triggers a segmentation fault.
>
> ```
> CREATE SCHEMA IF NOT EXISTS poc;
>
> CREATE FUNCTION poc.mystring_in(cstring)
> RETURNS poc.mystring
> AS 'textin' LANGUAGE internal IMMUTABLE STRICT;
>
> CREATE FUNCTION poc.mystring_out(poc.mystring)
> RETURNS cstring
> AS 'textout' LANGUAGE internal IMMUTABLE STRICT;
>
> CREATE TYPE poc.mystring (
> INPUT = poc.mystring_in,
> OUTPUT = poc.mystring_out,
> LIKE = text,
> CATEGORY = 'S'
> );
>
> SELECT '{"a":1}'::poc.mystring IS JSON;
>
> DROP SCHEMA IF EXISTS poc CASCADE;
> ```
>
> This is the output:
>
> ```
> sqlancer=# CREATE SCHEMA IF NOT EXISTS poc;
> CREATE SCHEMA
> sqlancer=# CREATE FUNCTION poc.mystring_in(cstring)
> RETURNS poc.mystring
> AS 'textin' LANGUAGE internal IMMUTABLE STRICT;
> NOTICE: type "poc.mystring" is not yet defined
> DETAIL: Creating a shell type definition.
> CREATE FUNCTION
> sqlancer=# CREATE FUNCTION poc.mystring_out(poc.mystring)
> RETURNS cstring
> AS 'textout' LANGUAGE internal IMMUTABLE STRICT;
> NOTICE: argument type poc.mystring is only a shell
> LINE 1: CREATE FUNCTION poc.mystring_out(poc.mystring)
> ^
> CREATE FUNCTION
> sqlancer=# CREATE TYPE poc.mystring (
> INPUT = poc.mystring_in,
> OUTPUT = poc.mystring_out,
> LIKE = text,
> CATEGORY = 'S'
> );
> CREATE TYPE
> sqlancer=# SELECT '{"a":1}'::poc.mystring IS JSON;
> 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: Succeeded.
> ```
>
Thanks for the report. I was able to reproduce this on HEAD with your SQL.
The crash is in the executor while building expression state for the IS JSON
predicate -- ExecInitExprRec() ends up being called with a NULL node:
#0 ExecInitExprRec(node=0x0, ...) execExpr.c:966
#1 ExecInitExprRec(<JsonIsPredicate>) execExpr.c:2507
#2 ExecBuildProjectionInfo(...) execExpr.c:511
The NULL comes from transformJsonParseArg(). For UNKNOWN or string-category
input types it implicitly coerces to text via coerce_to_target_type() and
then sets exprtype to TEXTOID without checking if the coercion succeeded.
poc.mystring is in CATEGORY = 'S' but has no implicit cast to text, so
coerce_to_target_type() returns NULL; the parser still claims it's text and
that NULL ends up as the JsonIsPredicate subject.
String-category alone isn't a promise of text-coercibility -- adding
CREATE CAST (poc.mystring AS text) ... AS IMPLICIT makes the same query
works fine. I guess the parser just shouldn't assume the coercion worked?
The smallest fix I could see is to only update expr / exprtype when
coerce_to_target_type() returns non-NULL. Then transformJsonIsPredicate()
(and the similar JSON() WITH UNIQUE KEYS path) raise their existing
"cannot use type X" errors instead of crashing:
ERROR: cannot use type poc.mystring in IS JSON predicate
Attached is a small patch with that fix and a regression test in sqljson.
Blame points at 6ee30209a6f1 (March 2023), so this looks like it goes back
to v16.
Regards,
Ayush
Commits
-
IS JSON/JSON(): Protect against expressions uncoercible to text
- d0acd2535b4a 17 (unreleased) landed
- 7dd15325952f 19 (unreleased) landed
- 60abb3c73175 16 (unreleased) landed
- 35d9a6263407 18 (unreleased) landed
-
Reject degenerate SPLIT PARTITION with DEFAULT partition
- d8af73010033 19 (unreleased) cited