From 47bcce494e741922803581a24306c0748419d891 Mon Sep 17 00:00:00 2001
From: EC2 Default User <ec2-user@ip-172-31-44-253.ec2.internal>
Date: Wed, 13 Sep 2023 00:18:34 +0000
Subject: [PATCH 1/1] Jumble the CALL command in pg_stat_statements

3db72ebcbe introduced gen_node_support.pl for

An earlier proposal to jumble CALL and SET commands [1]
was rejected in lieu of a more comprehensive solution.
3db72ebcbe allowed gen_node_support.pl to support query jumbling.

This change takes advantage of the infrastructure introduced
in the aforementioned commit and jumbles the CALL command.

[1] https://www.postgresql.org/message-id/flat/36e5bffe-e989-194f-85c8-06e7bc88e6f7%40amazon.com

Author: Sami Imseih
Reviewed-by: Michael Pacquier
Discussion: https://www.postgresql.org/message-id/flat/B44FA29D-EBD0-4DD9-ABC2-16F1CB087074%40amazon.com
---
 .../pg_stat_statements/expected/utility.out   | 44 ++++++++++++++++---
 contrib/pg_stat_statements/sql/utility.sql    | 23 ++++++++++
 src/include/nodes/parsenodes.h                |  6 +--
 3 files changed, 65 insertions(+), 8 deletions(-)

diff --git a/contrib/pg_stat_statements/expected/utility.out b/contrib/pg_stat_statements/expected/utility.out
index f331044f3e..f3bc9fcb7c 100644
--- a/contrib/pg_stat_statements/expected/utility.out
+++ b/contrib/pg_stat_statements/expected/utility.out
@@ -300,6 +300,25 @@ DECLARE
 BEGIN
   SELECT (i + j)::int INTO r;
 END; $$ LANGUAGE plpgsql;
+CREATE OR REPLACE PROCEDURE overload(i int) AS $$
+DECLARE
+  r int;
+BEGIN
+  SELECT (i + i)::int INTO r;
+END; $$ LANGUAGE plpgsql;
+CREATE OR REPLACE PROCEDURE overload(i text) AS $$
+DECLARE
+  r text;
+BEGIN
+  SELECT i::text INTO r;
+END; $$ LANGUAGE plpgsql;
+CREATE OR REPLACE PROCEDURE in_out(i int, i2 OUT int, i3 INOUT int) AS $$
+DECLARE
+  r int;
+BEGIN
+	i2 := i;
+	i3 := i3 + i;
+END; $$ LANGUAGE plpgsql;
 SELECT pg_stat_statements_reset();
  pg_stat_statements_reset 
 --------------------------
@@ -310,15 +329,30 @@ CALL sum_one(3);
 CALL sum_one(199);
 CALL sum_two(1,1);
 CALL sum_two(1,2);
+CALL overload(1);
+CALL overload('A');
+CALL in_out(1, NULL, 1);
+ i2 | i3 
+----+----
+  1 |  2
+(1 row)
+
+CALL in_out(2, 1, 2);
+ i2 | i3 
+----+----
+  2 |  4
+(1 row)
+
 SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
  calls | rows |               query               
 -------+------+-----------------------------------
-     1 |    0 | CALL sum_one(199)
-     1 |    0 | CALL sum_one(3)
-     1 |    0 | CALL sum_two(1,1)
-     1 |    0 | CALL sum_two(1,2)
+     2 |    0 | CALL in_out($1, $2, $3)
+     1 |    0 | CALL overload($1)
+     1 |    0 | CALL overload($1)
+     2 |    0 | CALL sum_one($1)
+     2 |    0 | CALL sum_two($1,$2)
      1 |    1 | SELECT pg_stat_statements_reset()
-(5 rows)
+(6 rows)
 
 -- COPY
 CREATE TABLE copy_stats (a int, b int);
diff --git a/contrib/pg_stat_statements/sql/utility.sql b/contrib/pg_stat_statements/sql/utility.sql
index 5f7d4a467f..28fd13dee0 100644
--- a/contrib/pg_stat_statements/sql/utility.sql
+++ b/contrib/pg_stat_statements/sql/utility.sql
@@ -164,11 +164,34 @@ DECLARE
 BEGIN
   SELECT (i + j)::int INTO r;
 END; $$ LANGUAGE plpgsql;
+CREATE OR REPLACE PROCEDURE overload(i int) AS $$
+DECLARE
+  r int;
+BEGIN
+  SELECT (i + i)::int INTO r;
+END; $$ LANGUAGE plpgsql;
+CREATE OR REPLACE PROCEDURE overload(i text) AS $$
+DECLARE
+  r text;
+BEGIN
+  SELECT i::text INTO r;
+END; $$ LANGUAGE plpgsql;
+CREATE OR REPLACE PROCEDURE in_out(i int, i2 OUT int, i3 INOUT int) AS $$
+DECLARE
+  r int;
+BEGIN
+	i2 := i;
+	i3 := i3 + i;
+END; $$ LANGUAGE plpgsql;
 SELECT pg_stat_statements_reset();
 CALL sum_one(3);
 CALL sum_one(199);
 CALL sum_two(1,1);
 CALL sum_two(1,2);
+CALL overload(1);
+CALL overload('A');
+CALL in_out(1, NULL, 1);
+CALL in_out(2, 1, 2);
 SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
 
 -- COPY
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index fef4c714b8..993b545739 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -3376,11 +3376,11 @@ typedef struct InlineCodeBlock
 typedef struct CallStmt
 {
 	NodeTag		type;
-	FuncCall   *funccall;		/* from the parser */
+	FuncCall   *funccall pg_node_attr(query_jumble_ignore);	/* from the parser */
 	/* transformed call, with only input args */
-	FuncExpr   *funcexpr pg_node_attr(query_jumble_ignore);
+	FuncExpr   *funcexpr;
 	/* transformed output-argument expressions */
-	List	   *outargs pg_node_attr(query_jumble_ignore);
+	List	   *outargs;
 } CallStmt;
 
 typedef struct CallContext
-- 
2.40.1

