From 7ef5e2e21c8af34f0feef2057bd51b5c94582ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Nordstr=C3=B6m?= Date: Wed, 16 Oct 2019 16:54:18 +0200 Subject: [PATCH] Fix output row estimation for ordered upper rels The number of output rows estimated for "remote" upper rels could sometimes erroneously be zero. This happened when computing the estimate for upper rels with different pathkeys: in case of several different path keys the estimation was not recalculated and instead relied on cached values from the first calculation on the same rel. However, the number of output rows was never cached so the second pathkey estimated for the upper rel would always produce zero output rows. This has now been fixed by storing the output rows in the upper rel after the first estimation. This fix affects some query plans so a number of tests are affected. --- tsl/src/fdw/estimate.c | 4 + tsl/test/expected/debug_notice.out | 13 +- tsl/test/expected/dist_partial_agg.out | 60 ++++----- .../expected/partitionwise_distributed-11.out | 116 ++++++++++-------- .../expected/partitionwise_distributed-12.out | 116 ++++++++++-------- tsl/test/sql/dist_partial_agg.sql | 2 +- 6 files changed, 171 insertions(+), 140 deletions(-) diff --git a/tsl/src/fdw/estimate.c b/tsl/src/fdw/estimate.c index 895890408..125008f82 100644 --- a/tsl/src/fdw/estimate.c +++ b/tsl/src/fdw/estimate.c @@ -263,6 +263,10 @@ get_upper_rel_estimate(PlannerInfo *root, RelOptInfo *rel, CostEstimate *ce) #endif ce->run_cost += cpu_tuple_cost * num_groups; ce->run_cost += ptarget->cost.per_tuple * num_groups; + + /* Update the relation's number of output rows. Needed on UPPER rels as + * "cached" value when we compute costs for different pathkeys */ + rel->rows = ce->rows; } static void diff --git a/tsl/test/expected/debug_notice.out b/tsl/test/expected/debug_notice.out index b29749974..8d85a38d0 100644 --- a/tsl/test/expected/debug_notice.out +++ b/tsl/test/expected/debug_notice.out @@ -115,31 +115,32 @@ GROUP BY 1, 2 HAVING avg(temp) > 4 ORDER BY 1, 2; DEBUG: Stage GROUP_AGG in get_foreign_upper_paths: -RELOPTINFO (hyper): rows=0 width=20 +RELOPTINFO (hyper): rows=9 width=20 path list: CustomScan (DataNodeScanPath) [parents: hyper] rows=9 cost=100.09..128.32 Agg [parents: hyper] rows=3 cost=128.18..128.34 CustomScan (DataNodeScanPath) [parents: hyper] rows=9 cost=100.00..128.09 - CustomScan (DataNodeScanPath) [parents: hyper] rows=0 cost=100.09..129.73 has pathkeys + Agg [parents: hyper] rows=3 cost=100.00..129.74 has pathkeys + CustomScan (DataNodeScanPath) [parents: hyper] rows=9 cost=100.00..129.49 has pathkeys DEBUG: Stage GROUP_AGG in get_foreign_upper_paths: -RELOPTINFO (hyper): rows=0 width=20 +RELOPTINFO (hyper): rows=19 width=20 path list: CustomScan (DataNodeScanPath) [parents: hyper] rows=19 cost=100.19..156.69 Agg [parents: hyper] rows=6 cost=156.61..157.18 has pathkeys Sort [parents: hyper] rows=19 cost=156.61..156.66 has pathkeys CustomScan (DataNodeScanPath) [parents: hyper] rows=19 cost=100.00..156.21 - CustomScan (DataNodeScanPath) [parents: hyper] rows=0 cost=100.20..159.50 has pathkeys DEBUG: Stage GROUP_AGG in get_foreign_upper_paths: -RELOPTINFO (hyper): rows=0 width=20 +RELOPTINFO (hyper): rows=9 width=20 path list: CustomScan (DataNodeScanPath) [parents: hyper] rows=9 cost=100.09..128.32 Agg [parents: hyper] rows=3 cost=128.18..128.34 CustomScan (DataNodeScanPath) [parents: hyper] rows=9 cost=100.00..128.09 - CustomScan (DataNodeScanPath) [parents: hyper] rows=0 cost=100.09..129.73 has pathkeys + Agg [parents: hyper] rows=3 cost=100.00..129.74 has pathkeys + CustomScan (DataNodeScanPath) [parents: hyper] rows=9 cost=100.00..129.49 has pathkeys time | device | temp diff --git a/tsl/test/expected/dist_partial_agg.out b/tsl/test/expected/dist_partial_agg.out index 511926bef..83421534c 100644 --- a/tsl/test/expected/dist_partial_agg.out +++ b/tsl/test/expected/dist_partial_agg.out @@ -332,34 +332,36 @@ SET enable_partitionwise_aggregate = ON; FROM :TEST_TABLE GROUP BY :GROUPING ORDER BY :GROUPING; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Finalize GroupAggregate - Output: region, min(allnull), max(temperature), (sum(temperature) + sum(humidity)), avg(humidity), round((stddev(humidity))::numeric, 1), bit_and(bit_int), bit_or(bit_int), bool_and(good_life), every((temperature > '0'::double precision)), bool_or(good_life), count(*), count(temperature), count(allnull), round((corr(temperature, humidity))::numeric, 1), round((covar_pop(temperature, humidity))::numeric, 1), round((covar_samp(temperature, humidity))::numeric, 1), round((regr_avgx(temperature, humidity))::numeric, 1), round((regr_avgy(temperature, humidity))::numeric, 1), round((regr_count(temperature, humidity))::numeric, 1), round((regr_intercept(temperature, humidity))::numeric, 1), round((regr_r2(temperature, humidity))::numeric, 1), round((regr_slope(temperature, humidity))::numeric, 1), round((regr_sxx(temperature, humidity))::numeric, 1), round((regr_sxy(temperature, humidity))::numeric, 1), round((regr_syy(temperature, humidity))::numeric, 1), round((stddev(temperature))::numeric, 1), round((stddev_pop(temperature))::numeric, 1), round((stddev_samp(temperature))::numeric, 1), round((variance(temperature))::numeric, 1), round((var_pop(temperature))::numeric, 1), round((var_samp(temperature))::numeric, 1), last(temperature, timec), histogram(temperature, '0'::double precision, '100'::double precision, 1) - Group Key: region - -> Custom Scan (AsyncAppend) - Output: region, (PARTIAL min(allnull)), (PARTIAL max(temperature)), (PARTIAL sum(temperature)), (PARTIAL sum(humidity)), (PARTIAL avg(humidity)), (PARTIAL stddev(humidity)), (PARTIAL bit_and(bit_int)), (PARTIAL bit_or(bit_int)), (PARTIAL bool_and(good_life)), (PARTIAL every((temperature > '0'::double precision))), (PARTIAL bool_or(good_life)), (PARTIAL count(*)), (PARTIAL count(temperature)), (PARTIAL count(allnull)), (PARTIAL corr(temperature, humidity)), (PARTIAL covar_pop(temperature, humidity)), (PARTIAL covar_samp(temperature, humidity)), (PARTIAL regr_avgx(temperature, humidity)), (PARTIAL regr_avgy(temperature, humidity)), (PARTIAL regr_count(temperature, humidity)), (PARTIAL regr_intercept(temperature, humidity)), (PARTIAL regr_r2(temperature, humidity)), (PARTIAL regr_slope(temperature, humidity)), (PARTIAL regr_sxx(temperature, humidity)), (PARTIAL regr_sxy(temperature, humidity)), (PARTIAL regr_syy(temperature, humidity)), (PARTIAL stddev(temperature)), (PARTIAL stddev_pop(temperature)), (PARTIAL stddev_samp(temperature)), (PARTIAL variance(temperature)), (PARTIAL var_pop(temperature)), (PARTIAL var_samp(temperature)), (PARTIAL last(temperature, timec)), (PARTIAL histogram(temperature, '0'::double precision, '100'::double precision, 1)) - -> Merge Append - Sort Key: conditions.region - -> Custom Scan (DataNodeScan) - Output: conditions.region, (PARTIAL min(conditions.allnull)), (PARTIAL max(conditions.temperature)), (PARTIAL sum(conditions.temperature)), (PARTIAL sum(conditions.humidity)), (PARTIAL avg(conditions.humidity)), (PARTIAL stddev(conditions.humidity)), (PARTIAL bit_and(conditions.bit_int)), (PARTIAL bit_or(conditions.bit_int)), (PARTIAL bool_and(conditions.good_life)), (PARTIAL every((conditions.temperature > '0'::double precision))), (PARTIAL bool_or(conditions.good_life)), (PARTIAL count(*)), (PARTIAL count(conditions.temperature)), (PARTIAL count(conditions.allnull)), (PARTIAL corr(conditions.temperature, conditions.humidity)), (PARTIAL covar_pop(conditions.temperature, conditions.humidity)), (PARTIAL covar_samp(conditions.temperature, conditions.humidity)), (PARTIAL regr_avgx(conditions.temperature, conditions.humidity)), (PARTIAL regr_avgy(conditions.temperature, conditions.humidity)), (PARTIAL regr_count(conditions.temperature, conditions.humidity)), (PARTIAL regr_intercept(conditions.temperature, conditions.humidity)), (PARTIAL regr_r2(conditions.temperature, conditions.humidity)), (PARTIAL regr_slope(conditions.temperature, conditions.humidity)), (PARTIAL regr_sxx(conditions.temperature, conditions.humidity)), (PARTIAL regr_sxy(conditions.temperature, conditions.humidity)), (PARTIAL regr_syy(conditions.temperature, conditions.humidity)), (PARTIAL stddev(conditions.temperature)), (PARTIAL stddev_pop(conditions.temperature)), (PARTIAL stddev_samp(conditions.temperature)), (PARTIAL variance(conditions.temperature)), (PARTIAL var_pop(conditions.temperature)), (PARTIAL var_samp(conditions.temperature)), (PARTIAL last(conditions.temperature, conditions.timec)), (PARTIAL histogram(conditions.temperature, '0'::double precision, '100'::double precision, 1)) - Relations: Aggregate on (public.conditions) - Data node: data_node_1 - Chunks: _hyper_1_1_dist_chunk, _hyper_1_2_dist_chunk, _hyper_1_3_dist_chunk, _hyper_1_4_dist_chunk - Remote SQL: SELECT region, _timescaledb_internal.partialize_agg(min(allnull)), _timescaledb_internal.partialize_agg(max(temperature)), _timescaledb_internal.partialize_agg(sum(temperature)), _timescaledb_internal.partialize_agg(sum(humidity)), _timescaledb_internal.partialize_agg(avg(humidity)), _timescaledb_internal.partialize_agg(stddev(humidity)), _timescaledb_internal.partialize_agg(bit_and(bit_int)), _timescaledb_internal.partialize_agg(bit_or(bit_int)), _timescaledb_internal.partialize_agg(bool_and(good_life)), _timescaledb_internal.partialize_agg(every((temperature > 0::double precision))), _timescaledb_internal.partialize_agg(bool_or(good_life)), _timescaledb_internal.partialize_agg(count(*)), _timescaledb_internal.partialize_agg(count(temperature)), _timescaledb_internal.partialize_agg(count(allnull)), _timescaledb_internal.partialize_agg(corr(temperature, humidity)), _timescaledb_internal.partialize_agg(covar_pop(temperature, humidity)), _timescaledb_internal.partialize_agg(covar_samp(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_avgx(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_avgy(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_count(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_intercept(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_r2(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_slope(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_sxx(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_sxy(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_syy(temperature, humidity)), _timescaledb_internal.partialize_agg(stddev(temperature)), _timescaledb_internal.partialize_agg(stddev_pop(temperature)), _timescaledb_internal.partialize_agg(stddev_samp(temperature)), _timescaledb_internal.partialize_agg(variance(temperature)), _timescaledb_internal.partialize_agg(var_pop(temperature)), _timescaledb_internal.partialize_agg(var_samp(temperature)), _timescaledb_internal.partialize_agg(public.last(temperature, timec)), _timescaledb_internal.partialize_agg(public.histogram(temperature, 0::double precision, 100::double precision, 1)) FROM public.conditions WHERE _timescaledb_internal.chunks_in(conditions, ARRAY[1, 2, 3, 4]) GROUP BY 1 ORDER BY region ASC NULLS LAST - -> Custom Scan (DataNodeScan) - Output: conditions_1.region, (PARTIAL min(conditions_1.allnull)), (PARTIAL max(conditions_1.temperature)), (PARTIAL sum(conditions_1.temperature)), (PARTIAL sum(conditions_1.humidity)), (PARTIAL avg(conditions_1.humidity)), (PARTIAL stddev(conditions_1.humidity)), (PARTIAL bit_and(conditions_1.bit_int)), (PARTIAL bit_or(conditions_1.bit_int)), (PARTIAL bool_and(conditions_1.good_life)), (PARTIAL every((conditions_1.temperature > '0'::double precision))), (PARTIAL bool_or(conditions_1.good_life)), (PARTIAL count(*)), (PARTIAL count(conditions_1.temperature)), (PARTIAL count(conditions_1.allnull)), (PARTIAL corr(conditions_1.temperature, conditions_1.humidity)), (PARTIAL covar_pop(conditions_1.temperature, conditions_1.humidity)), (PARTIAL covar_samp(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_avgx(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_avgy(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_count(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_intercept(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_r2(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_slope(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_sxx(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_sxy(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_syy(conditions_1.temperature, conditions_1.humidity)), (PARTIAL stddev(conditions_1.temperature)), (PARTIAL stddev_pop(conditions_1.temperature)), (PARTIAL stddev_samp(conditions_1.temperature)), (PARTIAL variance(conditions_1.temperature)), (PARTIAL var_pop(conditions_1.temperature)), (PARTIAL var_samp(conditions_1.temperature)), (PARTIAL last(conditions_1.temperature, conditions_1.timec)), (PARTIAL histogram(conditions_1.temperature, '0'::double precision, '100'::double precision, 1)) - Relations: Aggregate on (public.conditions) - Data node: data_node_2 - Chunks: _hyper_1_9_dist_chunk, _hyper_1_10_dist_chunk, _hyper_1_11_dist_chunk, _hyper_1_12_dist_chunk - Remote SQL: SELECT region, _timescaledb_internal.partialize_agg(min(allnull)), _timescaledb_internal.partialize_agg(max(temperature)), _timescaledb_internal.partialize_agg(sum(temperature)), _timescaledb_internal.partialize_agg(sum(humidity)), _timescaledb_internal.partialize_agg(avg(humidity)), _timescaledb_internal.partialize_agg(stddev(humidity)), _timescaledb_internal.partialize_agg(bit_and(bit_int)), _timescaledb_internal.partialize_agg(bit_or(bit_int)), _timescaledb_internal.partialize_agg(bool_and(good_life)), _timescaledb_internal.partialize_agg(every((temperature > 0::double precision))), _timescaledb_internal.partialize_agg(bool_or(good_life)), _timescaledb_internal.partialize_agg(count(*)), _timescaledb_internal.partialize_agg(count(temperature)), _timescaledb_internal.partialize_agg(count(allnull)), _timescaledb_internal.partialize_agg(corr(temperature, humidity)), _timescaledb_internal.partialize_agg(covar_pop(temperature, humidity)), _timescaledb_internal.partialize_agg(covar_samp(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_avgx(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_avgy(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_count(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_intercept(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_r2(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_slope(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_sxx(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_sxy(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_syy(temperature, humidity)), _timescaledb_internal.partialize_agg(stddev(temperature)), _timescaledb_internal.partialize_agg(stddev_pop(temperature)), _timescaledb_internal.partialize_agg(stddev_samp(temperature)), _timescaledb_internal.partialize_agg(variance(temperature)), _timescaledb_internal.partialize_agg(var_pop(temperature)), _timescaledb_internal.partialize_agg(var_samp(temperature)), _timescaledb_internal.partialize_agg(public.last(temperature, timec)), _timescaledb_internal.partialize_agg(public.histogram(temperature, 0::double precision, 100::double precision, 1)) FROM public.conditions WHERE _timescaledb_internal.chunks_in(conditions, ARRAY[1, 2, 3, 4]) GROUP BY 1 ORDER BY region ASC NULLS LAST - -> Custom Scan (DataNodeScan) - Output: conditions_2.region, (PARTIAL min(conditions_2.allnull)), (PARTIAL max(conditions_2.temperature)), (PARTIAL sum(conditions_2.temperature)), (PARTIAL sum(conditions_2.humidity)), (PARTIAL avg(conditions_2.humidity)), (PARTIAL stddev(conditions_2.humidity)), (PARTIAL bit_and(conditions_2.bit_int)), (PARTIAL bit_or(conditions_2.bit_int)), (PARTIAL bool_and(conditions_2.good_life)), (PARTIAL every((conditions_2.temperature > '0'::double precision))), (PARTIAL bool_or(conditions_2.good_life)), (PARTIAL count(*)), (PARTIAL count(conditions_2.temperature)), (PARTIAL count(conditions_2.allnull)), (PARTIAL corr(conditions_2.temperature, conditions_2.humidity)), (PARTIAL covar_pop(conditions_2.temperature, conditions_2.humidity)), (PARTIAL covar_samp(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_avgx(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_avgy(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_count(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_intercept(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_r2(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_slope(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_sxx(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_sxy(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_syy(conditions_2.temperature, conditions_2.humidity)), (PARTIAL stddev(conditions_2.temperature)), (PARTIAL stddev_pop(conditions_2.temperature)), (PARTIAL stddev_samp(conditions_2.temperature)), (PARTIAL variance(conditions_2.temperature)), (PARTIAL var_pop(conditions_2.temperature)), (PARTIAL var_samp(conditions_2.temperature)), (PARTIAL last(conditions_2.temperature, conditions_2.timec)), (PARTIAL histogram(conditions_2.temperature, '0'::double precision, '100'::double precision, 1)) - Relations: Aggregate on (public.conditions) - Data node: data_node_3 - Chunks: _hyper_1_5_dist_chunk, _hyper_1_6_dist_chunk, _hyper_1_7_dist_chunk, _hyper_1_8_dist_chunk - Remote SQL: SELECT region, _timescaledb_internal.partialize_agg(min(allnull)), _timescaledb_internal.partialize_agg(max(temperature)), _timescaledb_internal.partialize_agg(sum(temperature)), _timescaledb_internal.partialize_agg(sum(humidity)), _timescaledb_internal.partialize_agg(avg(humidity)), _timescaledb_internal.partialize_agg(stddev(humidity)), _timescaledb_internal.partialize_agg(bit_and(bit_int)), _timescaledb_internal.partialize_agg(bit_or(bit_int)), _timescaledb_internal.partialize_agg(bool_and(good_life)), _timescaledb_internal.partialize_agg(every((temperature > 0::double precision))), _timescaledb_internal.partialize_agg(bool_or(good_life)), _timescaledb_internal.partialize_agg(count(*)), _timescaledb_internal.partialize_agg(count(temperature)), _timescaledb_internal.partialize_agg(count(allnull)), _timescaledb_internal.partialize_agg(corr(temperature, humidity)), _timescaledb_internal.partialize_agg(covar_pop(temperature, humidity)), _timescaledb_internal.partialize_agg(covar_samp(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_avgx(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_avgy(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_count(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_intercept(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_r2(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_slope(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_sxx(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_sxy(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_syy(temperature, humidity)), _timescaledb_internal.partialize_agg(stddev(temperature)), _timescaledb_internal.partialize_agg(stddev_pop(temperature)), _timescaledb_internal.partialize_agg(stddev_samp(temperature)), _timescaledb_internal.partialize_agg(variance(temperature)), _timescaledb_internal.partialize_agg(var_pop(temperature)), _timescaledb_internal.partialize_agg(var_samp(temperature)), _timescaledb_internal.partialize_agg(public.last(temperature, timec)), _timescaledb_internal.partialize_agg(public.histogram(temperature, 0::double precision, 100::double precision, 1)) FROM public.conditions WHERE _timescaledb_internal.chunks_in(conditions, ARRAY[1, 2, 3, 4]) GROUP BY 1 ORDER BY region ASC NULLS LAST -(25 rows) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: region, (min(allnull)), (max(temperature)), ((sum(temperature) + sum(humidity))), (avg(humidity)), (round((stddev(humidity))::numeric, 1)), (bit_and(bit_int)), (bit_or(bit_int)), (bool_and(good_life)), (every((temperature > '0'::double precision))), (bool_or(good_life)), (count(*)), (count(temperature)), (count(allnull)), (round((corr(temperature, humidity))::numeric, 1)), (round((covar_pop(temperature, humidity))::numeric, 1)), (round((covar_samp(temperature, humidity))::numeric, 1)), (round((regr_avgx(temperature, humidity))::numeric, 1)), (round((regr_avgy(temperature, humidity))::numeric, 1)), (round((regr_count(temperature, humidity))::numeric, 1)), (round((regr_intercept(temperature, humidity))::numeric, 1)), (round((regr_r2(temperature, humidity))::numeric, 1)), (round((regr_slope(temperature, humidity))::numeric, 1)), (round((regr_sxx(temperature, humidity))::numeric, 1)), (round((regr_sxy(temperature, humidity))::numeric, 1)), (round((regr_syy(temperature, humidity))::numeric, 1)), (round((stddev(temperature))::numeric, 1)), (round((stddev_pop(temperature))::numeric, 1)), (round((stddev_samp(temperature))::numeric, 1)), (round((variance(temperature))::numeric, 1)), (round((var_pop(temperature))::numeric, 1)), (round((var_samp(temperature))::numeric, 1)), (last(temperature, timec)), (histogram(temperature, '0'::double precision, '100'::double precision, 1)) + Sort Key: region + -> Finalize HashAggregate + Output: region, min(allnull), max(temperature), (sum(temperature) + sum(humidity)), avg(humidity), round((stddev(humidity))::numeric, 1), bit_and(bit_int), bit_or(bit_int), bool_and(good_life), every((temperature > '0'::double precision)), bool_or(good_life), count(*), count(temperature), count(allnull), round((corr(temperature, humidity))::numeric, 1), round((covar_pop(temperature, humidity))::numeric, 1), round((covar_samp(temperature, humidity))::numeric, 1), round((regr_avgx(temperature, humidity))::numeric, 1), round((regr_avgy(temperature, humidity))::numeric, 1), round((regr_count(temperature, humidity))::numeric, 1), round((regr_intercept(temperature, humidity))::numeric, 1), round((regr_r2(temperature, humidity))::numeric, 1), round((regr_slope(temperature, humidity))::numeric, 1), round((regr_sxx(temperature, humidity))::numeric, 1), round((regr_sxy(temperature, humidity))::numeric, 1), round((regr_syy(temperature, humidity))::numeric, 1), round((stddev(temperature))::numeric, 1), round((stddev_pop(temperature))::numeric, 1), round((stddev_samp(temperature))::numeric, 1), round((variance(temperature))::numeric, 1), round((var_pop(temperature))::numeric, 1), round((var_samp(temperature))::numeric, 1), last(temperature, timec), histogram(temperature, '0'::double precision, '100'::double precision, 1) + Group Key: region + -> Custom Scan (AsyncAppend) + Output: region, (PARTIAL min(allnull)), (PARTIAL max(temperature)), (PARTIAL sum(temperature)), (PARTIAL sum(humidity)), (PARTIAL avg(humidity)), (PARTIAL stddev(humidity)), (PARTIAL bit_and(bit_int)), (PARTIAL bit_or(bit_int)), (PARTIAL bool_and(good_life)), (PARTIAL every((temperature > '0'::double precision))), (PARTIAL bool_or(good_life)), (PARTIAL count(*)), (PARTIAL count(temperature)), (PARTIAL count(allnull)), (PARTIAL corr(temperature, humidity)), (PARTIAL covar_pop(temperature, humidity)), (PARTIAL covar_samp(temperature, humidity)), (PARTIAL regr_avgx(temperature, humidity)), (PARTIAL regr_avgy(temperature, humidity)), (PARTIAL regr_count(temperature, humidity)), (PARTIAL regr_intercept(temperature, humidity)), (PARTIAL regr_r2(temperature, humidity)), (PARTIAL regr_slope(temperature, humidity)), (PARTIAL regr_sxx(temperature, humidity)), (PARTIAL regr_sxy(temperature, humidity)), (PARTIAL regr_syy(temperature, humidity)), (PARTIAL stddev(temperature)), (PARTIAL stddev_pop(temperature)), (PARTIAL stddev_samp(temperature)), (PARTIAL variance(temperature)), (PARTIAL var_pop(temperature)), (PARTIAL var_samp(temperature)), (PARTIAL last(temperature, timec)), (PARTIAL histogram(temperature, '0'::double precision, '100'::double precision, 1)) + -> Append + -> Custom Scan (DataNodeScan) + Output: conditions.region, (PARTIAL min(conditions.allnull)), (PARTIAL max(conditions.temperature)), (PARTIAL sum(conditions.temperature)), (PARTIAL sum(conditions.humidity)), (PARTIAL avg(conditions.humidity)), (PARTIAL stddev(conditions.humidity)), (PARTIAL bit_and(conditions.bit_int)), (PARTIAL bit_or(conditions.bit_int)), (PARTIAL bool_and(conditions.good_life)), (PARTIAL every((conditions.temperature > '0'::double precision))), (PARTIAL bool_or(conditions.good_life)), (PARTIAL count(*)), (PARTIAL count(conditions.temperature)), (PARTIAL count(conditions.allnull)), (PARTIAL corr(conditions.temperature, conditions.humidity)), (PARTIAL covar_pop(conditions.temperature, conditions.humidity)), (PARTIAL covar_samp(conditions.temperature, conditions.humidity)), (PARTIAL regr_avgx(conditions.temperature, conditions.humidity)), (PARTIAL regr_avgy(conditions.temperature, conditions.humidity)), (PARTIAL regr_count(conditions.temperature, conditions.humidity)), (PARTIAL regr_intercept(conditions.temperature, conditions.humidity)), (PARTIAL regr_r2(conditions.temperature, conditions.humidity)), (PARTIAL regr_slope(conditions.temperature, conditions.humidity)), (PARTIAL regr_sxx(conditions.temperature, conditions.humidity)), (PARTIAL regr_sxy(conditions.temperature, conditions.humidity)), (PARTIAL regr_syy(conditions.temperature, conditions.humidity)), (PARTIAL stddev(conditions.temperature)), (PARTIAL stddev_pop(conditions.temperature)), (PARTIAL stddev_samp(conditions.temperature)), (PARTIAL variance(conditions.temperature)), (PARTIAL var_pop(conditions.temperature)), (PARTIAL var_samp(conditions.temperature)), (PARTIAL last(conditions.temperature, conditions.timec)), (PARTIAL histogram(conditions.temperature, '0'::double precision, '100'::double precision, 1)) + Relations: Aggregate on (public.conditions) + Data node: data_node_1 + Chunks: _hyper_1_1_dist_chunk, _hyper_1_2_dist_chunk, _hyper_1_3_dist_chunk, _hyper_1_4_dist_chunk + Remote SQL: SELECT region, _timescaledb_internal.partialize_agg(min(allnull)), _timescaledb_internal.partialize_agg(max(temperature)), _timescaledb_internal.partialize_agg(sum(temperature)), _timescaledb_internal.partialize_agg(sum(humidity)), _timescaledb_internal.partialize_agg(avg(humidity)), _timescaledb_internal.partialize_agg(stddev(humidity)), _timescaledb_internal.partialize_agg(bit_and(bit_int)), _timescaledb_internal.partialize_agg(bit_or(bit_int)), _timescaledb_internal.partialize_agg(bool_and(good_life)), _timescaledb_internal.partialize_agg(every((temperature > 0::double precision))), _timescaledb_internal.partialize_agg(bool_or(good_life)), _timescaledb_internal.partialize_agg(count(*)), _timescaledb_internal.partialize_agg(count(temperature)), _timescaledb_internal.partialize_agg(count(allnull)), _timescaledb_internal.partialize_agg(corr(temperature, humidity)), _timescaledb_internal.partialize_agg(covar_pop(temperature, humidity)), _timescaledb_internal.partialize_agg(covar_samp(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_avgx(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_avgy(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_count(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_intercept(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_r2(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_slope(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_sxx(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_sxy(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_syy(temperature, humidity)), _timescaledb_internal.partialize_agg(stddev(temperature)), _timescaledb_internal.partialize_agg(stddev_pop(temperature)), _timescaledb_internal.partialize_agg(stddev_samp(temperature)), _timescaledb_internal.partialize_agg(variance(temperature)), _timescaledb_internal.partialize_agg(var_pop(temperature)), _timescaledb_internal.partialize_agg(var_samp(temperature)), _timescaledb_internal.partialize_agg(public.last(temperature, timec)), _timescaledb_internal.partialize_agg(public.histogram(temperature, 0::double precision, 100::double precision, 1)) FROM public.conditions WHERE _timescaledb_internal.chunks_in(conditions, ARRAY[1, 2, 3, 4]) GROUP BY 1 + -> Custom Scan (DataNodeScan) + Output: conditions_1.region, (PARTIAL min(conditions_1.allnull)), (PARTIAL max(conditions_1.temperature)), (PARTIAL sum(conditions_1.temperature)), (PARTIAL sum(conditions_1.humidity)), (PARTIAL avg(conditions_1.humidity)), (PARTIAL stddev(conditions_1.humidity)), (PARTIAL bit_and(conditions_1.bit_int)), (PARTIAL bit_or(conditions_1.bit_int)), (PARTIAL bool_and(conditions_1.good_life)), (PARTIAL every((conditions_1.temperature > '0'::double precision))), (PARTIAL bool_or(conditions_1.good_life)), (PARTIAL count(*)), (PARTIAL count(conditions_1.temperature)), (PARTIAL count(conditions_1.allnull)), (PARTIAL corr(conditions_1.temperature, conditions_1.humidity)), (PARTIAL covar_pop(conditions_1.temperature, conditions_1.humidity)), (PARTIAL covar_samp(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_avgx(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_avgy(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_count(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_intercept(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_r2(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_slope(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_sxx(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_sxy(conditions_1.temperature, conditions_1.humidity)), (PARTIAL regr_syy(conditions_1.temperature, conditions_1.humidity)), (PARTIAL stddev(conditions_1.temperature)), (PARTIAL stddev_pop(conditions_1.temperature)), (PARTIAL stddev_samp(conditions_1.temperature)), (PARTIAL variance(conditions_1.temperature)), (PARTIAL var_pop(conditions_1.temperature)), (PARTIAL var_samp(conditions_1.temperature)), (PARTIAL last(conditions_1.temperature, conditions_1.timec)), (PARTIAL histogram(conditions_1.temperature, '0'::double precision, '100'::double precision, 1)) + Relations: Aggregate on (public.conditions) + Data node: data_node_2 + Chunks: _hyper_1_9_dist_chunk, _hyper_1_10_dist_chunk, _hyper_1_11_dist_chunk, _hyper_1_12_dist_chunk + Remote SQL: SELECT region, _timescaledb_internal.partialize_agg(min(allnull)), _timescaledb_internal.partialize_agg(max(temperature)), _timescaledb_internal.partialize_agg(sum(temperature)), _timescaledb_internal.partialize_agg(sum(humidity)), _timescaledb_internal.partialize_agg(avg(humidity)), _timescaledb_internal.partialize_agg(stddev(humidity)), _timescaledb_internal.partialize_agg(bit_and(bit_int)), _timescaledb_internal.partialize_agg(bit_or(bit_int)), _timescaledb_internal.partialize_agg(bool_and(good_life)), _timescaledb_internal.partialize_agg(every((temperature > 0::double precision))), _timescaledb_internal.partialize_agg(bool_or(good_life)), _timescaledb_internal.partialize_agg(count(*)), _timescaledb_internal.partialize_agg(count(temperature)), _timescaledb_internal.partialize_agg(count(allnull)), _timescaledb_internal.partialize_agg(corr(temperature, humidity)), _timescaledb_internal.partialize_agg(covar_pop(temperature, humidity)), _timescaledb_internal.partialize_agg(covar_samp(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_avgx(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_avgy(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_count(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_intercept(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_r2(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_slope(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_sxx(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_sxy(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_syy(temperature, humidity)), _timescaledb_internal.partialize_agg(stddev(temperature)), _timescaledb_internal.partialize_agg(stddev_pop(temperature)), _timescaledb_internal.partialize_agg(stddev_samp(temperature)), _timescaledb_internal.partialize_agg(variance(temperature)), _timescaledb_internal.partialize_agg(var_pop(temperature)), _timescaledb_internal.partialize_agg(var_samp(temperature)), _timescaledb_internal.partialize_agg(public.last(temperature, timec)), _timescaledb_internal.partialize_agg(public.histogram(temperature, 0::double precision, 100::double precision, 1)) FROM public.conditions WHERE _timescaledb_internal.chunks_in(conditions, ARRAY[1, 2, 3, 4]) GROUP BY 1 + -> Custom Scan (DataNodeScan) + Output: conditions_2.region, (PARTIAL min(conditions_2.allnull)), (PARTIAL max(conditions_2.temperature)), (PARTIAL sum(conditions_2.temperature)), (PARTIAL sum(conditions_2.humidity)), (PARTIAL avg(conditions_2.humidity)), (PARTIAL stddev(conditions_2.humidity)), (PARTIAL bit_and(conditions_2.bit_int)), (PARTIAL bit_or(conditions_2.bit_int)), (PARTIAL bool_and(conditions_2.good_life)), (PARTIAL every((conditions_2.temperature > '0'::double precision))), (PARTIAL bool_or(conditions_2.good_life)), (PARTIAL count(*)), (PARTIAL count(conditions_2.temperature)), (PARTIAL count(conditions_2.allnull)), (PARTIAL corr(conditions_2.temperature, conditions_2.humidity)), (PARTIAL covar_pop(conditions_2.temperature, conditions_2.humidity)), (PARTIAL covar_samp(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_avgx(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_avgy(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_count(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_intercept(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_r2(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_slope(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_sxx(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_sxy(conditions_2.temperature, conditions_2.humidity)), (PARTIAL regr_syy(conditions_2.temperature, conditions_2.humidity)), (PARTIAL stddev(conditions_2.temperature)), (PARTIAL stddev_pop(conditions_2.temperature)), (PARTIAL stddev_samp(conditions_2.temperature)), (PARTIAL variance(conditions_2.temperature)), (PARTIAL var_pop(conditions_2.temperature)), (PARTIAL var_samp(conditions_2.temperature)), (PARTIAL last(conditions_2.temperature, conditions_2.timec)), (PARTIAL histogram(conditions_2.temperature, '0'::double precision, '100'::double precision, 1)) + Relations: Aggregate on (public.conditions) + Data node: data_node_3 + Chunks: _hyper_1_5_dist_chunk, _hyper_1_6_dist_chunk, _hyper_1_7_dist_chunk, _hyper_1_8_dist_chunk + Remote SQL: SELECT region, _timescaledb_internal.partialize_agg(min(allnull)), _timescaledb_internal.partialize_agg(max(temperature)), _timescaledb_internal.partialize_agg(sum(temperature)), _timescaledb_internal.partialize_agg(sum(humidity)), _timescaledb_internal.partialize_agg(avg(humidity)), _timescaledb_internal.partialize_agg(stddev(humidity)), _timescaledb_internal.partialize_agg(bit_and(bit_int)), _timescaledb_internal.partialize_agg(bit_or(bit_int)), _timescaledb_internal.partialize_agg(bool_and(good_life)), _timescaledb_internal.partialize_agg(every((temperature > 0::double precision))), _timescaledb_internal.partialize_agg(bool_or(good_life)), _timescaledb_internal.partialize_agg(count(*)), _timescaledb_internal.partialize_agg(count(temperature)), _timescaledb_internal.partialize_agg(count(allnull)), _timescaledb_internal.partialize_agg(corr(temperature, humidity)), _timescaledb_internal.partialize_agg(covar_pop(temperature, humidity)), _timescaledb_internal.partialize_agg(covar_samp(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_avgx(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_avgy(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_count(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_intercept(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_r2(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_slope(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_sxx(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_sxy(temperature, humidity)), _timescaledb_internal.partialize_agg(regr_syy(temperature, humidity)), _timescaledb_internal.partialize_agg(stddev(temperature)), _timescaledb_internal.partialize_agg(stddev_pop(temperature)), _timescaledb_internal.partialize_agg(stddev_samp(temperature)), _timescaledb_internal.partialize_agg(variance(temperature)), _timescaledb_internal.partialize_agg(var_pop(temperature)), _timescaledb_internal.partialize_agg(var_samp(temperature)), _timescaledb_internal.partialize_agg(public.last(temperature, timec)), _timescaledb_internal.partialize_agg(public.histogram(temperature, 0::double precision, 100::double precision, 1)) FROM public.conditions WHERE _timescaledb_internal.chunks_in(conditions, ARRAY[1, 2, 3, 4]) GROUP BY 1 +(27 rows) -- Aggregates on custom types are not yet pushed down :PREFIX SELECT :GROUPING, @@ -473,7 +475,7 @@ SELECT format('\! diff %s %s', :'RESULTS_CONTROL2', :'RESULTS_TEST2') as "DIFF_C \gset --generate the results into two different files \set ECHO errors --- Note that some difference in output is expected here because +-- Note that some difference in output could happen here because -- queries include last(col, time) and first(col, time); there are -- multiple values for "col" that has the same timestamp, so the -- output depends on the order of arriving tuples. diff --git a/tsl/test/expected/partitionwise_distributed-11.out b/tsl/test/expected/partitionwise_distributed-11.out index eb2100a5b..762c5368b 100644 --- a/tsl/test/expected/partitionwise_distributed-11.out +++ b/tsl/test/expected/partitionwise_distributed-11.out @@ -715,28 +715,30 @@ SELECT device, avg(temp) FROM hyper GROUP BY 1 ORDER BY 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Finalize GroupAggregate - Output: device, avg(temp) - Group Key: device - -> Custom Scan (AsyncAppend) - Output: device, (PARTIAL avg(temp)) - -> Merge Append - Sort Key: hyper.device - -> Custom Scan (DataNodeScan) - Output: hyper.device, (PARTIAL avg(hyper.temp)) - Relations: Aggregate on (public.hyper) - Data node: data_node_1 - Chunks: _hyper_1_1_dist_chunk, _hyper_1_3_dist_chunk, _hyper_1_5_dist_chunk, _hyper_1_7_dist_chunk - Remote SQL: SELECT device, _timescaledb_internal.partialize_agg(avg(temp)) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[1, 2, 3, 4]) GROUP BY 1 ORDER BY device ASC NULLS LAST - -> Custom Scan (DataNodeScan) - Output: hyper_1.device, (PARTIAL avg(hyper_1.temp)) - Relations: Aggregate on (public.hyper) - Data node: data_node_2 - Chunks: _hyper_1_2_dist_chunk, _hyper_1_4_dist_chunk, _hyper_1_6_dist_chunk - Remote SQL: SELECT device, _timescaledb_internal.partialize_agg(avg(temp)) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[1, 2, 3]) GROUP BY 1 ORDER BY device ASC NULLS LAST -(19 rows) + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: device, (avg(temp)) + Sort Key: device + -> Finalize HashAggregate + Output: device, avg(temp) + Group Key: device + -> Custom Scan (AsyncAppend) + Output: device, (PARTIAL avg(temp)) + -> Append + -> Custom Scan (DataNodeScan) + Output: hyper.device, (PARTIAL avg(hyper.temp)) + Relations: Aggregate on (public.hyper) + Data node: data_node_1 + Chunks: _hyper_1_1_dist_chunk, _hyper_1_3_dist_chunk, _hyper_1_5_dist_chunk, _hyper_1_7_dist_chunk + Remote SQL: SELECT device, _timescaledb_internal.partialize_agg(avg(temp)) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[1, 2, 3, 4]) GROUP BY 1 + -> Custom Scan (DataNodeScan) + Output: hyper_1.device, (PARTIAL avg(hyper_1.temp)) + Relations: Aggregate on (public.hyper) + Data node: data_node_2 + Chunks: _hyper_1_2_dist_chunk, _hyper_1_4_dist_chunk, _hyper_1_6_dist_chunk + Remote SQL: SELECT device, _timescaledb_internal.partialize_agg(avg(temp)) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[1, 2, 3]) GROUP BY 1 +(21 rows) -- Show result SELECT device, avg(temp) @@ -1236,25 +1238,29 @@ FROM hyper WHERE time BETWEEN '2018-04-19 00:01' AND '2018-06-01 00:00' GROUP BY 1, 2 ORDER BY 1, 2; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Custom Scan (AsyncAppend) Output: "time", device, (avg(temp)) -> Merge Append Sort Key: hyper."time", hyper.device - -> Custom Scan (DataNodeScan) - Output: hyper."time", hyper.device, (avg(hyper.temp)) - Relations: Aggregate on (public.hyper) - Data node: data_node_1 - Chunks: _hyper_1_3_dist_chunk - Remote SQL: SELECT "time", device, avg(temp) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) GROUP BY 1, 2 ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST - -> Custom Scan (DataNodeScan) - Output: hyper_1."time", hyper_1.device, (avg(hyper_1.temp)) - Relations: Aggregate on (public.hyper) - Data node: data_node_2 - Chunks: _hyper_1_4_dist_chunk - Remote SQL: SELECT "time", device, avg(temp) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) GROUP BY 1, 2 ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST -(16 rows) + -> GroupAggregate + Output: hyper."time", hyper.device, avg(hyper.temp) + Group Key: hyper."time", hyper.device + -> Custom Scan (DataNodeScan) on public.hyper + Output: hyper."time", hyper.device, hyper.temp + Data node: data_node_1 + Chunks: _hyper_1_3_dist_chunk + Remote SQL: SELECT "time", device, temp FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST + -> GroupAggregate + Output: hyper_1."time", hyper_1.device, avg(hyper_1.temp) + Group Key: hyper_1."time", hyper_1.device + -> Custom Scan (DataNodeScan) on public.hyper hyper_1 + Output: hyper_1."time", hyper_1.device, hyper_1.temp + Data node: data_node_2 + Chunks: _hyper_1_4_dist_chunk + Remote SQL: SELECT "time", device, temp FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST +(20 rows) -- Test HAVING qual EXPLAIN (VERBOSE, COSTS OFF) @@ -1306,25 +1312,31 @@ WHERE time BETWEEN '2018-04-19 00:01' AND '2018-06-01 00:00' GROUP BY 1, 2 HAVING avg(temp) > 4 ORDER BY 1, 2; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Custom Scan (AsyncAppend) Output: "time", device, (avg(temp)) -> Merge Append Sort Key: hyper."time", hyper.device - -> Custom Scan (DataNodeScan) - Output: hyper."time", hyper.device, (avg(hyper.temp)) - Relations: Aggregate on (public.hyper) - Data node: data_node_1 - Chunks: _hyper_1_3_dist_chunk - Remote SQL: SELECT "time", device, avg(temp) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) GROUP BY 1, 2 HAVING ((avg(temp) > 4::double precision)) ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST - -> Custom Scan (DataNodeScan) - Output: hyper_1."time", hyper_1.device, (avg(hyper_1.temp)) - Relations: Aggregate on (public.hyper) - Data node: data_node_2 - Chunks: _hyper_1_4_dist_chunk - Remote SQL: SELECT "time", device, avg(temp) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) GROUP BY 1, 2 HAVING ((avg(temp) > 4::double precision)) ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST -(16 rows) + -> GroupAggregate + Output: hyper."time", hyper.device, avg(hyper.temp) + Group Key: hyper."time", hyper.device + Filter: (avg(hyper.temp) > '4'::double precision) + -> Custom Scan (DataNodeScan) on public.hyper + Output: hyper."time", hyper.device, hyper.temp + Data node: data_node_1 + Chunks: _hyper_1_3_dist_chunk + Remote SQL: SELECT "time", device, temp FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST + -> GroupAggregate + Output: hyper_1."time", hyper_1.device, avg(hyper_1.temp) + Group Key: hyper_1."time", hyper_1.device + Filter: (avg(hyper_1.temp) > '4'::double precision) + -> Custom Scan (DataNodeScan) on public.hyper hyper_1 + Output: hyper_1."time", hyper_1.device, hyper_1.temp + Data node: data_node_2 + Chunks: _hyper_1_4_dist_chunk + Remote SQL: SELECT "time", device, temp FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST +(22 rows) SELECT time, device, avg(temp) AS temp FROM hyper diff --git a/tsl/test/expected/partitionwise_distributed-12.out b/tsl/test/expected/partitionwise_distributed-12.out index f2e19c677..4bc6d5478 100644 --- a/tsl/test/expected/partitionwise_distributed-12.out +++ b/tsl/test/expected/partitionwise_distributed-12.out @@ -715,28 +715,30 @@ SELECT device, avg(temp) FROM hyper GROUP BY 1 ORDER BY 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Finalize GroupAggregate - Output: device, avg(temp) - Group Key: device - -> Custom Scan (AsyncAppend) - Output: device, (PARTIAL avg(temp)) - -> Merge Append - Sort Key: hyper.device - -> Custom Scan (DataNodeScan) - Output: hyper.device, (PARTIAL avg(hyper.temp)) - Relations: Aggregate on (public.hyper) - Data node: data_node_1 - Chunks: _hyper_1_1_dist_chunk, _hyper_1_3_dist_chunk, _hyper_1_5_dist_chunk, _hyper_1_7_dist_chunk - Remote SQL: SELECT device, _timescaledb_internal.partialize_agg(avg(temp)) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[1, 2, 3, 4]) GROUP BY 1 ORDER BY device ASC NULLS LAST - -> Custom Scan (DataNodeScan) - Output: hyper_1.device, (PARTIAL avg(hyper_1.temp)) - Relations: Aggregate on (public.hyper) - Data node: data_node_2 - Chunks: _hyper_1_2_dist_chunk, _hyper_1_4_dist_chunk, _hyper_1_6_dist_chunk - Remote SQL: SELECT device, _timescaledb_internal.partialize_agg(avg(temp)) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[1, 2, 3]) GROUP BY 1 ORDER BY device ASC NULLS LAST -(19 rows) + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: device, (avg(temp)) + Sort Key: device + -> Finalize HashAggregate + Output: device, avg(temp) + Group Key: device + -> Custom Scan (AsyncAppend) + Output: device, (PARTIAL avg(temp)) + -> Append + -> Custom Scan (DataNodeScan) + Output: hyper.device, (PARTIAL avg(hyper.temp)) + Relations: Aggregate on (public.hyper) + Data node: data_node_1 + Chunks: _hyper_1_1_dist_chunk, _hyper_1_3_dist_chunk, _hyper_1_5_dist_chunk, _hyper_1_7_dist_chunk + Remote SQL: SELECT device, _timescaledb_internal.partialize_agg(avg(temp)) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[1, 2, 3, 4]) GROUP BY 1 + -> Custom Scan (DataNodeScan) + Output: hyper_1.device, (PARTIAL avg(hyper_1.temp)) + Relations: Aggregate on (public.hyper) + Data node: data_node_2 + Chunks: _hyper_1_2_dist_chunk, _hyper_1_4_dist_chunk, _hyper_1_6_dist_chunk + Remote SQL: SELECT device, _timescaledb_internal.partialize_agg(avg(temp)) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[1, 2, 3]) GROUP BY 1 +(21 rows) -- Show result SELECT device, avg(temp) @@ -1236,25 +1238,29 @@ FROM hyper WHERE time BETWEEN '2018-04-19 00:01' AND '2018-06-01 00:00' GROUP BY 1, 2 ORDER BY 1, 2; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Custom Scan (AsyncAppend) Output: "time", device, (avg(temp)) -> Merge Append Sort Key: hyper."time", hyper.device - -> Custom Scan (DataNodeScan) - Output: hyper."time", hyper.device, (avg(hyper.temp)) - Relations: Aggregate on (public.hyper) - Data node: data_node_1 - Chunks: _hyper_1_3_dist_chunk - Remote SQL: SELECT "time", device, avg(temp) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) GROUP BY 1, 2 ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST - -> Custom Scan (DataNodeScan) - Output: hyper_1."time", hyper_1.device, (avg(hyper_1.temp)) - Relations: Aggregate on (public.hyper) - Data node: data_node_2 - Chunks: _hyper_1_4_dist_chunk - Remote SQL: SELECT "time", device, avg(temp) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) GROUP BY 1, 2 ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST -(16 rows) + -> GroupAggregate + Output: hyper."time", hyper.device, avg(hyper.temp) + Group Key: hyper."time", hyper.device + -> Custom Scan (DataNodeScan) on public.hyper + Output: hyper."time", hyper.device, hyper.temp + Data node: data_node_1 + Chunks: _hyper_1_3_dist_chunk + Remote SQL: SELECT "time", device, temp FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST + -> GroupAggregate + Output: hyper_1."time", hyper_1.device, avg(hyper_1.temp) + Group Key: hyper_1."time", hyper_1.device + -> Custom Scan (DataNodeScan) on public.hyper hyper_1 + Output: hyper_1."time", hyper_1.device, hyper_1.temp + Data node: data_node_2 + Chunks: _hyper_1_4_dist_chunk + Remote SQL: SELECT "time", device, temp FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST +(20 rows) -- Test HAVING qual EXPLAIN (VERBOSE, COSTS OFF) @@ -1306,25 +1312,31 @@ WHERE time BETWEEN '2018-04-19 00:01' AND '2018-06-01 00:00' GROUP BY 1, 2 HAVING avg(temp) > 4 ORDER BY 1, 2; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Custom Scan (AsyncAppend) Output: "time", device, (avg(temp)) -> Merge Append Sort Key: hyper."time", hyper.device - -> Custom Scan (DataNodeScan) - Output: hyper."time", hyper.device, (avg(hyper.temp)) - Relations: Aggregate on (public.hyper) - Data node: data_node_1 - Chunks: _hyper_1_3_dist_chunk - Remote SQL: SELECT "time", device, avg(temp) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) GROUP BY 1, 2 HAVING ((avg(temp) > 4::double precision)) ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST - -> Custom Scan (DataNodeScan) - Output: hyper_1."time", hyper_1.device, (avg(hyper_1.temp)) - Relations: Aggregate on (public.hyper) - Data node: data_node_2 - Chunks: _hyper_1_4_dist_chunk - Remote SQL: SELECT "time", device, avg(temp) FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) GROUP BY 1, 2 HAVING ((avg(temp) > 4::double precision)) ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST -(16 rows) + -> GroupAggregate + Output: hyper."time", hyper.device, avg(hyper.temp) + Group Key: hyper."time", hyper.device + Filter: (avg(hyper.temp) > '4'::double precision) + -> Custom Scan (DataNodeScan) on public.hyper + Output: hyper."time", hyper.device, hyper.temp + Data node: data_node_1 + Chunks: _hyper_1_3_dist_chunk + Remote SQL: SELECT "time", device, temp FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST + -> GroupAggregate + Output: hyper_1."time", hyper_1.device, avg(hyper_1.temp) + Group Key: hyper_1."time", hyper_1.device + Filter: (avg(hyper_1.temp) > '4'::double precision) + -> Custom Scan (DataNodeScan) on public.hyper hyper_1 + Output: hyper_1."time", hyper_1.device, hyper_1.temp + Data node: data_node_2 + Chunks: _hyper_1_4_dist_chunk + Remote SQL: SELECT "time", device, temp FROM public.hyper WHERE _timescaledb_internal.chunks_in(hyper, ARRAY[2]) AND (("time" >= '2018-04-19 00:01:00-07'::timestamp with time zone)) AND (("time" <= '2018-06-01 00:00:00-07'::timestamp with time zone)) ORDER BY "time" ASC NULLS LAST, device ASC NULLS LAST +(22 rows) SELECT time, device, avg(temp) AS temp FROM hyper diff --git a/tsl/test/sql/dist_partial_agg.sql b/tsl/test/sql/dist_partial_agg.sql index 84a94f8db..7d399f0d3 100644 --- a/tsl/test/sql/dist_partial_agg.sql +++ b/tsl/test/sql/dist_partial_agg.sql @@ -99,7 +99,7 @@ SET enable_partitionwise_aggregate = ON; \o \set ECHO all --- Note that some difference in output is expected here because +-- Note that some difference in output could happen here because -- queries include last(col, time) and first(col, time); there are -- multiple values for "col" that has the same timestamp, so the -- output depends on the order of arriving tuples.