diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c index 18021d60af1..2191d67bfc0 100644 --- a/src/backend/utils/adt/jsonpath_exec.c +++ b/src/backend/utils/adt/jsonpath_exec.c @@ -3346,10 +3346,14 @@ JsonItemFromDatum(Datum val, Oid typid, int32 typmod, JsonbValue *res) break; case TEXTOID: case VARCHAROID: - res->type = jbvString; - res->val.string.val = VARDATA_ANY(DatumGetPointer(val)); - res->val.string.len = VARSIZE_ANY_EXHDR(DatumGetPointer(val)); - break; + { + text *txt = DatumGetTextPP(val); + + res->type = jbvString; + res->val.string.val = VARDATA_ANY(txt); + res->val.string.len = VARSIZE_ANY_EXHDR(txt); + break; + } case DATEOID: case TIMEOID: case TIMETZOID: diff --git a/src/test/regress/expected/sqljson_queryfuncs.out b/src/test/regress/expected/sqljson_queryfuncs.out index ff64dce0c59..fe8aa927b5e 100644 --- a/src/test/regress/expected/sqljson_queryfuncs.out +++ b/src/test/regress/expected/sqljson_queryfuncs.out @@ -1473,6 +1473,32 @@ SELECT JSON_QUERY(jsonb 'null', '$"Xyz"' PASSING 1 AS "Xyz"); 1 (1 row) +-- Test PASSING and toasted values +CREATE TABLE test_passing_toast (t text); +ALTER TABLE test_passing_toast ALTER COLUMN t SET STORAGE EXTENDED; +INSERT INTO test_passing_toast(t) + SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50) + FROM generate_series(1, 500) g(i); +ALTER TABLE test_passing_toast ALTER COLUMN t SET STORAGE EXTERNAL; +INSERT INTO test_passing_toast(t) + SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50) + FROM generate_series(1, 500) g(i); +SELECT count(*) AS toasted_chunks + FROM test_passing_toast WHERE pg_column_toast_chunk_id(t) IS NOT NULL; + toasted_chunks +---------------- + 2 +(1 row) + +SELECT JSON_VALUE(jsonb 'null', '$a' PASSING t AS a) = t AS ok + FROM test_passing_toast; + ok +---- + t + t +(2 rows) + +DROP TABLE test_passing_toast; -- Test ON ERROR / EMPTY value validity for the function; all fail. SELECT JSON_EXISTS(jsonb '1', '$' DEFAULT 1 ON ERROR); ERROR: invalid ON ERROR behavior diff --git a/src/test/regress/sql/sqljson_queryfuncs.sql b/src/test/regress/sql/sqljson_queryfuncs.sql index a69ef253f66..0767db9cfff 100644 --- a/src/test/regress/sql/sqljson_queryfuncs.sql +++ b/src/test/regress/sql/sqljson_queryfuncs.sql @@ -488,6 +488,22 @@ SELECT JSON_QUERY(jsonb 'null', '$Xyz' PASSING 1 AS Xyz); SELECT JSON_QUERY(jsonb 'null', '$Xyz' PASSING 1 AS "Xyz"); SELECT JSON_QUERY(jsonb 'null', '$"Xyz"' PASSING 1 AS "Xyz"); +-- Test PASSING and toasted values +CREATE TABLE test_passing_toast (t text); +ALTER TABLE test_passing_toast ALTER COLUMN t SET STORAGE EXTENDED; +INSERT INTO test_passing_toast(t) + SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50) + FROM generate_series(1, 500) g(i); +ALTER TABLE test_passing_toast ALTER COLUMN t SET STORAGE EXTERNAL; +INSERT INTO test_passing_toast(t) + SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50) + FROM generate_series(1, 500) g(i); +SELECT count(*) AS toasted_chunks + FROM test_passing_toast WHERE pg_column_toast_chunk_id(t) IS NOT NULL; +SELECT JSON_VALUE(jsonb 'null', '$a' PASSING t AS a) = t AS ok + FROM test_passing_toast; +DROP TABLE test_passing_toast; + -- Test ON ERROR / EMPTY value validity for the function; all fail. SELECT JSON_EXISTS(jsonb '1', '$' DEFAULT 1 ON ERROR); SELECT JSON_VALUE(jsonb '1', '$' EMPTY ON ERROR);