diff --git a/contrib/pg_stat_statements/expected/select.out b/contrib/pg_stat_statements/expected/select.out index 708c6b0e9c4..1eebc2898ab 100644 --- a/contrib/pg_stat_statements/expected/select.out +++ b/contrib/pg_stat_statements/expected/select.out @@ -433,11 +433,10 @@ COMMIT; SELECT calls, query FROM pg_stat_statements ORDER BY query COLLATE "C"; calls | query -------+------------------------------------------------------------------------ - 1 | SELECT * FROM temp_t - 1 | SELECT * FROM temp_t + 2 | SELECT * FROM temp_t 0 | SELECT calls, query FROM pg_stat_statements ORDER BY query COLLATE "C" 1 | SELECT pg_stat_statements_reset() IS NOT NULL AS t -(4 rows) +(3 rows) SELECT pg_stat_statements_reset() IS NOT NULL AS t; t @@ -623,18 +622,15 @@ SELECT a AS a1 FROM pgss_schema_2.tab_search_diff_2; SELECT calls, query FROM pg_stat_statements ORDER BY query COLLATE "C"; calls | query -------+------------------------------------------------------------------------ - 3 | SELECT a FROM pgss_schema_2.tab_search_diff_2 AS t1 - 9 | SELECT a FROM tab_search_diff_2 AS t1 - 1 | SELECT a, b FROM pgss_schema_1.tab_search_same - 3 | SELECT a, b FROM tab_search_same + 8 | SELECT a FROM tab_search_diff_2 + 4 | SELECT a FROM tab_search_diff_2 AS t1 + 4 | SELECT a, b FROM tab_search_same 0 | SELECT calls, query FROM pg_stat_statements ORDER BY query COLLATE "C" - 1 | SELECT count(*) FROM pgss_schema_1.tab_search_same - 1 | SELECT count(*) FROM pgss_schema_2.tab_search_diff_1 - 3 | SELECT count(*) FROM tab_search_diff_1 + 4 | SELECT count(*) FROM tab_search_diff_1 4 | SELECT count(*) FROM tab_search_diff_2 - 3 | SELECT count(*) FROM tab_search_same + 4 | SELECT count(*) FROM tab_search_same 1 | SELECT pg_stat_statements_reset() IS NOT NULL AS t -(11 rows) +(8 rows) DROP SCHEMA pgss_schema_1 CASCADE; NOTICE: drop cascades to 3 other objects diff --git a/doc/src/sgml/pgstatstatements.sgml b/doc/src/sgml/pgstatstatements.sgml index f4e384e95ae..625b84ebfef 100644 --- a/doc/src/sgml/pgstatstatements.sgml +++ b/doc/src/sgml/pgstatstatements.sgml @@ -675,8 +675,13 @@ calls | 2 things, the internal object identifiers appearing in this representation. This has some counterintuitive implications. For example, pg_stat_statements will consider two apparently-identical - queries to be distinct, if they reference a table that was dropped - and recreated between the executions of the two queries. + queries to be distinct, if they reference for example a function that was + dropped and recreated between the executions of the two queries. + Conversely, if a table is dropped and recreated between the + executions of queries, two apparently-identical queries may be + considered the same. However, if the alias for a table is different + for otherwise-similar queries, these queries will be considered + distinct. The hashing process is also sensitive to differences in machine architecture and other facets of the platform. Furthermore, it is not safe to assume that queryid diff --git a/src/backend/nodes/queryjumblefuncs.c b/src/backend/nodes/queryjumblefuncs.c index f8b0f91704b..62d6cfb7ac1 100644 --- a/src/backend/nodes/queryjumblefuncs.c +++ b/src/backend/nodes/queryjumblefuncs.c @@ -67,6 +67,9 @@ static void _jumbleElements(JumbleState *jstate, List *elements); static void _jumbleA_Const(JumbleState *jstate, Node *node); static void _jumbleList(JumbleState *jstate, Node *node); static void _jumbleVariableSetStmt(JumbleState *jstate, Node *node); +static void _jumbleRangeTblEntry_eref(JumbleState *jstate, + RangeTblEntry *rte, + Alias *expr); /* * Given a possibly multi-statement source string, confine our attention to the @@ -516,3 +519,19 @@ _jumbleVariableSetStmt(JumbleState *jstate, Node *node) JUMBLE_FIELD(is_local); JUMBLE_LOCATION(location); } + +/* + * Custom query jumble function for RangeTblEntry.eref. + */ +static void +_jumbleRangeTblEntry_eref(JumbleState *jstate, + RangeTblEntry *rte, + Alias *expr) +{ + JUMBLE_FIELD(type); + + /* + * This includes only the table name, the list of column names is ignored. + */ + JUMBLE_STRING(aliasname); +} diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 23c9e3c5abf..df331b1c0d9 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1050,8 +1050,13 @@ typedef struct RangeTblEntry */ /* user-written alias clause, if any */ Alias *alias pg_node_attr(query_jumble_ignore); - /* expanded reference names */ - Alias *eref pg_node_attr(query_jumble_ignore); + + /* + * Expanded reference names. This uses a custom query jumble function so + * that the table name is included in the computation, but not its list of + * columns. + */ + Alias *eref pg_node_attr(custom_query_jumble); RTEKind rtekind; /* see above */ @@ -1094,7 +1099,7 @@ typedef struct RangeTblEntry * tables to be invalidated if the underlying table is altered. */ /* OID of the relation */ - Oid relid; + Oid relid pg_node_attr(query_jumble_ignore); /* inheritance requested? */ bool inh; /* relation kind (see pg_class.relkind) */