Re: BUG #19491: Segmentation fault triggered by IS NULL - Mailing list pgsql-bugs

From Srinath Reddy Sadipiralla
Subject Re: BUG #19491: Segmentation fault triggered by IS NULL
Date
Msg-id CAFC+b6q8GikS7NdDq8sC-Au4j7WZshUtw4Gzw78j0umxJ-LTqg@mail.gmail.com
Whole thread
In response to Re: BUG #19491: Segmentation fault triggered by IS NULL  (Ayush Tiwari <ayushtiwari.slg01@gmail.com>)
List pgsql-bugs
Hi,

On Mon, May 25, 2026 at 8:43 PM Ayush Tiwari <ayushtiwari.slg01@gmail.com> wrote:
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.

yeah , this was the reason.
 

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

I have reviewed the patch , i think the error message might be
something like

diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 89d0f348303..59e34f082e4 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -4203,6 +4203,13 @@ transformJsonParseArg(ParseState *pstate, Node *jsexpr, JsonFormat *format,
                                                                                 TEXTOID, -1,
                                                                                 COERCION_IMPLICIT,
                                                                                 COERCE_IMPLICIT_CAST, -1);
+                       if(expr == NULL)
+                               ereport(ERROR,
+                               (errcode(ERRCODE_CANNOT_COERCE),
+                                errmsg("cannot cast type %s to %s",
+                                               format_type_be(*exprtype),
+                                               format_type_be(TEXTOID)),
+                                parser_errposition(pstate, exprLocation(raw_expr))));
                        *exprtype = TEXTOID;
                } 

--
Thanks,
Srinath Reddy Sadipiralla
EDB: https://www.enterprisedb.com/

pgsql-bugs by date:

Previous
From: Ayush Tiwari
Date:
Subject: Re: BUG #19491: Segmentation fault triggered by IS NULL
Next
From: Tom Lane
Date:
Subject: Re: BUG #19486: Regression in SQL-language functions using XML values and IS DOCUMENT