| From: | Srinath Reddy Sadipiralla <srinath2133(at)gmail(dot)com> |
|---|---|
| To: | Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com> |
| Cc: | 798604270(at)qq(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org, Álvaro Herrera <alvherre(at)kurilemu(dot)de> |
| Subject: | Re: BUG #19491: Segmentation fault triggered by IS NULL |
| Date: | 2026-05-25 16:36:01 |
| Message-ID: | CAFC+b6q8GikS7NdDq8sC-Au4j7WZshUtw4Gzw78j0umxJ-LTqg@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
Hi,
On Mon, May 25, 2026 at 8:43 PM Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com>
wrote:
> Hi,
>
> On Mon, 25 May 2026 at 18:57, PG Bug reporting form <
> noreply(at)postgresql(dot)org> wrote:
>
>> The following bug has been logged on the website:
>>
>> Bug reference: 19491
>> Logged by: Chi Zhang
>> Email address: 798604270(at)qq(dot)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/
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Alexander Korotkov | 2026-05-25 19:26:51 | Re: BUG #19435: Error: "No relation entry for relid 2" Triggered by Complex Join with Self-Referencing Tables |
| Previous Message | Ayush Tiwari | 2026-05-25 15:12:41 | Re: BUG #19491: Segmentation fault triggered by IS NULL |