On Mon, Jun 09, 2025 at 12:44:59PM +0200, Alvaro Herrera wrote:
> I also added a recursive call in IsSquashableExpression to itself.  The
> check for stack depth can be done without throwing an error.  I tested
> this by adding stack bloat in that function.  I also renamed it to
> IsSquashableConstant.  This changes one of the tests, because a cast
> sequence like 42::int::bigint::int is considered squashable.
> 
> Other than that, the changes are cosmetic.
> 
> Barring objections, I'll push this soon, then look at rebasing 0003 on
> top, which I expect to be an easy job.

v9-0002 is failing in the CI for the freebsd task:
https://github.com/michaelpq/postgres/runs/43784034162

Here is the link to the diffs, also attached to this message:
https://api.cirrus-ci.com/v1/artifact/task/5378459897167872/testrun/build/testrun/pg_stat_statements/regress/regression.diffs

I am also able to reproduce these failures locally, FWIW.  For
example, with a IN clause made of integer constants gets converted to
an ArrayExpr, but in _jumbleElements() we fail to call
RecordConstLocation() and the list is not squashed.

I think that this is can be reproduced by
-DWRITE_READ_PARSE_PLAN_TREES -DCOPY_PARSE_PLAN_TREES
-DRAW_EXPRESSION_COVERAGE_TEST that I always include in my builds.
The freebsd task uses the same with debug_copy_parse_plan_trees=on,
debug_write_read_parse_plan_trees=on and
debug_raw_expression_coverage_test=on.
--
Michael
diff -U3 /tmp/cirrus-ci-build/contrib/pg_stat_statements/expected/select.out 
/tmp/cirrus-ci-build/build/testrun/pg_stat_statements/regress/results/select.out
--- /tmp/cirrus-ci-build/contrib/pg_stat_statements/expected/select.out 
2025-06-10 06:13:14.867518000 +0000
+++ 
/tmp/cirrus-ci-build/build/testrun/pg_stat_statements/regress/results/select.out
    2025-06-10 06:16:54.005179000 +0000
@@ -292,10 +292,11 @@
 SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
                                  query                                  | 
calls 
 
------------------------------------------------------------------------+-------
- SELECT WHERE $1 IN ($2 /*, ... */)                                     |     2
+ SELECT WHERE $1 = ANY (ARRAY[$2 /*, ... */])                           |     1
+ SELECT WHERE $1 IN ($2, int4($3), int4($4))                            |     1
  SELECT pg_stat_statements_reset() IS NOT NULL AS t                     |     1
  SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C" |     0
-(3 rows)
+(4 rows)
 
 --
 -- queries with locking clauses
diff -U3 /tmp/cirrus-ci-build/contrib/pg_stat_statements/expected/dml.out 
/tmp/cirrus-ci-build/build/testrun/pg_stat_statements/regress/results/dml.out
--- /tmp/cirrus-ci-build/contrib/pg_stat_statements/expected/dml.out    
2025-06-10 06:13:14.866052000 +0000
+++ 
/tmp/cirrus-ci-build/build/testrun/pg_stat_statements/regress/results/dml.out   
    2025-06-10 06:16:54.106500000 +0000
@@ -80,7 +80,7 @@
      1 |   10 | INSERT INTO pgss_dml_tab VALUES(generate_series($1, $2), $3)
      1 |   12 | SELECT * FROM pgss_dml_tab ORDER BY a
      2 |    4 | SELECT * FROM pgss_dml_tab WHERE a > $1 ORDER BY a
-     1 |    8 | SELECT * FROM pgss_dml_tab WHERE a IN ($1 /*, ... */)
+     1 |    8 | SELECT * FROM pgss_dml_tab WHERE a IN ($1, $2, $3, $4, $5)
      1 |    1 | SELECT pg_stat_statements_reset() IS NOT NULL AS t
      1 |    0 | SET pg_stat_statements.track_utility = $1
      6 |    6 | UPDATE pgss_dml_tab SET b = $1 WHERE a = $2
diff -U3 /tmp/cirrus-ci-build/contrib/pg_stat_statements/expected/squashing.out 
/tmp/cirrus-ci-build/build/testrun/pg_stat_statements/regress/results/squashing.out
--- /tmp/cirrus-ci-build/contrib/pg_stat_statements/expected/squashing.out      
2025-06-10 06:13:14.867938000 +0000
+++ 
/tmp/cirrus-ci-build/build/testrun/pg_stat_statements/regress/results/squashing.out
 2025-06-10 06:17:00.844056000 +0000
@@ -73,12 +73,14 @@
 (1 row)
 
 SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
