v1-0002-Don-t-treat-record-json-b-conversions-as-immutabl.patch
application/octet-stream
Filename: v1-0002-Don-t-treat-record-json-b-conversions-as-immutabl.patch
Type: application/octet-stream
Part: 2
Patch
Format: format-patch
Series: patch v1-0002
Subject: Don't treat record -> json(b) conversions as immutable.
| File | + | − |
|---|---|---|
| src/backend/utils/adt/jsonfuncs.c | 0 | 6 |
| src/test/regress/expected/sqljson.out | 1 | 1 |
| src/test/regress/sql/sqljson.sql | 0 | 1 |
From 85557388d40d6d3fe3e4ac91ca7b97fe27e29739 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Wed, 1 Jul 2026 10:29:32 -0400
Subject: [PATCH v1 2/5] Don't treat record -> json(b) conversions as
immutable.
The existing behavior is accidental and incorrect. Output functions
are required to be stable, but only some of them are immutable; hence,
output functions for container types should be treated as stable.
The JSON code has not gotten this right. A recent refactoring surfaced
the defect but preserved it via a special-case exception; this commit
removes that exception and updates the test accordingly.
This also removes the corresponding exceptions for anyarray and
anycompatiblearray, which are wrong for the same reasons, but removing
those exceptions is not expected to have any significant user-visible
consequences. Values of type record can be constructed using
ROW(), but there's no equivalent for anyarray or anycompatiblearray.
Note that the change for type record is a (minor) backward compatibility
break that could block upgrades; see the regression test for an example
of a case that would break.
---
src/backend/utils/adt/jsonfuncs.c | 6 ------
src/test/regress/expected/sqljson.out | 2 +-
src/test/regress/sql/sqljson.sql | 1 -
3 files changed, 1 insertion(+), 8 deletions(-)
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c
index f769e90ba5e..c289dbae715 100644
--- a/src/backend/utils/adt/jsonfuncs.c
+++ b/src/backend/utils/adt/jsonfuncs.c
@@ -6135,12 +6135,6 @@ json_check_mutability(Oid typoid, bool *has_mutable)
case TIMESTAMPTZOID:
*has_mutable = true;
break;
- case RECORDOID:
- case ANYARRAYOID:
- case ANYCOMPATIBLEARRAYOID:
- /* XXX incorrectly treated as known immutable */
- break;
-
default:
{
Oid castfunc = get_json_cast_for_type(typoid);
diff --git a/src/test/regress/expected/sqljson.out b/src/test/regress/expected/sqljson.out
index fedbeca7a21..f5504c11f66 100644
--- a/src/test/regress/expected/sqljson.out
+++ b/src/test/regress/expected/sqljson.out
@@ -1759,5 +1759,5 @@ SELECT JSON_OBJECT('a': JSON_OBJECTAGG('b': 1 RETURNING text) FORMAT JSON);
DROP FUNCTION volatile_one, stable_one;
-- JSON_ARRAY(ROW(...)) is not immutable, so it should be impossible to
-- create a generated column.
--- XXX: Currently, this is erroneously allowed.
CREATE TABLE json_array_of_row (a int, j json GENERATED ALWAYS AS (JSON_ARRAY(ROW(a))) STORED);
+ERROR: generation expression is not immutable
diff --git a/src/test/regress/sql/sqljson.sql b/src/test/regress/sql/sqljson.sql
index 77910137573..0762af26188 100644
--- a/src/test/regress/sql/sqljson.sql
+++ b/src/test/regress/sql/sqljson.sql
@@ -709,5 +709,4 @@ DROP FUNCTION volatile_one, stable_one;
-- JSON_ARRAY(ROW(...)) is not immutable, so it should be impossible to
-- create a generated column.
--- XXX: Currently, this is erroneously allowed.
CREATE TABLE json_array_of_row (a int, j json GENERATED ALWAYS AS (JSON_ARRAY(ROW(a))) STORED);
--
2.50.1 (Apple Git-155)