From e89e5148504e8a3587f39c27c02895d71f7546ba Mon Sep 17 00:00:00 2001
From: Alexandra Wang <alexandra.wang.oss@gmail.com>
Date: Thu, 18 Sep 2025 15:54:24 -0700
Subject: [PATCH v20 1/5] Add test coverage for indirection transformation

These tests cover nested arrays of composite data types,
single-argument functions, and casting using dot-notation, providing a
baseline for future enhancements to jsonb dot-notation support.
---
 src/test/regress/expected/arrays.out | 26 ++++++--
 src/test/regress/expected/jsonb.out  | 88 ++++++++++++++++++++++++++++
 src/test/regress/sql/arrays.sql      |  7 ++-
 src/test/regress/sql/jsonb.sql       | 18 ++++++
 4 files changed, 132 insertions(+), 7 deletions(-)

diff --git a/src/test/regress/expected/arrays.out b/src/test/regress/expected/arrays.out
index 69ea2cf5ad8..e1ab6dc278a 100644
--- a/src/test/regress/expected/arrays.out
+++ b/src/test/regress/expected/arrays.out
@@ -1782,17 +1782,17 @@ SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
 (1 row)
 
 -- A few simple tests for arrays of composite types
-create type comptype as (f1 int, f2 text);
+create type comptype as (f1 int, f2 text, f3 int[]);
 create table comptable (c1 comptype, c2 comptype[]);
 -- XXX would like to not have to specify row() construct types here ...
 insert into comptable
-  values (row(1,'foo'), array[row(2,'bar')::comptype, row(3,'baz')::comptype]);
+  values (row(1,'foo',array[10,20]), array[row(2,'bar',array[30,40])::comptype, row(3,'baz',array[50,60])::comptype]);
 -- check that implicitly named array type _comptype isn't a problem
 create type _comptype as enum('fooey');
 select * from comptable;
-   c1    |          c2           
----------+-----------------------
- (1,foo) | {"(2,bar)","(3,baz)"}
+        c1         |                      c2                       
+-------------------+-----------------------------------------------
+ (1,foo,"{10,20}") | {"(2,bar,\"{30,40}\")","(3,baz,\"{50,60}\")"}
 (1 row)
 
 select c2[2].f2 from comptable;
@@ -1801,6 +1801,22 @@ select c2[2].f2 from comptable;
  baz
 (1 row)
 
+select c2[2].f3 from comptable;
+   f3    
+---------
+ {50,60}
+(1 row)
+
+select c2[2].f3[1:2] from comptable;
+   f3    
+---------
+ {50,60}
+(1 row)
+
+select c2[1:2].f3[1:2] from comptable;
+ERROR:  column notation .f3 applied to type comptype[], which is not a composite type
+LINE 1: select c2[1:2].f3[1:2] from comptable;
+               ^
 drop type _comptype;
 drop table comptable;
 drop type comptype;
diff --git a/src/test/regress/expected/jsonb.out b/src/test/regress/expected/jsonb.out
index 5a1eb18aba2..fb47c8a893a 100644
--- a/src/test/regress/expected/jsonb.out
+++ b/src/test/regress/expected/jsonb.out
@@ -5831,3 +5831,91 @@ select '12345.0000000000000000000000000000000000000000000005'::jsonb::int8;
  12345
 (1 row)
 
