diff --git a/GNUmakefile.in b/GNUmakefile.in index 2ca2070c1430..2bfa640ff59a 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -14,6 +14,7 @@ $(call recurse,all install,src config) all: $(MAKE) -C contrib/amcheck all $(MAKE) -C contrib/auto_explain all + $(MAKE) -C contrib/pg_stat_statements all $(MAKE) -C contrib/citext all $(MAKE) -C contrib/file_fdw all $(MAKE) -C contrib/formatter all @@ -67,6 +68,7 @@ html man: install: $(MAKE) -C contrib/amcheck $@ $(MAKE) -C contrib/auto_explain $@ + $(MAKE) -C contrib/pg_stat_statements $@ $(MAKE) -C contrib/citext $@ #$(MAKE) -C contrib/file_fdw $@ # GPDB_91_MERGE_FIXME: disable installation until it's officially supported. $(MAKE) -C contrib/formatter $@ @@ -174,6 +176,7 @@ $(call recurse,check-world,src/test src/pl src/interfaces/ecpg contrib src/bin g # recipe body). ICW_TARGETS = src/test src/pl src/interfaces/gppc ICW_TARGETS += contrib/amcheck contrib/auto_explain contrib/citext +ICW_TARGETS += contrib/pg_stat_statements ICW_TARGETS += contrib/formatter_fixedwidth ICW_TARGETS += contrib/extprotocol ICW_TARGETS += contrib/pg_trgm contrib/btree_gin contrib/isn diff --git a/contrib/pg_stat_statements/Makefile b/contrib/pg_stat_statements/Makefile index 95a27670067d..daab4987b9ff 100644 --- a/contrib/pg_stat_statements/Makefile +++ b/contrib/pg_stat_statements/Makefile @@ -7,6 +7,8 @@ EXTENSION = pg_stat_statements DATA = pg_stat_statements--1.2.sql pg_stat_statements--1.1--1.2.sql \ pg_stat_statements--1.0--1.1.sql pg_stat_statements--unpackaged--1.0.sql +REGRESS = test_pg_stat_statements + ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) diff --git a/contrib/pg_stat_statements/expected/test_pg_stat_statements.out b/contrib/pg_stat_statements/expected/test_pg_stat_statements.out new file mode 100644 index 000000000000..3b81742d84e6 --- /dev/null +++ b/contrib/pg_stat_statements/expected/test_pg_stat_statements.out @@ -0,0 +1,135 @@ +CREATE TABLE t(a int, b text) DISTRIBUTED BY (a); +-- Known issue: query is not added to pg_stat_statements statistics in +-- case it is planned by GPORCA. So disable GPORCA during tests. +SET optimizer=off; +SELECT pg_stat_statements_reset(); + pg_stat_statements_reset +-------------------------- + +(1 row) + +SELECT GROUPING (a) FROM t GROUP BY ROLLUP(a, b); + grouping +---------- +(0 rows) + +-- launch not equivalent query +SELECT GROUPING (b) FROM t GROUP BY ROLLUP(a, b); + grouping +---------- +(0 rows) + +-- check group_id() in a query +SELECT group_id() FROM t GROUP BY ROLLUP(a, b); + ?column? +---------- +(0 rows) + +-- check that queries have separate entries +SELECT query, calls FROM pg_stat_statements ORDER BY query; + query | calls +---------------------------------------------------+------- + SELECT group_id() FROM t GROUP BY ROLLUP(a, b); | 1 + SELECT GROUPING (a) FROM t GROUP BY ROLLUP(a, b); | 1 + SELECT GROUPING (b) FROM t GROUP BY ROLLUP(a, b); | 1 + SELECT pg_stat_statements_reset(); | 1 +(4 rows) + +SELECT pg_stat_statements_reset(); + pg_stat_statements_reset +-------------------------- + +(1 row) + +-- check that different grouping options result in separate entries +SELECT COUNT (*) FROM t GROUP BY ROLLUP(a, b); + count +------- +(0 rows) + +SELECT COUNT (*) FROM t GROUP BY CUBE(a, b); + count +------- +(0 rows) + +SELECT COUNT (*) FROM t GROUP BY GROUPING SETS(a, b); + count +------- +(0 rows) + +SELECT COUNT (*) FROM t GROUP BY GROUPING SETS((a), (a, b)); + count +------- +(0 rows) + +SELECT COUNT (*) FROM t GROUP BY a, b; + count +------- +(0 rows) + +SELECT query, calls FROM pg_stat_statements ORDER BY query; + query | calls +--------------------------------------------------------------+------- + SELECT COUNT (*) FROM t GROUP BY a, b; | 1 + SELECT COUNT (*) FROM t GROUP BY CUBE(a, b); | 1 + SELECT COUNT (*) FROM t GROUP BY GROUPING SETS((a), (a, b)); | 1 + SELECT COUNT (*) FROM t GROUP BY GROUPING SETS(a, b); | 1 + SELECT COUNT (*) FROM t GROUP BY ROLLUP(a, b); | 1 + SELECT pg_stat_statements_reset(); | 1 +(6 rows) + +-- check several parameters options in ROLLUP +-- all should result in separate entries +SELECT pg_stat_statements_reset(); + pg_stat_statements_reset +-------------------------- + +(1 row) + +SELECT COUNT (*) FROM t GROUP BY ROLLUP(a, b); + count +------- +(0 rows) + +SELECT COUNT (*) FROM t GROUP BY ROLLUP(b); + count +------- +(0 rows) + +SELECT query, calls FROM pg_stat_statements ORDER BY query; + query | calls +------------------------------------------------+------- + SELECT COUNT (*) FROM t GROUP BY ROLLUP(a, b); | 1 + SELECT COUNT (*) FROM t GROUP BY ROLLUP(b); | 1 + SELECT pg_stat_statements_reset(); | 1 +(3 rows) + +--- check anytable parameter for a function +SELECT pg_stat_statements_reset(); + pg_stat_statements_reset +-------------------------- + +(1 row) + +-- call of anytable_out will cause an error, +-- thus prevent actual call by adding FALSE condition +SELECT * FROM anytable_out(TABLE(SELECT * FROM t)) WHERE 1 = 0; + anytable_out +-------------- +(0 rows) + +SELECT * FROM anytable_out(TABLE(SELECT * FROM t WHERE a=0)) WHERE 1 = 0; + anytable_out +-------------- +(0 rows) + +SELECT query, calls FROM pg_stat_statements ORDER BY query; + query | calls +---------------------------------------------------------------------------+------- + SELECT * FROM anytable_out(TABLE(SELECT * FROM t)) WHERE ? = ?; | 1 + SELECT * FROM anytable_out(TABLE(SELECT * FROM t WHERE a=?)) WHERE ? = ?; | 1 + SELECT pg_stat_statements_reset(); | 1 +(3 rows) + +RESET optimizer; +DROP TABLE t; diff --git a/contrib/pg_stat_statements/sql/test_pg_stat_statements.sql b/contrib/pg_stat_statements/sql/test_pg_stat_statements.sql new file mode 100644 index 000000000000..9dc2d6b6a0a1 --- /dev/null +++ b/contrib/pg_stat_statements/sql/test_pg_stat_statements.sql @@ -0,0 +1,61 @@ +-- start_ignore +\! gpconfig -c shared_preload_libraries -v 'pg_stat_statements'; +\! gpstop -raq -M fast; +\c +CREATE EXTENSION IF NOT EXISTS pg_stat_statements; +DROP TABLE IF EXISTS t; +-- end_ignore +CREATE TABLE t(a int, b text) DISTRIBUTED BY (a); + +-- Known issue: query is not added to pg_stat_statements statistics in +-- case it is planned by GPORCA. So disable GPORCA during tests. +SET optimizer=off; + +SELECT pg_stat_statements_reset(); + +SELECT GROUPING (a) FROM t GROUP BY ROLLUP(a, b); +-- launch not equivalent query +SELECT GROUPING (b) FROM t GROUP BY ROLLUP(a, b); +-- check group_id() in a query +SELECT group_id() FROM t GROUP BY ROLLUP(a, b); + +-- check that queries have separate entries +SELECT query, calls FROM pg_stat_statements ORDER BY query; + +SELECT pg_stat_statements_reset(); + +-- check that different grouping options result in separate entries +SELECT COUNT (*) FROM t GROUP BY ROLLUP(a, b); +SELECT COUNT (*) FROM t GROUP BY CUBE(a, b); +SELECT COUNT (*) FROM t GROUP BY GROUPING SETS(a, b); +SELECT COUNT (*) FROM t GROUP BY GROUPING SETS((a), (a, b)); +SELECT COUNT (*) FROM t GROUP BY a, b; + +SELECT query, calls FROM pg_stat_statements ORDER BY query; + +-- check several parameters options in ROLLUP +-- all should result in separate entries +SELECT pg_stat_statements_reset(); + +SELECT COUNT (*) FROM t GROUP BY ROLLUP(a, b); +SELECT COUNT (*) FROM t GROUP BY ROLLUP(b); + +SELECT query, calls FROM pg_stat_statements ORDER BY query; + +--- check anytable parameter for a function +SELECT pg_stat_statements_reset(); + +-- call of anytable_out will cause an error, +-- thus prevent actual call by adding FALSE condition +SELECT * FROM anytable_out(TABLE(SELECT * FROM t)) WHERE 1 = 0; +SELECT * FROM anytable_out(TABLE(SELECT * FROM t WHERE a=0)) WHERE 1 = 0; + +SELECT query, calls FROM pg_stat_statements ORDER BY query; + +RESET optimizer; + +DROP TABLE t; +-- start_ignore +\! gpconfig -r shared_preload_libraries; +\! gpstop -raq -M fast; +-- end_ignore diff --git a/src/backend/utils/misc/queryjumble.c b/src/backend/utils/misc/queryjumble.c index 28b4e5cd9b3d..879dc552d766 100644 --- a/src/backend/utils/misc/queryjumble.c +++ b/src/backend/utils/misc/queryjumble.c @@ -179,6 +179,7 @@ JumbleRangeTable(JumbleState *jstate, List *rtable) APP_JUMB(rte->jointype); break; case RTE_FUNCTION: + case RTE_TABLEFUNCTION: JumbleExpr(jstate, (Node *) rte->functions); break; case RTE_VALUES: @@ -597,6 +598,34 @@ JumbleExpr(JumbleState *jstate, Node *node) JumbleExpr(jstate, rtfunc->funcexpr); } break; + case T_GroupId: + /* + * Struct GroupId has only the node tag, already added to the jumble + * in the code above. So just leave case empty to suppress warning. + */ + break; + case T_Integer: + APP_JUMB(intVal(node)); + break; + case T_TableValueExpr: + { + TableValueExpr *tve = (TableValueExpr *) node; + JumbleQueryInternal(jstate, (Query *) tve->subquery); + } + break; + case T_GroupingClause: + { + GroupingClause *gc = (GroupingClause *) node; + APP_JUMB(gc->groupType); + JumbleExpr(jstate, (Node *) gc->groupsets); + } + break; + case T_GroupingFunc: + { + GroupingFunc *gf = (GroupingFunc *) node; + JumbleExpr(jstate, (Node *) gf->args); + } + break; default: /* Only a warning, since we can stumble along anyway */ elog(WARNING, "unrecognized node type: %d",