-                         query                         | calls 
--------------------------------------------------------+-------
- SELECT * FROM test_squash WHERE id IN ($1 /*, ... */) |     3
- SELECT ARRAY[$1 /*, ... */]                           |     3
- SELECT pg_stat_statements_reset() IS NOT NULL AS t    |     1
-(3 rows)
+                           query                            | calls 
+------------------------------------------------------------+-------
+ SELECT * FROM test_squash WHERE id IN ($1, $2, $3)         |     1
+ SELECT * FROM test_squash WHERE id IN ($1, $2, $3, $4)     |     1
+ SELECT * FROM test_squash WHERE id IN ($1, $2, $3, $4, $5) |     1
+ SELECT ARRAY[$1 /*, ... */]                                |     3
+ SELECT pg_stat_statements_reset() IS NOT NULL AS t         |     1
+(5 rows)
 
 -- built-in functions will be squashed
 -- the IN and ARRAY forms of this statement will have the same queryId
@@ -99,9 +101,10 @@
 SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
                        query                        | calls 
 ----------------------------------------------------+-------
- SELECT WHERE $1 IN ($2 /*, ... */)                 |     2
+ SELECT WHERE $1 = ANY (ARRAY[$2 /*, ... */])       |     1
+ SELECT WHERE $1 IN ($2, int4($3), int4($4), $5)    |     1
  SELECT pg_stat_statements_reset() IS NOT NULL AS t |     1
-(2 rows)
+(3 rows)
 
 -- external parameters will not be squashed
 SELECT pg_stat_statements_reset() IS NOT NULL AS t;
@@ -200,11 +203,14 @@
 (0 rows)
 
 SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
-                                query                                | calls 
----------------------------------------------------------------------+-------
- SELECT * FROM test_squash WHERE id IN ($1 /*, ... */) AND data = $2 |     6
- SELECT pg_stat_statements_reset() IS NOT NULL AS t                  |     1
-(2 rows)
+                                                query                          
                      | calls 
+-----------------------------------------------------------------------------------------------------+-------
+ SELECT * FROM test_squash WHERE id = ANY (ARRAY[$1 /*, ... */]) AND data = $2 
                      |     3
+ SELECT * FROM test_squash WHERE id IN ($1, $2, $3, $4, $5, $6, $7, $8, $9) 
AND data = $10           |     1
+ SELECT * FROM test_squash WHERE id IN ($1, $2, $3, $4, $5, $6, $7, $8, $9, 
$10) AND data = $11      |     1
+ SELECT * FROM test_squash WHERE id IN ($1, $2, $3, $4, $5, $6, $7, $8, $9, 
$10, $11) AND data = $12 |     1
+ SELECT pg_stat_statements_reset() IS NOT NULL AS t                            
                      |     1
+(5 rows)
 
 -- Multiple squashed intervals
 SELECT pg_stat_statements_reset() IS NOT NULL AS t;
@@ -250,12 +256,18 @@
 (0 rows)
 
 SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
-                         query                         | calls 
--------------------------------------------------------+-------
- SELECT * FROM test_squash WHERE id IN ($1 /*, ... */)+|     6
-     AND data IN ($2 /*, ... */)                       | 
- SELECT pg_stat_statements_reset() IS NOT NULL AS t    |     1
-(2 rows)
+                                        query                                  
       | calls 
+--------------------------------------------------------------------------------------+-------
+ SELECT * FROM test_squash WHERE id = ANY (ARRAY[$1 /*, ... */])               
      +|     3
+     AND data = ANY (ARRAY[$2 /*, ... */])                                     
       | 
+ SELECT * FROM test_squash WHERE id IN ($1, $2, $3, $4, $5, $6, $7, $8, $9)    
      +|     1
+     AND data IN ($10, $11, $12, $13, $14, $15, $16, $17, $18)                 
       | 
+ SELECT * FROM test_squash WHERE id IN ($1, $2, $3, $4, $5, $6, $7, $8, $9, 
$10)     +|     1
+     AND data IN ($11, $12, $13, $14, $15, $16, $17, $18, $19, $20)            
       | 
+ SELECT * FROM test_squash WHERE id IN ($1, $2, $3, $4, $5, $6, $7, $8, $9, 
$10, $11)+|     1
+     AND data IN ($12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22)       
       | 
+ SELECT pg_stat_statements_reset() IS NOT NULL AS t                            
       |     1
+(5 rows)
 
 SELECT pg_stat_statements_reset() IS NOT NULL AS t;
  t 
@@ -372,9 +384,14 @@
                                query                                | calls 
 --------------------------------------------------------------------+-------
  SELECT data FROM test_float WHERE data = ANY(ARRAY[$1 /*, ... */]) |     3