+-- single argument jsonb functions as jsonb_function(jsonb) and jsonb.jsonb_function
+select jsonb_typeof('{"a":1}'::jsonb);
+ jsonb_typeof 
+--------------
+ object
+(1 row)
+
+select ('{"a":1}'::jsonb).jsonb_typeof;
+ jsonb_typeof 
+--------------
+ object
+(1 row)
+
+select jsonb_array_length('["a", "b", "c"]'::jsonb);
+ jsonb_array_length 
+--------------------
+                  3
+(1 row)
+
+select ('["a", "b", "c"]'::jsonb).jsonb_array_length;
+ jsonb_array_length 
+--------------------
+                  3
+(1 row)
+
+select jsonb_object_keys('{"a":1, "b":2}'::jsonb);
+ jsonb_object_keys 
+-------------------
+ a
+ b
+(2 rows)
+
+select ('{"a":1, "b":2}'::jsonb).jsonb_object_keys;
+ jsonb_object_keys 
+-------------------
+ a
+ b
+(2 rows)
+
+-- cast jsonb to other types as (jsonb)::type and (jsonb).type
+select ('123.45'::jsonb)::numeric;
+ numeric 
+---------
+  123.45
+(1 row)
+
+select ('123.45'::jsonb).numeric;
+ numeric 
+---------
+  123.45
+(1 row)
+
+select ('[{"name": "alice"}, {"name": "bob"}]'::jsonb)::name;
+                 name                 
+--------------------------------------
+ [{"name": "alice"}, {"name": "bob"}]
+(1 row)
+
+select ('[{"name": "alice"}, {"name": "bob"}]'::jsonb).name;
+                 name                 
+--------------------------------------
+ [{"name": "alice"}, {"name": "bob"}]
+(1 row)
+
+select ('true'::jsonb)::bool;
+ bool 
+------
+ t
+(1 row)
+
+select ('true'::jsonb).bool;
+ bool 
+------
+ t
+(1 row)
+
+select ('{"text": "hello"}'::jsonb)::text;
+       text        
+-------------------
+ {"text": "hello"}
+(1 row)
+
+select ('{"text": "hello"}'::jsonb).text;
+       text        
+-------------------
+ {"text": "hello"}
+(1 row)
+
diff --git a/src/test/regress/sql/arrays.sql b/src/test/regress/sql/arrays.sql
index 47d62c1d38d..450389831a0 100644
--- a/src/test/regress/sql/arrays.sql
+++ b/src/test/regress/sql/arrays.sql
@@ -555,19 +555,22 @@ SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
 
 -- A few simple tests for arrays of composite types
 
-create type comptype as (f1 int, f2 text);
+create type comptype as (f1 int, f2 text, f3 int[]);
 
 create table comptable (c1 comptype, c2 comptype[]);
 
 -- XXX would like to not have to specify row() construct types here ...
 insert into comptable
-  values (row(1,'foo'), array[row(2,'bar')::comptype, row(3,'baz')::comptype]);
+  values (row(1,'foo',array[10,20]), array[row(2,'bar',array[30,40])::comptype, row(3,'baz',array[50,60])::comptype]);
 
 -- check that implicitly named array type _comptype isn't a problem
 create type _comptype as enum('fooey');
 
 select * from comptable;
 select c2[2].f2 from comptable;
+select c2[2].f3 from comptable;
+select c2[2].f3[1:2] from comptable;
+select c2[1:2].f3[1:2] from comptable;
 
 drop type _comptype;
 drop table comptable;
diff --git a/src/test/regress/sql/jsonb.sql b/src/test/regress/sql/jsonb.sql
index 57c11acddfe..970ed1cffca 100644
--- a/src/test/regress/sql/jsonb.sql
+++ b/src/test/regress/sql/jsonb.sql
@@ -1590,3 +1590,21 @@ select '12345.0000000000000000000000000000000000000000000005'::jsonb::float8;
 select '12345.0000000000000000000000000000000000000000000005'::jsonb::int2;
 select '12345.0000000000000000000000000000000000000000000005'::jsonb::int4;
 select '12345.0000000000000000000000000000000000000000000005'::jsonb::int8;
+
+-- single argument jsonb functions as jsonb_function(jsonb) and jsonb.jsonb_function
+select jsonb_typeof('{"a":1}'::jsonb);
+select ('{"a":1}'::jsonb).jsonb_typeof;
+select jsonb_array_length('["a", "b", "c"]'::jsonb);
+select ('["a", "b", "c"]'::jsonb).jsonb_array_length;
+select jsonb_object_keys('{"a":1, "b":2}'::jsonb);
+select ('{"a":1, "b":2}'::jsonb).jsonb_object_keys;
+
+-- cast jsonb to other types as (jsonb)::type and (jsonb).type
+select ('123.45'::jsonb)::numeric;
+select ('123.45'::jsonb).numeric;
+select ('[{"name": "alice"}, {"name": "bob"}]'::jsonb)::name;
+select ('[{"name": "alice"}, {"name": "bob"}]'::jsonb).name;
+select ('true'::jsonb)::bool;
+select ('true'::jsonb).bool;
+select ('{"text": "hello"}'::jsonb)::text;
+select ('{"text": "hello"}'::jsonb).text;
-- 
2.39.5 (Apple Git-154)

