From fe37fac6c7483bb7ae10b0588c71fa0e0b711118 Mon Sep 17 00:00:00 2001 From: Ilya Staroverov Date: Mon, 26 Oct 2026 12:59:23 +0300 Subject: [PATCH v1 06/11] Include column definition lists in query jumbling The column definition list of a function in FROM, recorded in RangeTblFunction.funccolnames, funccoltypes, funccoltypmods and funccolcollations, has never been part of the query ID. But it gives the types of the result columns, and for functions like json_to_record() the column names are the keys to look up. So queries like SELECT * FROM json_to_record(...) AS t(a int) and the same with t(a text) or t(b int) were merged into a single pg_stat_statements entry. Include these fields in query jumbling. This changes the query IDs of the queries with functions in FROM, so it is for master only. Author: Ilya Staroverov --- contrib/pg_stat_statements/expected/select.out | 13 ++++++++++--- src/include/nodes/parsenodes.h | 8 ++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/contrib/pg_stat_statements/expected/select.out b/contrib/pg_stat_statements/expected/select.out index 1ea8c622ce..66a1524417 100644 --- a/contrib/pg_stat_statements/expected/select.out +++ b/contrib/pg_stat_statements/expected/select.out @@ -1155,13 +1155,20 @@ SELECT * FROM ROWS FROM (json_to_record('{"a": 1}') AS (a int), SELECT calls, query FROM pg_stat_statements ORDER BY query COLLATE "C"; calls | query -------+------------------------------------------------------------------------ - 2 | SELECT * FROM ROWS FROM (json_to_record($1) AS (a int), + + 1 | SELECT * FROM ROWS FROM (json_to_record($1) AS (a int), + | json_to_record($2) AS (b int)) AS t - 7 | SELECT * FROM json_to_record($1) AS t(a int) + 1 | SELECT * FROM ROWS FROM (json_to_record($1) AS (a int), + + | json_to_record($2) AS (b text)) AS t + 2 | SELECT * FROM json_to_record($1) AS t(a int) 1 | SELECT * FROM json_to_record($1) AS t(a int, b int) + 1 | SELECT * FROM json_to_record($1) AS t(a text COLLATE "C") + 1 | SELECT * FROM json_to_record($1) AS t(a text) + 1 | SELECT * FROM json_to_record($1) AS t(a varchar(3)) + 1 | SELECT * FROM json_to_record($1) AS t(a varchar(4)) + 1 | SELECT * FROM json_to_record($1) AS t(b int) 0 | SELECT calls, query FROM pg_stat_statements ORDER BY query COLLATE "C" 1 | SELECT pg_stat_statements_reset() IS NOT NULL AS t -(5 rows) +(11 rows) SELECT pg_stat_statements_reset() IS NOT NULL AS t; t diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 26208eddb3..d753cd2388 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1354,13 +1354,13 @@ typedef struct RangeTblFunction int funccolcount pg_node_attr(query_jumble_ignore); /* These fields record the contents of a column definition list, if any: */ /* column names (list of String) */ - List *funccolnames pg_node_attr(query_jumble_ignore); + List *funccolnames; /* OID list of column type OIDs */ - List *funccoltypes pg_node_attr(query_jumble_ignore); + List *funccoltypes; /* integer list of column typmods */ - List *funccoltypmods pg_node_attr(query_jumble_ignore); + List *funccoltypmods; /* OID list of column collation OIDs */ - List *funccolcollations pg_node_attr(query_jumble_ignore); + List *funccolcollations; /* This is set during planning for use by the executor: */ /* PARAM_EXEC Param IDs affecting this func */ -- 2.43.0