- SELECT data FROM test_float WHERE data IN ($1 /*, ... */)          |     7
+ SELECT data FROM test_float WHERE data = ANY(ARRAY[$1 /*, ... */]) |     2
+ SELECT data FROM test_float WHERE data IN ($1, $2)                 |     1
+ SELECT data FROM test_float WHERE data IN ($1, $2)                 |     1
+ SELECT data FROM test_float WHERE data IN ($1, $2)                 |     1
+ SELECT data FROM test_float WHERE data IN ($1, $2)                 |     1
+ SELECT data FROM test_float WHERE data IN ($1, $2)                 |     1
  SELECT pg_stat_statements_reset() IS NOT NULL AS t                 |     1
-(3 rows)
+(8 rows)
 
 -- Numeric type, implicit cast is squashed
 CREATE TABLE test_squash_numeric (id int, data numeric(5, 2));
@@ -395,11 +412,11 @@
 (0 rows)
 
 SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
-                                  query                                   | 
calls 
---------------------------------------------------------------------------+-------
- SELECT * FROM test_squash_numeric WHERE data = ANY(ARRAY[$1 /*, ... */]) |    
 1
- SELECT * FROM test_squash_numeric WHERE data IN ($1 /*, ... */)          |    
 1
- SELECT pg_stat_statements_reset() IS NOT NULL AS t                       |    
 1
+                                             query                             
                 | calls 
+------------------------------------------------------------------------------------------------+-------
+ SELECT * FROM test_squash_numeric WHERE data = ANY(ARRAY[$1 /*, ... */])      
                 |     1
+ SELECT * FROM test_squash_numeric WHERE data IN ($1, $2, $3, $4, $5, $6, $7, 
$8, $9, $10, $11) |     1
+ SELECT pg_stat_statements_reset() IS NOT NULL AS t                            
                 |     1
 (3 rows)
 
 -- Bigint, implicit cast is squashed
@@ -421,11 +438,11 @@
 (0 rows)
 
 SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
-                                  query                                  | 
calls 
--------------------------------------------------------------------------+-------
- SELECT * FROM test_squash_bigint WHERE data = ANY(ARRAY[$1 /*, ... */]) |     
1
- SELECT * FROM test_squash_bigint WHERE data IN ($1 /*, ... */)          |     
1
- SELECT pg_stat_statements_reset() IS NOT NULL AS t                      |     
1
+                                             query                             
                | calls 
+-----------------------------------------------------------------------------------------------+-------
+ SELECT * FROM test_squash_bigint WHERE data = ANY(ARRAY[$1 /*, ... */])       
                |     1
+ SELECT * FROM test_squash_bigint WHERE data IN ($1, $2, $3, $4, $5, $6, $7, 
$8, $9, $10, $11) |     1
+ SELECT pg_stat_statements_reset() IS NOT NULL AS t                            
                |     1
 (3 rows)
 
 -- Bigint, explicit cast is squashed
@@ -450,12 +467,14 @@
 (0 rows)
 
 SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
-                       query                        | calls 
-----------------------------------------------------+-------
- SELECT * FROM test_squash_bigint WHERE data IN    +|     2
-         ($1 /*, ... */)                            | 
- SELECT pg_stat_statements_reset() IS NOT NULL AS t |     1
-(2 rows)
+                                      query                                    
   | calls 
+----------------------------------------------------------------------------------+-------
+ SELECT * FROM test_squash_bigint WHERE data = ANY(ARRAY[$1 /*, ... */])       
   |     1
+ SELECT * FROM test_squash_bigint WHERE data IN                                
  +|     1
+         ($1::bigint, $2::bigint, $3::bigint, $4::bigint, $5::bigint, 
$6::bigint,+| 
+          $7::bigint, $8::bigint, $9::bigint, $10::bigint, $11::bigint)        
   | 
+ SELECT pg_stat_statements_reset() IS NOT NULL AS t                            
   |     1
+(3 rows)
 
 -- Bigint, long tokens with parenthesis, will not squash
 SELECT pg_stat_statements_reset() IS NOT NULL AS t;
@@ -503,11 +522,12 @@
 (1 row)
 
 SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
-                       query                        | calls 
-----------------------------------------------------+-------
- SELECT WHERE $1 IN ($2 /*, ... */)                 |     2
- SELECT pg_stat_statements_reset() IS NOT NULL AS t |     1
-(2 rows)
+                              query                              | calls 
+-----------------------------------------------------------------+-------
+ SELECT WHERE $1 = ANY(ARRAY[$2 /*, ... */])                     |     1
+ SELECT WHERE $1 IN ($2::int::bigint::int, $3::int::bigint::int) |     1
+ SELECT pg_stat_statements_reset() IS NOT NULL AS t              |     1
+(3 rows)
 
 --
 -- CoerceViaIO
