diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 796f564e4f88e608c6bf86c60c389911a5a2078e..f484fb91c119ac354f304ca84798c5769f0f4e30 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -5193,6 +5193,10 @@ plan_cluster_use_sort(Oid tableOid, Oid indexOid) IndexPath *indexScanPath; ListCell *lc; + /* We can short-circuit the cost comparison if indexscans are disabled */ + if (!enable_indexscan) + return true; /* use sort */ + /* Set up mostly-dummy planner state */ query = makeNode(Query); query->commandType = CMD_SELECT; diff --git a/src/test/regress/expected/cluster.out b/src/test/regress/expected/cluster.out index bc26846d6a41b1124ddf3ebc12a86e2c94faa89e..4c8d834d7ab7c675fd974ec4c61c30ff47cae264 100644 --- a/src/test/regress/expected/cluster.out +++ b/src/test/regress/expected/cluster.out @@ -438,10 +438,46 @@ select * from clstr_temp; (2 rows) drop table clstr_temp; +RESET SESSION AUTHORIZATION; +-- Test CLUSTER with external tuplesorting +create table clstr_4 as select * from tenk1; +create index cluster_sort on clstr_4 (hundred, thousand, tenthous); +-- ensure we don't use the index in CLUSTER nor the checking SELECTs +set enable_indexscan = off; +-- Use external sort that only ever uses quicksort to sort runs: +set maintenance_work_mem = '1MB'; +set replacement_sort_tuples = 0; +cluster clstr_4 using cluster_sort; +select * from +(select hundred, lag(hundred) over () as lhundred, + thousand, lag(thousand) over () as lthousand, + tenthous, lag(tenthous) over () as ltenthous from clstr_4) ss +where row(hundred, thousand, tenthous) <= row(lhundred, lthousand, ltenthous); + hundred | lhundred | thousand | lthousand | tenthous | ltenthous +---------+----------+----------+-----------+----------+----------- +(0 rows) + +-- Replacement selection will now be forced. It should only produce a single +-- run, due to the fact that input is found to be presorted: +set replacement_sort_tuples = 150000; +cluster clstr_4 using cluster_sort; +select * from +(select hundred, lag(hundred) over () as lhundred, + thousand, lag(thousand) over () as lthousand, + tenthous, lag(tenthous) over () as ltenthous from clstr_4) ss +where row(hundred, thousand, tenthous) <= row(lhundred, lthousand, ltenthous); + hundred | lhundred | thousand | lthousand | tenthous | ltenthous +---------+----------+----------+-----------+----------+----------- +(0 rows) + +reset enable_indexscan; +reset maintenance_work_mem; +reset replacement_sort_tuples; -- clean up \c - DROP TABLE clustertest; DROP TABLE clstr_1; DROP TABLE clstr_2; DROP TABLE clstr_3; +DROP TABLE clstr_4; DROP USER clstr_user; diff --git a/src/test/regress/sql/cluster.sql b/src/test/regress/sql/cluster.sql index 8d536c8c36310ce75fecb59ad2bba302acea55bd..6e619fdcc7d18460d8ebb556e1f273228fec85fe 100644 --- a/src/test/regress/sql/cluster.sql +++ b/src/test/regress/sql/cluster.sql @@ -194,10 +194,44 @@ cluster clstr_temp using clstr_temp_pkey; select * from clstr_temp; drop table clstr_temp; +RESET SESSION AUTHORIZATION; + +-- Test CLUSTER with external tuplesorting + +create table clstr_4 as select * from tenk1; +create index cluster_sort on clstr_4 (hundred, thousand, tenthous); +-- ensure we don't use the index in CLUSTER nor the checking SELECTs +set enable_indexscan = off; + +-- Use external sort that only ever uses quicksort to sort runs: +set maintenance_work_mem = '1MB'; +set replacement_sort_tuples = 0; +cluster clstr_4 using cluster_sort; +select * from +(select hundred, lag(hundred) over () as lhundred, + thousand, lag(thousand) over () as lthousand, + tenthous, lag(tenthous) over () as ltenthous from clstr_4) ss +where row(hundred, thousand, tenthous) <= row(lhundred, lthousand, ltenthous); + +-- Replacement selection will now be forced. It should only produce a single +-- run, due to the fact that input is found to be presorted: +set replacement_sort_tuples = 150000; +cluster clstr_4 using cluster_sort; +select * from +(select hundred, lag(hundred) over () as lhundred, + thousand, lag(thousand) over () as lthousand, + tenthous, lag(tenthous) over () as ltenthous from clstr_4) ss +where row(hundred, thousand, tenthous) <= row(lhundred, lthousand, ltenthous); + +reset enable_indexscan; +reset maintenance_work_mem; +reset replacement_sort_tuples; + -- clean up \c - DROP TABLE clustertest; DROP TABLE clstr_1; DROP TABLE clstr_2; DROP TABLE clstr_3; +DROP TABLE clstr_4; DROP USER clstr_user;