@@ -569,12 +589,17 @@
 (0 rows)
 
 SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
-                       query                        | calls 
-----------------------------------------------------+-------
- SELECT * FROM test_squash_cast WHERE data IN      +|     2
-         ($1 /*, ... */)                            | 
- SELECT pg_stat_statements_reset() IS NOT NULL AS t |     1
-(2 rows)
+                                      query                                    
   | calls 
+----------------------------------------------------------------------------------+-------
+ SELECT * FROM test_squash_cast WHERE data = ANY (ARRAY                        
  +|     1
+         [$1 /*, ... */])                                                      
   | 
+ SELECT * FROM test_squash_cast WHERE data IN                                  
  +|     1
+         ($1::int4::casttesttype, $2::int4::casttesttype, 
$3::int4::casttesttype,+| 
+          $4::int4::casttesttype, $5::int4::casttesttype, 
$6::int4::casttesttype,+| 
+          $7::int4::casttesttype, $8::int4::casttesttype, 
$9::int4::casttesttype,+| 
+          $10::int4::casttesttype, $11::int4::casttesttype)                    
   | 
+ SELECT pg_stat_statements_reset() IS NOT NULL AS t                            
   |     1
+(3 rows)
 
 -- Some casting expression are simplified to Const
 CREATE TABLE test_squash_jsonb (id int, data jsonb);
@@ -601,12 +626,16 @@
 (0 rows)
 
 SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
-                       query                        | calls 
-----------------------------------------------------+-------
- SELECT * FROM test_squash_jsonb WHERE data IN     +|     2
-         ($1 /*, ... */)                            | 
- SELECT pg_stat_statements_reset() IS NOT NULL AS t |     1
-(2 rows)
+                            query                             | calls 
+--------------------------------------------------------------+-------
+ SELECT * FROM test_squash_jsonb WHERE data = ANY (ARRAY     +|     1
+         [$1 /*, ... */])                                     | 
+ SELECT * FROM test_squash_jsonb WHERE data IN               +|     1
+         (($1)::jsonb, ($2)::jsonb, ($3)::jsonb, ($4)::jsonb,+| 
+          ($5)::jsonb, ($6)::jsonb, ($7)::jsonb, ($8)::jsonb,+| 
+          ($9)::jsonb, ($10)::jsonb)                          | 
+ SELECT pg_stat_statements_reset() IS NOT NULL AS t           |     1
+(3 rows)
 
 -- CoerceViaIO, SubLink instead of a Const. Will not squash
 SELECT pg_stat_statements_reset() IS NOT NULL AS t;
@@ -701,13 +730,13 @@
 (0 rows)
 
 SELECT query, calls FROM pg_stat_statements ORDER BY query COLLATE "C";
-                               query                                | calls 
---------------------------------------------------------------------+-------
- SELECT * FROM test_squash WHERE id IN                             +|     1
-         ($1 /*, ... */)                                            | 
- SELECT * FROM test_squash WHERE id IN ($1::oid, $2::oid::int::oid) |     2
- SELECT ARRAY[$1 /*, ... */]                                        |     1
- SELECT pg_stat_statements_reset() IS NOT NULL AS t                 |     1
+                                           query                               
            | calls 
+-------------------------------------------------------------------------------------------+-------
+ SELECT * FROM test_squash WHERE id IN                                         
           +|     1
+         ($1::oid, $2::oid, $3::oid, $4::oid, $5::oid, $6::oid, $7::oid, 
$8::oid, $9::oid) | 
+ SELECT * FROM test_squash WHERE id IN ($1::oid, $2::oid::int::oid)            
            |     2
+ SELECT ARRAY[$1 /*, ... */]                                                   
            |     1
+ SELECT pg_stat_statements_reset() IS NOT NULL AS t                            
            |     1
 (4 rows)
 
 --
@@ -773,7 +802,7 @@
                        query                        | calls 
 ----------------------------------------------------+-------
  SELECT pg_stat_statements_reset() IS NOT NULL AS t |     1
- select where $1 IN ($2 /*, ... */)                 |     1
+ select where $1 IN ($2::int, $3::int)              |     1
  select where $1 IN ($2::int, $3::int::text)        |     1
 (3 rows)
 
@@ -797,8 +826,9 @@
                        query                        | calls 
 ----------------------------------------------------+-------
  SELECT pg_stat_statements_reset() IS NOT NULL AS t |     1
- select where $1 IN ($2 /*, ... */)                 |     2
-(2 rows)
+ select where $1 = ANY (array[$2 /*, ... */])       |     1
+ select where $1 IN ($2::int::text, $3::int::text)  |     1
+(3 rows)
 
 --
 -- cleanup

Attachment: signature.asc
Description: PGP signature

Reply via email to