From 844412c34365bdea0b70f2e6d2ff25c9cd74c8ac Mon Sep 17 00:00:00 2001 From: Jan Nidzwetzki Date: Tue, 22 Aug 2023 13:53:15 +0200 Subject: [PATCH] Support for partial aggregations at chunk level This patch adds support for partial aggregations at the chunk level. The aggregation is replanned in the create_upper_paths_hook of PostgreSQL. The AggPath is split up into multiple AGGSPLIT_INITIAL_SERIAL operations (one on top of each chunk), which create partials, and one AGGSPLIT_FINAL_DESERIAL operation, which finalizes the aggregation. --- .unreleased/feature_5596 | 1 + src/guc.c | 13 + src/guc.h | 1 + src/nodes/chunk_append/planner.c | 1 + src/planner/partialize.c | 684 ++++++++++++++++++ src/planner/partialize.h | 5 + src/planner/planner.c | 10 +- test/expected/agg_bookends.out | 498 ++++++++----- test/expected/append-13.out | 124 ++-- test/expected/append-14.out | 124 ++-- test/expected/append-15.out | 124 ++-- test/expected/parallel-13.out | 137 ++-- test/expected/parallel-14.out | 137 ++-- test/expected/parallel-15.out | 137 ++-- test/expected/partitionwise.out | 177 +++-- test/expected/sql_query.out | 38 +- .../nodes/decompress_chunk/decompress_chunk.c | 9 + .../nodes/decompress_chunk/decompress_chunk.h | 2 + tsl/test/expected/agg_partials_pushdown.out | 424 +++++++++++ tsl/test/expected/compression.out | 29 +- tsl/test/expected/compression_ddl.out | 180 +++-- .../expected/compression_qualpushdown.out | 30 +- .../merge_append_partially_compressed-13.out | 35 +- .../merge_append_partially_compressed-14.out | 44 +- .../merge_append_partially_compressed-15.out | 44 +- tsl/test/expected/partialize_finalize.out | 208 +++++- .../expected/transparent_decompression-13.out | 486 ++++++++----- .../expected/transparent_decompression-14.out | 486 ++++++++----- .../expected/transparent_decompression-15.out | 486 ++++++++----- tsl/test/shared/expected/constify_now-13.out | 40 +- tsl/test/shared/expected/constify_now-14.out | 40 +- tsl/test/shared/expected/constify_now-15.out | 40 +- .../shared/expected/dist_parallel_agg.out | 40 +- .../shared/expected/ordered_append-13.out | 368 ++++++---- .../shared/expected/ordered_append-14.out | 368 ++++++---- .../shared/expected/ordered_append-15.out | 368 ++++++---- .../expected/ordered_append_join-13.out | 163 +++-- .../expected/ordered_append_join-14.out | 163 +++-- .../expected/ordered_append_join-15.out | 163 +++-- .../shared/sql/include/ordered_append.sql | 4 + .../sql/include/ordered_append_join.sql | 10 + .../shared/sql/ordered_append_join.sql.in | 2 + tsl/test/sql/CMakeLists.txt | 1 + tsl/test/sql/agg_partials_pushdown.sql | 109 +++ tsl/test/sql/compression.sql | 6 + .../transparent_decompression_query.sql | 4 + 46 files changed, 4653 insertions(+), 1910 deletions(-) create mode 100644 .unreleased/feature_5596 create mode 100644 tsl/test/expected/agg_partials_pushdown.out create mode 100644 tsl/test/sql/agg_partials_pushdown.sql diff --git a/.unreleased/feature_5596 b/.unreleased/feature_5596 new file mode 100644 index 00000000000..45aebe0c07b --- /dev/null +++ b/.unreleased/feature_5596 @@ -0,0 +1 @@ +Implements: #5596 Support for partial aggregations at chunk level diff --git a/src/guc.c b/src/guc.c index 028ebf8bcd3..5027c930229 100644 --- a/src/guc.c +++ b/src/guc.c @@ -83,6 +83,7 @@ TSDLLEXPORT bool ts_guc_enable_decompression_sorted_merge = true; bool ts_guc_enable_per_data_node_queries = true; bool ts_guc_enable_parameterized_data_node_scan = true; bool ts_guc_enable_async_append = true; +bool ts_guc_enable_chunkwise_aggregation = true; TSDLLEXPORT bool ts_guc_enable_compression_indexscan = true; TSDLLEXPORT bool ts_guc_enable_bulk_decompression = true; TSDLLEXPORT bool ts_guc_enable_skip_scan = true; @@ -557,6 +558,18 @@ _guc_init(void) NULL, NULL); + DefineCustomBoolVariable("timescaledb.enable_chunkwise_aggregation", + "Enable chunk-wise aggregation", + "Enable the pushdown of aggregations to the" + " chunk level", + &ts_guc_enable_chunkwise_aggregation, + true, + PGC_USERSET, + 0, + NULL, + NULL, + NULL); + DefineCustomBoolVariable("timescaledb.enable_remote_explain", "Show explain from remote nodes when using VERBOSE flag", "Enable getting and showing EXPLAIN output from remote nodes", diff --git a/src/guc.h b/src/guc.h index 12a1836f5dd..409ba38df7c 100644 --- a/src/guc.h +++ b/src/guc.h @@ -35,6 +35,7 @@ extern TSDLLEXPORT bool ts_guc_enable_per_data_node_queries; extern TSDLLEXPORT bool ts_guc_enable_parameterized_data_node_scan; extern TSDLLEXPORT bool ts_guc_enable_async_append; extern TSDLLEXPORT bool ts_guc_enable_skip_scan; +extern TSDLLEXPORT bool ts_guc_enable_chunkwise_aggregation; extern bool ts_guc_restoring; extern int ts_guc_max_open_chunks_per_insert; extern int ts_guc_max_cached_chunks_per_hypertable; diff --git a/src/nodes/chunk_append/planner.c b/src/nodes/chunk_append/planner.c index c8ab310f376..56919af2c03 100644 --- a/src/nodes/chunk_append/planner.c +++ b/src/nodes/chunk_append/planner.c @@ -402,6 +402,7 @@ ts_chunk_append_get_scan_plan(Plan *plan) return NULL; break; case T_MergeAppend: + case T_Agg: return NULL; break; default: diff --git a/src/planner/partialize.c b/src/planner/partialize.c index 0bcb090a51d..be39e788ae4 100644 --- a/src/planner/partialize.c +++ b/src/planner/partialize.c @@ -9,16 +9,28 @@ #include #include #include +#include +#include #include #include +#include +#include #include +#include #include #include #include +#include "debug_assert.h" +#include "partialize.h" #include "planner.h" +#include "gapfill.h" +#include "nodes/print.h" #include "extension_constants.h" #include "utils.h" +#include "estimate.h" +#include "nodes/chunk_append/chunk_append.h" +#include "import/planner.h" #define TS_PARTIALFN "partialize_agg" @@ -185,6 +197,678 @@ partialize_agg_paths(RelOptInfo *rel) return has_combine; } +/* Helper function to find the first node of the provided type in the pathlist of the relation */ +static Node * +find_node(const RelOptInfo *relation, NodeTag type) +{ + ListCell *lc; + foreach (lc, relation->pathlist) + { + Node *node = lfirst(lc); + if (nodeTag(node) == type) + return node; + } + + return NULL; +} + +/* Check if the relation already has a min/max path */ +static bool +has_min_max_agg_path(const RelOptInfo *relation) +{ + return find_node(relation, T_MinMaxAggPath) != NULL; +} + +/* + * Get an an existing aggregation path for the given relation or NULL if no aggregation path exists. + */ +static AggPath * +get_existing_agg_path(const RelOptInfo *relation) +{ + Node *node = find_node(relation, T_AggPath); + return node ? castNode(AggPath, node) : NULL; +} + +/* + * Get all subpaths from a Append, MergeAppend, or ChunkAppend path + */ +static List * +get_subpaths_from_append_path(Path *path, bool handle_gather_path) +{ + if (IsA(path, AppendPath)) + { + AppendPath *append_path = castNode(AppendPath, path); + return append_path->subpaths; + } + else if (IsA(path, MergeAppendPath)) + { + MergeAppendPath *merge_append_path = castNode(MergeAppendPath, path); + return merge_append_path->subpaths; + } + else if (ts_is_chunk_append_path(path)) + { + CustomPath *custom_path = castNode(CustomPath, path); + return custom_path->custom_paths; + } + else if (handle_gather_path && IsA(path, GatherPath)) + { + return get_subpaths_from_append_path(castNode(GatherPath, path)->subpath, false); + } + + /* Aggregation push-down is not supported for other path types so far */ + return NIL; +} + +/* + * Copy an AppendPath and set new subpaths. + */ +static AppendPath * +copy_append_path(AppendPath *path, List *subpaths) +{ + AppendPath *newPath = makeNode(AppendPath); + memcpy(newPath, path, sizeof(AppendPath)); + newPath->subpaths = subpaths; + cost_append(newPath); + + return newPath; +} + +/* + * Copy a MergeAppendPath and set new subpaths. + */ +static MergeAppendPath * +copy_merge_append_path(PlannerInfo *root, MergeAppendPath *path, List *subpaths) +{ + MergeAppendPath *newPath = create_merge_append_path_compat(root, + path->path.parent, + subpaths, + path->path.pathkeys, + NULL, + path->partitioned_rels); + +#if PG14_LT + newPath->partitioned_rels = list_copy(path->partitioned_rels); +#endif + + newPath->path.param_info = path->path.param_info; + + return newPath; +} + +/* + * Copy an append-like path and set new subpaths + */ +static Path * +copy_append_like_path(PlannerInfo *root, Path *path, List *new_subpaths, PathTarget *pathtarget) +{ + if (IsA(path, AppendPath)) + { + AppendPath *append_path = castNode(AppendPath, path); + append_path->path.pathtarget = pathtarget; + return (Path *) copy_append_path(append_path, new_subpaths); + } + else if (IsA(path, MergeAppendPath)) + { + MergeAppendPath *merge_append_path = castNode(MergeAppendPath, path); + merge_append_path->path.pathtarget = pathtarget; + return (Path *) copy_merge_append_path(root, merge_append_path, new_subpaths); + } + else if (ts_is_chunk_append_path(path)) + { + CustomPath *custom_path = castNode(CustomPath, path); + ChunkAppendPath *chunk_append_path = (ChunkAppendPath *) custom_path; + chunk_append_path->cpath.path.pathtarget = pathtarget; + return (Path *) ts_chunk_append_path_copy(chunk_append_path, new_subpaths); + } + + /* Should never happen, already checked by caller */ + Ensure(false, "unknown path type"); + pg_unreachable(); +} + +/* + * Generate a partially sorted aggregated agg path on top of a path + */ +static Path * +create_sorted_partial_agg_path(PlannerInfo *root, Path *path, PathTarget *target, + double d_num_groups, GroupPathExtraData *extra_data) +{ + Query *parse = root->parse; + + /* Determine costs for aggregations */ + AggClauseCosts *agg_partial_costs = &extra_data->agg_partial_costs; + + bool is_sorted = pathkeys_contained_in(root->group_pathkeys, path->pathkeys); + + if (!is_sorted) + { + path = (Path *) create_sort_path(root, path->parent, path, root->group_pathkeys, -1.0); + } + + Path *sorted_agg_path = (Path *) create_agg_path(root, + path->parent, + path, + target, + parse->groupClause ? AGG_SORTED : AGG_PLAIN, + AGGSPLIT_INITIAL_SERIAL, + parse->groupClause, + NIL, + agg_partial_costs, + d_num_groups); + + return sorted_agg_path; +} + +/* + * Generate a partially hashed aggregated add path on top of a path + */ +static Path * +create_hashed_partial_agg_path(PlannerInfo *root, Path *path, PathTarget *target, + double d_num_groups, GroupPathExtraData *extra_data) +{ + Query *parse = root->parse; + + /* Determine costs for aggregations */ + AggClauseCosts *agg_partial_costs = &extra_data->agg_partial_costs; + + Path *hash_path = (Path *) create_agg_path(root, + path->parent, + path, + target, + AGG_HASHED, + AGGSPLIT_INITIAL_SERIAL, + parse->groupClause, + NIL, + agg_partial_costs, + d_num_groups); + return hash_path; +} + +/* + * Add partially aggregated subpath + */ +static void +add_partially_aggregated_subpaths(PlannerInfo *root, Path *parent_path, + PathTarget *partial_grouping_target, double d_num_groups, + GroupPathExtraData *extra_data, bool can_sort, bool can_hash, + Path *subpath, List **sorted_paths, List **hashed_paths) +{ + /* Translate targetlist for partition */ + AppendRelInfo *appinfo = ts_get_appendrelinfo(root, subpath->parent->relid, false); + PathTarget *chunktarget = copy_pathtarget(partial_grouping_target); + chunktarget->exprs = + castNode(List, adjust_appendrel_attrs(root, (Node *) chunktarget->exprs, 1, &appinfo)); + + /* In declarative partitioning planning, this is done by appy_scanjoin_target_to_path */ + Assert(list_length(subpath->pathtarget->exprs) == list_length(parent_path->pathtarget->exprs)); + subpath->pathtarget->sortgrouprefs = parent_path->pathtarget->sortgrouprefs; + + if (can_sort) + { + *sorted_paths = lappend(*sorted_paths, + create_sorted_partial_agg_path(root, + subpath, + chunktarget, + d_num_groups, + extra_data)); + } + + if (can_hash) + { + *hashed_paths = lappend(*hashed_paths, + create_hashed_partial_agg_path(root, + subpath, + chunktarget, + d_num_groups, + extra_data)); + } +} + +/* + * Generate a total aggregation path for partial aggregations. + * + * The generated paths contain partial aggregations (created by using AGGSPLIT_INITIAL_SERIAL). + * These aggregations need to be finished by the caller by adding a node that performs the + * AGGSPLIT_FINAL_DESERIAL step. + */ +static void +generate_agg_pushdown_path(PlannerInfo *root, Path *cheapest_total_path, RelOptInfo *output_rel, + RelOptInfo *partially_grouped_rel, PathTarget *grouping_target, + PathTarget *partial_grouping_target, bool can_sort, bool can_hash, + double d_num_groups, GroupPathExtraData *extra_data) +{ + /* Get subpaths */ + List *subpaths = get_subpaths_from_append_path(cheapest_total_path, false); + + /* No subpaths available or unsupported append node */ + if (subpaths == NIL) + return; + + /* Generate agg paths on top of the append children */ + List *sorted_subpaths = NIL; + List *hashed_subpaths = NIL; + + ListCell *lc; + foreach (lc, subpaths) + { + Path *subpath = lfirst(lc); + + /* Check if we have an append path under an append path (e.g., a partially compressed + * chunk. The first append path merges the chunk results. The second append path merges the + * uncompressed and the compressed part of the chunk). + * + * In this case, the partial aggregation needs to be pushed down below the lower + * append path. + */ + List *subsubpaths = get_subpaths_from_append_path(subpath, false); + + if (subsubpaths != NIL) + { + List *sorted_subsubpaths = NIL; + List *hashed_subsubpaths = NIL; + + ListCell *lc2; + foreach (lc2, subsubpaths) + { + Path *subsubpath = lfirst(lc2); + + add_partially_aggregated_subpaths(root, + cheapest_total_path, + partial_grouping_target, + d_num_groups, + extra_data, + can_sort, + can_hash, + subsubpath, + &sorted_subsubpaths /* Result path */, + &hashed_subsubpaths /* Result path */); + } + + if (can_sort) + { + sorted_subpaths = lappend(sorted_subpaths, + copy_append_like_path(root, + subpath, + sorted_subsubpaths, + subpath->pathtarget)); + } + + if (can_hash) + { + hashed_subpaths = lappend(hashed_subpaths, + copy_append_like_path(root, + subpath, + hashed_subsubpaths, + subpath->pathtarget)); + } + } + else + { + add_partially_aggregated_subpaths(root, + cheapest_total_path, + partial_grouping_target, + d_num_groups, + extra_data, + can_sort, + can_hash, + subpath, + &sorted_subpaths /* Result paths */, + &hashed_subpaths /* Result paths */); + } + } + + /* Create new append paths */ + if (sorted_subpaths != NIL) + { + add_path(partially_grouped_rel, + copy_append_like_path(root, + cheapest_total_path, + sorted_subpaths, + partial_grouping_target)); + } + + if (hashed_subpaths != NIL) + { + add_path(partially_grouped_rel, + copy_append_like_path(root, + cheapest_total_path, + hashed_subpaths, + partial_grouping_target)); + } +} + +/* + * Generate a partial aggregation path for chunk-wise partial aggregations. + + * This function does almost the same as generate_agg_pushdown_path(). In contrast, it processes a + * partial_path (paths that are usually used in parallel plans) of the input relation, pushes down + * the aggregation in this path and adds a gather node on top of the partial plan. Therefore, the + * push-down of the partial aggregates also works in parallel plans. + * + * Note: The PostgreSQL terminology can cause some confusion here. Partial paths are usually used by + * PostgreSQL to distribute work between parallel workers. This has nothing to do with the partial + * aggregation we are creating in the function. + */ +static void +generate_partial_agg_pushdown_path(PlannerInfo *root, Path *cheapest_partial_path, + RelOptInfo *output_rel, RelOptInfo *partially_grouped_rel, + PathTarget *grouping_target, PathTarget *partial_grouping_target, + bool can_sort, bool can_hash, double d_num_groups, + GroupPathExtraData *extra_data) +{ + /* Get subpaths */ + List *subpaths = get_subpaths_from_append_path(cheapest_partial_path, false); + + /* No subpaths available or unsupported append node */ + if (subpaths == NIL) + return; + + /* Generate agg paths on top of the append children */ + ListCell *lc; + List *sorted_subpaths = NIL; + List *hashed_subpaths = NIL; + + foreach (lc, subpaths) + { + Path *subpath = lfirst(lc); + + Assert(subpath->parallel_safe); + + /* There should be no nested append paths in the partial paths to construct the upper + * relation */ + Assert(get_subpaths_from_append_path(subpath, false) == NIL); + + add_partially_aggregated_subpaths(root, + cheapest_partial_path, + partial_grouping_target, + d_num_groups, + extra_data, + can_sort, + can_hash, + subpath, + &sorted_subpaths /* Result paths */, + &hashed_subpaths /* Result paths */); + } + + /* Create new append paths */ + if (sorted_subpaths != NIL) + { + add_partial_path(partially_grouped_rel, + copy_append_like_path(root, + cheapest_partial_path, + sorted_subpaths, + partial_grouping_target)); + } + + if (hashed_subpaths != NIL) + { + add_partial_path(partially_grouped_rel, + copy_append_like_path(root, + cheapest_partial_path, + hashed_subpaths, + partial_grouping_target)); + } + + /* Finish the partial paths (just added by add_partial_path to partially_grouped_rel in this + * function) by adding a gather node and add this path to the partially_grouped_rel using + * add_path). */ + foreach (lc, partially_grouped_rel->partial_pathlist) + { + Path *append_path = lfirst(lc); + double total_groups = append_path->rows * append_path->parallel_workers; + + Path *gather_path = (Path *) create_gather_path(root, + partially_grouped_rel, + append_path, + partially_grouped_rel->reltarget, + NULL, + &total_groups); + add_path(partially_grouped_rel, (Path *) gather_path); + } +} + +/* + * Get the best total path for aggregation. Prefer chunk append paths if we have one, otherwise + * return the cheapest_total_path; + */ +static Path * +get_best_total_path(RelOptInfo *output_rel) +{ + ListCell *lc; + foreach (lc, output_rel->pathlist) + { + Path *path = lfirst(lc); + + if (ts_is_chunk_append_path(path)) + return path; + } + + return output_rel->cheapest_total_path; +} + +/* + * Check if this path belongs to a plain or sorted aggregation + */ +static bool +is_plain_or_sorted_agg_path(Path *path) +{ + List *subpaths = get_subpaths_from_append_path(path, true); + + Ensure(subpaths != NIL, "Unable to determine aggregation type"); + + Path *subpath = linitial(subpaths); + + if (IsA(subpath, AggPath)) + { + AggPath *agg_path = castNode(AggPath, linitial(subpaths)); + Assert(agg_path->aggstrategy == AGG_SORTED || agg_path->aggstrategy == AGG_PLAIN || + agg_path->aggstrategy == AGG_HASHED); + return agg_path->aggstrategy == AGG_SORTED || agg_path->aggstrategy == AGG_PLAIN; + } + + return is_plain_or_sorted_agg_path(subpath); +} + +/* + * Replan the aggregation and create a partial aggregation at chunk level and finalize the + * aggregation on top of an append node. + * + * The functionality is inspired by PostgreSQL's create_partitionwise_grouping_paths() function + * + * Generated aggregation paths: + * + * Finalize Aggregate + * -> Append + * -> Partial Aggregation + * - Chunk 1 + * ... + * -> Append of partially compressed chunk 2 + * -> Partial Aggregation + * -> Scan on uncompressed part of chunk 2 + * -> Partial Aggregation + * -> Scan on compressed part of chunk 2 + * ... + * -> Partial Aggregation N + * - Chunk N + */ +void +ts_pushdown_partial_agg(PlannerInfo *root, Hypertable *ht, RelOptInfo *input_rel, + RelOptInfo *output_rel, void *extra) +{ + Query *parse = root->parse; + + /* We are only interested in hypertables */ + if (ht == NULL || hypertable_is_distributed(ht)) + return; + + /* Perform partial aggregation planning only if there is an aggregation is requested */ + if (!parse->hasAggs) + return; + + /* Groupting sets are not supported by the partial aggregation pushdown */ + if (parse->groupingSets) + return; + + /* Don't replan aggregation if we already have a MinMaxAggPath (e.g., created by + * ts_preprocess_first_last_aggregates) */ + if (has_min_max_agg_path(output_rel)) + return; + + /* Is sorting possible ? */ + bool can_sort = grouping_is_sortable(parse->groupClause) && ts_guc_enable_chunkwise_aggregation; + + /* Is hashing possible ? */ + bool can_hash = grouping_is_hashable(parse->groupClause) && + !ts_is_gapfill_path(linitial(output_rel->pathlist)) && enable_hashagg; + + Assert(extra != NULL); + GroupPathExtraData *extra_data = (GroupPathExtraData *) extra; + + /* Determine the number of groups from the already planned aggregation */ + AggPath *existing_agg_path = get_existing_agg_path(output_rel); + if (existing_agg_path == NULL) + return; + + /* Skip partial aggregations already created by _timescaledb_functions.partialize_agg */ + if (existing_agg_path->aggsplit == AGGSPLIT_INITIAL_SERIAL) + return; + +/* Don't replan aggregation if it contains already partials or non-serializable aggregates */ +#if PG14_LT + AggClauseCosts agg_costs; + MemSet(&agg_costs, 0, sizeof(AggClauseCosts)); + get_agg_clause_costs_compat(root, (Node *) root->processed_tlist, AGGSPLIT_SIMPLE, &agg_costs); + get_agg_clause_costs_compat(root, parse->havingQual, AGGSPLIT_SIMPLE, &agg_costs); + + if (agg_costs.hasNonPartial || agg_costs.hasNonSerial) +#else + if (root->hasNonPartialAggs || root->hasNonSerialAggs) +#endif + return; + + double d_num_groups = existing_agg_path->numGroups; + Assert(d_num_groups > 0); + + /* Construct partial group agg upper relation */ + RelOptInfo *partially_grouped_rel = + fetch_upper_rel(root, UPPERREL_PARTIAL_GROUP_AGG, input_rel->relids); + partially_grouped_rel->consider_parallel = input_rel->consider_parallel; + partially_grouped_rel->reloptkind = input_rel->reloptkind; + partially_grouped_rel->serverid = input_rel->serverid; + partially_grouped_rel->userid = input_rel->userid; + partially_grouped_rel->useridiscurrent = input_rel->useridiscurrent; + partially_grouped_rel->fdwroutine = input_rel->fdwroutine; + + /* Build target list for partial aggregate paths */ + PathTarget *grouping_target = output_rel->reltarget; + PathTarget *partial_grouping_target = ts_make_partial_grouping_target(root, grouping_target); + partially_grouped_rel->reltarget = partial_grouping_target; + + /* Calculate aggregation costs */ + if (!extra_data->partial_costs_set) + { + /* partial phase */ + get_agg_clause_costs_compat(root, + (Node *) partial_grouping_target->exprs, + AGGSPLIT_INITIAL_SERIAL, + &extra_data->agg_partial_costs); + + /* final phase */ + get_agg_clause_costs_compat(root, + (Node *) root->upper_targets[UPPERREL_GROUP_AGG]->exprs, + AGGSPLIT_FINAL_DESERIAL, + &extra_data->agg_final_costs); + + extra_data->partial_costs_set = true; + } + + /* Generate the aggregation pushdown path */ + Path *cheapest_total_path = get_best_total_path(input_rel); + Assert(cheapest_total_path != NULL); + generate_agg_pushdown_path(root, + cheapest_total_path, + output_rel, + partially_grouped_rel, + grouping_target, + partial_grouping_target, + can_sort, + can_hash, + d_num_groups, + extra_data); + + /* The same as above but for partial paths */ + if (input_rel->partial_pathlist != NIL && input_rel->consider_parallel) + { + Path *cheapest_partial_path = linitial(input_rel->partial_pathlist); + generate_partial_agg_pushdown_path(root, + cheapest_partial_path, + output_rel, + partially_grouped_rel, + grouping_target, + partial_grouping_target, + can_sort, + can_hash, + d_num_groups, + extra_data); + } + + /* Replan aggregation if we were able to generate partially grouped rel paths */ + if (partially_grouped_rel->pathlist == NIL) + return; + + /* Prefer our paths */ + output_rel->pathlist = NIL; + output_rel->partial_pathlist = NIL; + + /* Finalize the created partially aggregated paths by adding a 'Finalize Aggregate' node on top + * of them. */ + AggClauseCosts *agg_final_costs = &extra_data->agg_final_costs; + ListCell *lc; + foreach (lc, partially_grouped_rel->pathlist) + { + Path *append_path = lfirst(lc); + + if (is_plain_or_sorted_agg_path(append_path)) + { + bool is_sorted; + + is_sorted = pathkeys_contained_in(root->group_pathkeys, append_path->pathkeys); + + if (!is_sorted) + { + append_path = (Path *) + create_sort_path(root, output_rel, append_path, root->group_pathkeys, -1.0); + } + + add_path(output_rel, + (Path *) create_agg_path(root, + output_rel, + append_path, + grouping_target, + parse->groupClause ? AGG_SORTED : AGG_PLAIN, + AGGSPLIT_FINAL_DESERIAL, + parse->groupClause, + (List *) parse->havingQual, + agg_final_costs, + d_num_groups)); + } + else + { + add_path(output_rel, + (Path *) create_agg_path(root, + output_rel, + append_path, + grouping_target, + AGG_HASHED, + AGGSPLIT_FINAL_DESERIAL, + parse->groupClause, + (List *) parse->havingQual, + agg_final_costs, + d_num_groups)); + } + } +} + /* * Turn an aggregate relation into a partial aggregate relation if aggregates * are enclosed by the partialize_agg function. diff --git a/src/planner/partialize.h b/src/planner/partialize.h index c0f7edec286..a1e6e7cd61b 100644 --- a/src/planner/partialize.h +++ b/src/planner/partialize.h @@ -8,4 +8,9 @@ #include #include +#include "chunk.h" + +void ts_pushdown_partial_agg(PlannerInfo *root, Hypertable *ht, RelOptInfo *input_rel, + RelOptInfo *output_rel, void *extra); + #endif /* TIMESCALEDB_PLAN_PARTIALIZE_H */ diff --git a/src/planner/planner.c b/src/planner/planner.c index d460ccb5a33..e8bfaaf39a5 100644 --- a/src/planner/planner.c +++ b/src/planner/planner.c @@ -60,6 +60,7 @@ #include "nodes/hypertable_modify.h" #include "partitioning.h" #include "planner/planner.h" +#include "planner/partialize.h" #include "utils.h" #include "compat/compat.h" @@ -1580,11 +1581,14 @@ timescaledb_create_upper_paths_hook(PlannerInfo *root, UpperRelationKind stage, if (stage == UPPERREL_GROUP_AGG && output_rel != NULL) { - if (!partials_found) - ts_plan_add_hashagg(root, input_rel, output_rel); - if (parse->hasAggs) ts_preprocess_first_last_aggregates(root, root->processed_tlist); + + if (ts_guc_enable_chunkwise_aggregation) + ts_pushdown_partial_agg(root, ht, input_rel, output_rel, extra); + + if (!partials_found) + ts_plan_add_hashagg(root, input_rel, output_rel); } } diff --git a/test/expected/agg_bookends.out b/test/expected/agg_bookends.out index 38811b89227..2aaccddefd8 100644 --- a/test/expected/agg_bookends.out +++ b/test/expected/agg_bookends.out @@ -77,92 +77,116 @@ SELECT setting, current_setting(setting) AS value from (VALUES ('timescaledb.ena (5 rows) :PREFIX SELECT last(temp, time_alt) FROM btest; - QUERY PLAN ------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) -(2 rows) + QUERY PLAN +------------------------------------------------------------------ + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) +(5 rows) :PREFIX SELECT first(temp, time_alt) FROM btest; - QUERY PLAN ------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) -(2 rows) - -:PREFIX SELECT gp, last(temp, time) FROM btest GROUP BY gp ORDER BY gp; QUERY PLAN ------------------------------------------------------------------ + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) +(5 rows) + +:PREFIX SELECT gp, last(temp, time) FROM btest GROUP BY gp ORDER BY gp; + QUERY PLAN +------------------------------------------------------------------------ Sort (actual rows=2 loops=1) Sort Key: _hyper_1_1_chunk.gp Sort Method: quicksort - -> HashAggregate (actual rows=2 loops=1) + -> Finalize HashAggregate (actual rows=2 loops=1) Group Key: _hyper_1_1_chunk.gp Batches: 1 - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) -(7 rows) + -> Partial HashAggregate (actual rows=2 loops=1) + Group Key: _hyper_1_1_chunk.gp + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) +(10 rows) :PREFIX SELECT gp, first(temp, time) FROM btest GROUP BY gp ORDER BY gp; - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Sort (actual rows=2 loops=1) Sort Key: _hyper_1_1_chunk.gp Sort Method: quicksort - -> HashAggregate (actual rows=2 loops=1) + -> Finalize HashAggregate (actual rows=2 loops=1) Group Key: _hyper_1_1_chunk.gp Batches: 1 - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) -(7 rows) + -> Partial HashAggregate (actual rows=2 loops=1) + Group Key: _hyper_1_1_chunk.gp + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) +(10 rows) --check whole row :PREFIX SELECT gp, first(btest, time) FROM btest GROUP BY gp ORDER BY gp; - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Sort (actual rows=2 loops=1) Sort Key: _hyper_1_1_chunk.gp Sort Method: quicksort - -> HashAggregate (actual rows=2 loops=1) + -> Finalize HashAggregate (actual rows=2 loops=1) Group Key: _hyper_1_1_chunk.gp Batches: 1 - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) -(7 rows) + -> Partial HashAggregate (actual rows=2 loops=1) + Group Key: _hyper_1_1_chunk.gp + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) +(10 rows) --check toasted col :PREFIX SELECT gp, left(last(strid, time), 10) FROM btest GROUP BY gp ORDER BY gp; - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Sort (actual rows=2 loops=1) Sort Key: _hyper_1_1_chunk.gp Sort Method: quicksort - -> HashAggregate (actual rows=2 loops=1) + -> Finalize HashAggregate (actual rows=2 loops=1) Group Key: _hyper_1_1_chunk.gp Batches: 1 - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) -(7 rows) + -> Partial HashAggregate (actual rows=2 loops=1) + Group Key: _hyper_1_1_chunk.gp + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) +(10 rows) :PREFIX SELECT gp, last(temp, strid) FROM btest GROUP BY gp ORDER BY gp; - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Sort (actual rows=2 loops=1) Sort Key: _hyper_1_1_chunk.gp Sort Method: quicksort - -> HashAggregate (actual rows=2 loops=1) + -> Finalize HashAggregate (actual rows=2 loops=1) Group Key: _hyper_1_1_chunk.gp Batches: 1 - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) -(7 rows) + -> Partial HashAggregate (actual rows=2 loops=1) + Group Key: _hyper_1_1_chunk.gp + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) +(10 rows) :PREFIX SELECT gp, last(strid, temp) FROM btest GROUP BY gp ORDER BY gp; - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Sort (actual rows=2 loops=1) Sort Key: _hyper_1_1_chunk.gp Sort Method: quicksort - -> HashAggregate (actual rows=2 loops=1) + -> Finalize HashAggregate (actual rows=2 loops=1) Group Key: _hyper_1_1_chunk.gp Batches: 1 - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) -(7 rows) + -> Partial HashAggregate (actual rows=2 loops=1) + Group Key: _hyper_1_1_chunk.gp + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) +(10 rows) BEGIN; --check null value as last element @@ -202,82 +226,142 @@ INSERT INTO btest VALUES('2019-01-20T09:00:43', '2018-01-20T09:00:55', 2, 30.5); --check null cmp element is skipped INSERT INTO btest VALUES('2018-01-20T09:00:43', NULL, 2, 32.3); :PREFIX SELECT last(temp, time_alt) FROM btest; - QUERY PLAN ------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=9 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) - -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) -(5 rows) + QUERY PLAN +------------------------------------------------------------------------ + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Append (actual rows=3 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) +(12 rows) -- fist returns NULL value :PREFIX SELECT first(temp, time_alt) FROM btest; - QUERY PLAN ------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=9 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) - -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) -(5 rows) + QUERY PLAN +------------------------------------------------------------------------ + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Append (actual rows=3 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) +(12 rows) -- test first return non NULL value INSERT INTO btest VALUES('2016-01-20T09:00:00', '2016-01-20T09:00:00', 2, 36.5); :PREFIX SELECT first(temp, time_alt) FROM btest; - QUERY PLAN ------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=10 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) - -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) -(6 rows) + QUERY PLAN +------------------------------------------------------------------------ + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Append (actual rows=4 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) +(15 rows) --check non null cmp element insert after null cmp INSERT INTO btest VALUES('2020-01-20T09:00:43', '2020-01-20T09:00:43', 2, 35.3); :PREFIX SELECT last(temp, time_alt) FROM btest; - QUERY PLAN ------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=11 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) - -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_5_chunk (actual rows=1 loops=1) -(7 rows) + QUERY PLAN +------------------------------------------------------------------------ + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Append (actual rows=5 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_5_chunk (actual rows=1 loops=1) +(18 rows) :PREFIX SELECT first(temp, time_alt) FROM btest; - QUERY PLAN ------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=11 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) - -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_5_chunk (actual rows=1 loops=1) -(7 rows) + QUERY PLAN +------------------------------------------------------------------------ + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Append (actual rows=5 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_5_chunk (actual rows=1 loops=1) +(18 rows) --cmp nulls should be ignored and not present in groups :PREFIX SELECT gp, last(temp, time_alt) FROM btest GROUP BY gp ORDER BY gp; - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------ Sort (actual rows=2 loops=1) Sort Key: _hyper_1_1_chunk.gp Sort Method: quicksort - -> HashAggregate (actual rows=2 loops=1) + -> Finalize HashAggregate (actual rows=2 loops=1) Group Key: _hyper_1_1_chunk.gp Batches: 1 - -> Append (actual rows=11 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) - -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_5_chunk (actual rows=1 loops=1) -(12 rows) + -> Append (actual rows=6 loops=1) + -> Partial HashAggregate (actual rows=2 loops=1) + Group Key: _hyper_1_1_chunk.gp + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Group Key: _hyper_1_2_chunk.gp + Batches: 1 + -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Group Key: _hyper_1_3_chunk.gp + Batches: 1 + -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Group Key: _hyper_1_4_chunk.gp + Batches: 1 + -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Group Key: _hyper_1_5_chunk.gp + Batches: 1 + -> Seq Scan on _hyper_1_5_chunk (actual rows=1 loops=1) +(27 rows) --Previously, some bugs were found with NULLS and numeric types, so test that INSERT INTO btest_numeric VALUES ('2019-01-20T09:00:43', NULL); @@ -351,16 +435,27 @@ INSERT INTO btest_numeric VALUES('2020-01-20T09:00:43', 30.5); -- can't do index scan when ordering on non-index column :PREFIX SELECT first(temp, time_alt) FROM btest; - QUERY PLAN ------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=11 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) - -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_5_chunk (actual rows=1 loops=1) -(7 rows) + QUERY PLAN +------------------------------------------------------------------------ + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Append (actual rows=5 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_5_chunk (actual rows=1 loops=1) +(18 rows) -- do index scan for subquery :PREFIX SELECT * FROM (SELECT last(temp, time) FROM btest) last; @@ -509,32 +604,54 @@ INSERT INTO btest_numeric VALUES('2020-01-20T09:00:43', 30.5); -- can't do index scan for MAX and LAST combined (MinMax optimization fails when having different aggregate functions) :PREFIX SELECT max(time), last(temp, time) FROM btest; - QUERY PLAN ------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=11 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) - -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_5_chunk (actual rows=1 loops=1) -(7 rows) - --- can't do index scan when using FIRST/LAST in ORDER BY -:PREFIX SELECT last(temp, time) FROM btest ORDER BY last(temp, time); QUERY PLAN ------------------------------------------------------------------------ - Sort (actual rows=1 loops=1) - Sort Key: (last(_hyper_1_1_chunk.temp, _hyper_1_1_chunk."time")) - Sort Method: quicksort - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=11 loops=1) + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Append (actual rows=5 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 -> Seq Scan on _hyper_1_5_chunk (actual rows=1 loops=1) -(10 rows) +(18 rows) + +-- can't do index scan when using FIRST/LAST in ORDER BY +:PREFIX SELECT last(temp, time) FROM btest ORDER BY last(temp, time); + QUERY PLAN +------------------------------------------------------------------------------ + Sort (actual rows=1 loops=1) + Sort Key: (last(_hyper_1_1_chunk.temp, _hyper_1_1_chunk."time")) + Sort Method: quicksort + -> Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Append (actual rows=5 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_5_chunk (actual rows=1 loops=1) +(21 rows) -- do index scan :PREFIX SELECT last(temp, time) FROM btest WHERE temp < 30; @@ -662,19 +779,30 @@ CREATE INDEX btest_time_alt_idx ON btest(time_alt); -- test nested FIRST/LAST in ORDER BY - no optimization possible :PREFIX SELECT abs(last(temp, time)) FROM btest ORDER BY abs(last(temp,time)); - QUERY PLAN -------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------ Sort (actual rows=1 loops=1) Sort Key: (abs(last(_hyper_1_1_chunk.temp, _hyper_1_1_chunk."time"))) Sort Method: quicksort - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=11 loops=1) - -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) - -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_1_5_chunk (actual rows=1 loops=1) -(10 rows) + -> Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Append (actual rows=5 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_1_chunk (actual rows=6 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_2_chunk (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_3_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_4_chunk (actual rows=1 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_1_5_chunk (actual rows=1 loops=1) +(21 rows) ROLLBACK; -- Test with NULL numeric values @@ -721,18 +849,24 @@ INSERT INTO btest_numeric VALUES('2018-01-20T09:00:43', NULL); (5 rows) :PREFIX SELECT first(time, quantity) FROM btest_numeric; - QUERY PLAN ------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Seq Scan on _hyper_2_8_chunk (actual rows=2 loops=1) -(2 rows) + QUERY PLAN +------------------------------------------------------------------ + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_2_8_chunk (actual rows=2 loops=1) +(5 rows) :PREFIX SELECT last(time, quantity) FROM btest_numeric; - QUERY PLAN ------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Seq Scan on _hyper_2_8_chunk (actual rows=2 loops=1) -(2 rows) + QUERY PLAN +------------------------------------------------------------------ + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_2_8_chunk (actual rows=2 loops=1) +(5 rows) -- NULL values followed by non-NULL values INSERT INTO btest_numeric VALUES('2019-01-20T09:00:43', 1); @@ -766,22 +900,32 @@ INSERT INTO btest_numeric VALUES('2019-01-20T09:00:43', 2); (9 rows) :PREFIX SELECT first(time, quantity) FROM btest_numeric; - QUERY PLAN ------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=4 loops=1) - -> Seq Scan on _hyper_2_8_chunk (actual rows=2 loops=1) - -> Seq Scan on _hyper_2_9_chunk (actual rows=2 loops=1) -(4 rows) + QUERY PLAN +------------------------------------------------------------------------ + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Append (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_2_8_chunk (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_2_9_chunk (actual rows=2 loops=1) +(9 rows) :PREFIX SELECT last(time, quantity) FROM btest_numeric; - QUERY PLAN ------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=4 loops=1) - -> Seq Scan on _hyper_2_8_chunk (actual rows=2 loops=1) - -> Seq Scan on _hyper_2_9_chunk (actual rows=2 loops=1) -(4 rows) + QUERY PLAN +------------------------------------------------------------------------ + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Append (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_2_8_chunk (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_2_9_chunk (actual rows=2 loops=1) +(9 rows) TRUNCATE btest_numeric; -- non-NULL values followed by NULL values @@ -818,22 +962,32 @@ INSERT INTO btest_numeric VALUES('2018-01-20T09:00:43', NULL); (9 rows) :PREFIX SELECT first(time, quantity) FROM btest_numeric; - QUERY PLAN -------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=4 loops=1) - -> Seq Scan on _hyper_2_10_chunk (actual rows=2 loops=1) - -> Seq Scan on _hyper_2_11_chunk (actual rows=2 loops=1) -(4 rows) + QUERY PLAN +------------------------------------------------------------------------- + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Append (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_2_10_chunk (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_2_11_chunk (actual rows=2 loops=1) +(9 rows) :PREFIX SELECT last(time, quantity) FROM btest_numeric; - QUERY PLAN -------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=4 loops=1) - -> Seq Scan on _hyper_2_10_chunk (actual rows=2 loops=1) - -> Seq Scan on _hyper_2_11_chunk (actual rows=2 loops=1) -(4 rows) + QUERY PLAN +------------------------------------------------------------------------- + Finalize HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Append (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_2_10_chunk (actual rows=2 loops=1) + -> Partial HashAggregate (actual rows=1 loops=1) + Batches: 1 + -> Seq Scan on _hyper_2_11_chunk (actual rows=2 loops=1) +(9 rows) ROLLBACK; -- we want test results as part of the output too to make sure we produce correct output diff --git a/test/expected/append-13.out b/test/expected/append-13.out index 6b7312f4247..b1f7dc32be4 100644 --- a/test/expected/append-13.out +++ b/test/expected/append-13.out @@ -2035,67 +2035,95 @@ ORDER BY time DESC, device_id; -- aggregates should prevent pushdown :PREFIX SELECT count(*) FROM metrics_timestamptz LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=26787 loops=1) - -> Seq Scan on _hyper_5_17_chunk (actual rows=4032 loops=1) - -> Seq Scan on _hyper_5_18_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_19_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_20_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_21_chunk (actual rows=4611 loops=1) -(8 rows) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=5 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_17_chunk (actual rows=4032 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_18_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_19_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_20_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_21_chunk (actual rows=4611 loops=1) +(13 rows) :PREFIX SELECT count(*) FROM metrics_space LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=37450 loops=1) - -> Seq Scan on _hyper_6_22_chunk (actual rows=5376 loops=1) - -> Seq Scan on _hyper_6_23_chunk (actual rows=5376 loops=1) - -> Seq Scan on _hyper_6_24_chunk (actual rows=2688 loops=1) - -> Seq Scan on _hyper_6_25_chunk (actual rows=8064 loops=1) - -> Seq Scan on _hyper_6_26_chunk (actual rows=8064 loops=1) - -> Seq Scan on _hyper_6_27_chunk (actual rows=4032 loops=1) - -> Seq Scan on _hyper_6_28_chunk (actual rows=1540 loops=1) - -> Seq Scan on _hyper_6_29_chunk (actual rows=1540 loops=1) - -> Seq Scan on _hyper_6_30_chunk (actual rows=770 loops=1) -(12 rows) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_22_chunk (actual rows=5376 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_23_chunk (actual rows=5376 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_24_chunk (actual rows=2688 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_25_chunk (actual rows=8064 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_26_chunk (actual rows=8064 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_27_chunk (actual rows=4032 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_28_chunk (actual rows=1540 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_29_chunk (actual rows=1540 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_30_chunk (actual rows=770 loops=1) +(21 rows) -- HAVING should prevent pushdown :PREFIX SELECT 1 FROM metrics_timestamptz HAVING count(*) > 1 LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) - -> Aggregate (actual rows=1 loops=1) + -> Finalize Aggregate (actual rows=1 loops=1) Filter: (count(*) > 1) - -> Append (actual rows=26787 loops=1) - -> Seq Scan on _hyper_5_17_chunk (actual rows=4032 loops=1) - -> Seq Scan on _hyper_5_18_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_19_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_20_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_21_chunk (actual rows=4611 loops=1) -(9 rows) + -> Append (actual rows=5 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_17_chunk (actual rows=4032 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_18_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_19_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_20_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_21_chunk (actual rows=4611 loops=1) +(14 rows) :PREFIX SELECT 1 FROM metrics_space HAVING count(*) > 1 LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) - -> Aggregate (actual rows=1 loops=1) + -> Finalize Aggregate (actual rows=1 loops=1) Filter: (count(*) > 1) - -> Append (actual rows=37450 loops=1) - -> Seq Scan on _hyper_6_22_chunk (actual rows=5376 loops=1) - -> Seq Scan on _hyper_6_23_chunk (actual rows=5376 loops=1) - -> Seq Scan on _hyper_6_24_chunk (actual rows=2688 loops=1) - -> Seq Scan on _hyper_6_25_chunk (actual rows=8064 loops=1) - -> Seq Scan on _hyper_6_26_chunk (actual rows=8064 loops=1) - -> Seq Scan on _hyper_6_27_chunk (actual rows=4032 loops=1) - -> Seq Scan on _hyper_6_28_chunk (actual rows=1540 loops=1) - -> Seq Scan on _hyper_6_29_chunk (actual rows=1540 loops=1) - -> Seq Scan on _hyper_6_30_chunk (actual rows=770 loops=1) -(13 rows) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_22_chunk (actual rows=5376 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_23_chunk (actual rows=5376 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_24_chunk (actual rows=2688 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_25_chunk (actual rows=8064 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_26_chunk (actual rows=8064 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_27_chunk (actual rows=4032 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_28_chunk (actual rows=1540 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_29_chunk (actual rows=1540 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_30_chunk (actual rows=770 loops=1) +(22 rows) -- DISTINCT should prevent pushdown SET enable_hashagg TO false; diff --git a/test/expected/append-14.out b/test/expected/append-14.out index 8e449cb917b..a3928f14890 100644 --- a/test/expected/append-14.out +++ b/test/expected/append-14.out @@ -2035,67 +2035,95 @@ ORDER BY time DESC, device_id; -- aggregates should prevent pushdown :PREFIX SELECT count(*) FROM metrics_timestamptz LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=26787 loops=1) - -> Seq Scan on _hyper_5_17_chunk (actual rows=4032 loops=1) - -> Seq Scan on _hyper_5_18_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_19_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_20_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_21_chunk (actual rows=4611 loops=1) -(8 rows) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=5 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_17_chunk (actual rows=4032 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_18_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_19_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_20_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_21_chunk (actual rows=4611 loops=1) +(13 rows) :PREFIX SELECT count(*) FROM metrics_space LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=37450 loops=1) - -> Seq Scan on _hyper_6_22_chunk (actual rows=5376 loops=1) - -> Seq Scan on _hyper_6_23_chunk (actual rows=5376 loops=1) - -> Seq Scan on _hyper_6_24_chunk (actual rows=2688 loops=1) - -> Seq Scan on _hyper_6_25_chunk (actual rows=8064 loops=1) - -> Seq Scan on _hyper_6_26_chunk (actual rows=8064 loops=1) - -> Seq Scan on _hyper_6_27_chunk (actual rows=4032 loops=1) - -> Seq Scan on _hyper_6_28_chunk (actual rows=1540 loops=1) - -> Seq Scan on _hyper_6_29_chunk (actual rows=1540 loops=1) - -> Seq Scan on _hyper_6_30_chunk (actual rows=770 loops=1) -(12 rows) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_22_chunk (actual rows=5376 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_23_chunk (actual rows=5376 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_24_chunk (actual rows=2688 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_25_chunk (actual rows=8064 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_26_chunk (actual rows=8064 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_27_chunk (actual rows=4032 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_28_chunk (actual rows=1540 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_29_chunk (actual rows=1540 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_30_chunk (actual rows=770 loops=1) +(21 rows) -- HAVING should prevent pushdown :PREFIX SELECT 1 FROM metrics_timestamptz HAVING count(*) > 1 LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) - -> Aggregate (actual rows=1 loops=1) + -> Finalize Aggregate (actual rows=1 loops=1) Filter: (count(*) > 1) - -> Append (actual rows=26787 loops=1) - -> Seq Scan on _hyper_5_17_chunk (actual rows=4032 loops=1) - -> Seq Scan on _hyper_5_18_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_19_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_20_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_21_chunk (actual rows=4611 loops=1) -(9 rows) + -> Append (actual rows=5 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_17_chunk (actual rows=4032 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_18_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_19_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_20_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_21_chunk (actual rows=4611 loops=1) +(14 rows) :PREFIX SELECT 1 FROM metrics_space HAVING count(*) > 1 LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) - -> Aggregate (actual rows=1 loops=1) + -> Finalize Aggregate (actual rows=1 loops=1) Filter: (count(*) > 1) - -> Append (actual rows=37450 loops=1) - -> Seq Scan on _hyper_6_22_chunk (actual rows=5376 loops=1) - -> Seq Scan on _hyper_6_23_chunk (actual rows=5376 loops=1) - -> Seq Scan on _hyper_6_24_chunk (actual rows=2688 loops=1) - -> Seq Scan on _hyper_6_25_chunk (actual rows=8064 loops=1) - -> Seq Scan on _hyper_6_26_chunk (actual rows=8064 loops=1) - -> Seq Scan on _hyper_6_27_chunk (actual rows=4032 loops=1) - -> Seq Scan on _hyper_6_28_chunk (actual rows=1540 loops=1) - -> Seq Scan on _hyper_6_29_chunk (actual rows=1540 loops=1) - -> Seq Scan on _hyper_6_30_chunk (actual rows=770 loops=1) -(13 rows) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_22_chunk (actual rows=5376 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_23_chunk (actual rows=5376 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_24_chunk (actual rows=2688 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_25_chunk (actual rows=8064 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_26_chunk (actual rows=8064 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_27_chunk (actual rows=4032 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_28_chunk (actual rows=1540 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_29_chunk (actual rows=1540 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_30_chunk (actual rows=770 loops=1) +(22 rows) -- DISTINCT should prevent pushdown SET enable_hashagg TO false; diff --git a/test/expected/append-15.out b/test/expected/append-15.out index 55f5ea6c74b..fbf1f113b4a 100644 --- a/test/expected/append-15.out +++ b/test/expected/append-15.out @@ -2039,67 +2039,95 @@ ORDER BY time DESC, device_id; -- aggregates should prevent pushdown :PREFIX SELECT count(*) FROM metrics_timestamptz LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=26787 loops=1) - -> Seq Scan on _hyper_5_17_chunk (actual rows=4032 loops=1) - -> Seq Scan on _hyper_5_18_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_19_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_20_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_21_chunk (actual rows=4611 loops=1) -(8 rows) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=5 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_17_chunk (actual rows=4032 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_18_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_19_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_20_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_21_chunk (actual rows=4611 loops=1) +(13 rows) :PREFIX SELECT count(*) FROM metrics_space LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=37450 loops=1) - -> Seq Scan on _hyper_6_22_chunk (actual rows=5376 loops=1) - -> Seq Scan on _hyper_6_23_chunk (actual rows=5376 loops=1) - -> Seq Scan on _hyper_6_24_chunk (actual rows=2688 loops=1) - -> Seq Scan on _hyper_6_25_chunk (actual rows=8064 loops=1) - -> Seq Scan on _hyper_6_26_chunk (actual rows=8064 loops=1) - -> Seq Scan on _hyper_6_27_chunk (actual rows=4032 loops=1) - -> Seq Scan on _hyper_6_28_chunk (actual rows=1540 loops=1) - -> Seq Scan on _hyper_6_29_chunk (actual rows=1540 loops=1) - -> Seq Scan on _hyper_6_30_chunk (actual rows=770 loops=1) -(12 rows) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_22_chunk (actual rows=5376 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_23_chunk (actual rows=5376 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_24_chunk (actual rows=2688 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_25_chunk (actual rows=8064 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_26_chunk (actual rows=8064 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_27_chunk (actual rows=4032 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_28_chunk (actual rows=1540 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_29_chunk (actual rows=1540 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_30_chunk (actual rows=770 loops=1) +(21 rows) -- HAVING should prevent pushdown :PREFIX SELECT 1 FROM metrics_timestamptz HAVING count(*) > 1 LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) - -> Aggregate (actual rows=1 loops=1) + -> Finalize Aggregate (actual rows=1 loops=1) Filter: (count(*) > 1) - -> Append (actual rows=26787 loops=1) - -> Seq Scan on _hyper_5_17_chunk (actual rows=4032 loops=1) - -> Seq Scan on _hyper_5_18_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_19_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_20_chunk (actual rows=6048 loops=1) - -> Seq Scan on _hyper_5_21_chunk (actual rows=4611 loops=1) -(9 rows) + -> Append (actual rows=5 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_17_chunk (actual rows=4032 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_18_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_19_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_20_chunk (actual rows=6048 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_5_21_chunk (actual rows=4611 loops=1) +(14 rows) :PREFIX SELECT 1 FROM metrics_space HAVING count(*) > 1 LIMIT 1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Limit (actual rows=1 loops=1) - -> Aggregate (actual rows=1 loops=1) + -> Finalize Aggregate (actual rows=1 loops=1) Filter: (count(*) > 1) - -> Append (actual rows=37450 loops=1) - -> Seq Scan on _hyper_6_22_chunk (actual rows=5376 loops=1) - -> Seq Scan on _hyper_6_23_chunk (actual rows=5376 loops=1) - -> Seq Scan on _hyper_6_24_chunk (actual rows=2688 loops=1) - -> Seq Scan on _hyper_6_25_chunk (actual rows=8064 loops=1) - -> Seq Scan on _hyper_6_26_chunk (actual rows=8064 loops=1) - -> Seq Scan on _hyper_6_27_chunk (actual rows=4032 loops=1) - -> Seq Scan on _hyper_6_28_chunk (actual rows=1540 loops=1) - -> Seq Scan on _hyper_6_29_chunk (actual rows=1540 loops=1) - -> Seq Scan on _hyper_6_30_chunk (actual rows=770 loops=1) -(13 rows) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_22_chunk (actual rows=5376 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_23_chunk (actual rows=5376 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_24_chunk (actual rows=2688 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_25_chunk (actual rows=8064 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_26_chunk (actual rows=8064 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_27_chunk (actual rows=4032 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_28_chunk (actual rows=1540 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_29_chunk (actual rows=1540 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_6_30_chunk (actual rows=770 loops=1) +(22 rows) -- DISTINCT should prevent pushdown SET enable_hashagg TO false; diff --git a/test/expected/parallel-13.out b/test/expected/parallel-13.out index 7ba66f290a3..be727f0fd82 100644 --- a/test/expected/parallel-13.out +++ b/test/expected/parallel-13.out @@ -30,11 +30,12 @@ EXPLAIN (costs off) SELECT first(i, j) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT first(i, j) FROM "test"; first @@ -48,11 +49,12 @@ EXPLAIN (costs off) SELECT last(i, j) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT last(i, j) FROM "test"; last @@ -131,11 +133,12 @@ EXPLAIN (costs off) SELECT histogram(i, 1, 1000000, 2) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT histogram(i, 1, 1000000, 2) FROM "test"; histogram @@ -149,11 +152,12 @@ EXPLAIN (costs off) SELECT histogram(i, 1,1000001,10) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT histogram(i, 1, 1000001, 10) FROM "test"; histogram @@ -167,11 +171,12 @@ EXPLAIN (costs off) SELECT histogram(i, 0,100000,5) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT histogram(i, 0, 100000, 5) FROM "test"; histogram @@ -185,11 +190,12 @@ EXPLAIN (costs off) SELECT histogram(i, 10,100000,5) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT histogram(i, 10, 100000, 5) FROM "test"; histogram @@ -203,13 +209,14 @@ EXPLAIN (costs off) SELECT histogram(NULL, 10,100000,5) FROM "test" WHERE i = c Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk Filter: ((i)::double precision = '-1'::double precision) + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk Filter: ((i)::double precision = '-1'::double precision) -(9 rows) +(10 rows) SELECT histogram(NULL, 10,100000,5) FROM "test" WHERE i = coalesce(-1,j); histogram @@ -242,20 +249,21 @@ SELECT histogram(NULL, 10,100000,5) FROM "test" WHERE i = coalesce(-1,j); Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_1_chunk Filter: (i > 1) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk Filter: (i > 1) -(16 rows) +(17 rows) SELECT count(*) FROM "test" WHERE i > 1 AND length(version()) > 0; count @@ -524,20 +532,21 @@ SET max_parallel_workers_per_gather TO 2; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Index Only Scan using _hyper_1_1_chunk_test_i_idx on _hyper_1_1_chunk Index Cond: (i >= 400000) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk Filter: (i >= 400000) -(16 rows) +(17 rows) SELECT count(*) FROM "test" WHERE i >= 400000 AND length(version()) > 0; count @@ -553,20 +562,21 @@ SELECT count(*) FROM "test" WHERE i >= 400000 AND length(version()) > 0; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Index Only Scan using _hyper_1_2_chunk_test_i_idx on _hyper_1_2_chunk Index Cond: (i < 600000) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_1_chunk Filter: (i < 600000) -(16 rows) +(17 rows) SELECT count(*) FROM "test" WHERE i < 600000 AND length(version()) > 0; count @@ -582,18 +592,19 @@ SET max_parallel_workers_per_gather TO 1; Finalize Aggregate -> Gather Workers Planned: 1 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk -(14 rows) +(15 rows) SELECT count(*) FROM "test" WHERE length(version()) > 0; count @@ -609,11 +620,11 @@ SET max_parallel_workers_per_gather TO 2; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk @@ -637,20 +648,21 @@ ALTER TABLE :CHUNK2 SET (parallel_workers=2); Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Index Only Scan using _hyper_1_1_chunk_test_i_idx on _hyper_1_1_chunk Index Cond: (i > 400000) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk Filter: (i > 400000) -(16 rows) +(17 rows) ALTER TABLE :CHUNK1 SET (parallel_workers=2); ALTER TABLE :CHUNK2 SET (parallel_workers=0); @@ -660,20 +672,21 @@ ALTER TABLE :CHUNK2 SET (parallel_workers=0); Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Index Only Scan using _hyper_1_2_chunk_test_i_idx on _hyper_1_2_chunk Index Cond: (i < 600000) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_1_chunk Filter: (i < 600000) -(16 rows) +(17 rows) ALTER TABLE :CHUNK1 RESET (parallel_workers); ALTER TABLE :CHUNK2 RESET (parallel_workers); diff --git a/test/expected/parallel-14.out b/test/expected/parallel-14.out index 7ba66f290a3..be727f0fd82 100644 --- a/test/expected/parallel-14.out +++ b/test/expected/parallel-14.out @@ -30,11 +30,12 @@ EXPLAIN (costs off) SELECT first(i, j) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT first(i, j) FROM "test"; first @@ -48,11 +49,12 @@ EXPLAIN (costs off) SELECT last(i, j) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT last(i, j) FROM "test"; last @@ -131,11 +133,12 @@ EXPLAIN (costs off) SELECT histogram(i, 1, 1000000, 2) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT histogram(i, 1, 1000000, 2) FROM "test"; histogram @@ -149,11 +152,12 @@ EXPLAIN (costs off) SELECT histogram(i, 1,1000001,10) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT histogram(i, 1, 1000001, 10) FROM "test"; histogram @@ -167,11 +171,12 @@ EXPLAIN (costs off) SELECT histogram(i, 0,100000,5) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT histogram(i, 0, 100000, 5) FROM "test"; histogram @@ -185,11 +190,12 @@ EXPLAIN (costs off) SELECT histogram(i, 10,100000,5) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT histogram(i, 10, 100000, 5) FROM "test"; histogram @@ -203,13 +209,14 @@ EXPLAIN (costs off) SELECT histogram(NULL, 10,100000,5) FROM "test" WHERE i = c Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk Filter: ((i)::double precision = '-1'::double precision) + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk Filter: ((i)::double precision = '-1'::double precision) -(9 rows) +(10 rows) SELECT histogram(NULL, 10,100000,5) FROM "test" WHERE i = coalesce(-1,j); histogram @@ -242,20 +249,21 @@ SELECT histogram(NULL, 10,100000,5) FROM "test" WHERE i = coalesce(-1,j); Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_1_chunk Filter: (i > 1) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk Filter: (i > 1) -(16 rows) +(17 rows) SELECT count(*) FROM "test" WHERE i > 1 AND length(version()) > 0; count @@ -524,20 +532,21 @@ SET max_parallel_workers_per_gather TO 2; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Index Only Scan using _hyper_1_1_chunk_test_i_idx on _hyper_1_1_chunk Index Cond: (i >= 400000) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk Filter: (i >= 400000) -(16 rows) +(17 rows) SELECT count(*) FROM "test" WHERE i >= 400000 AND length(version()) > 0; count @@ -553,20 +562,21 @@ SELECT count(*) FROM "test" WHERE i >= 400000 AND length(version()) > 0; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Index Only Scan using _hyper_1_2_chunk_test_i_idx on _hyper_1_2_chunk Index Cond: (i < 600000) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_1_chunk Filter: (i < 600000) -(16 rows) +(17 rows) SELECT count(*) FROM "test" WHERE i < 600000 AND length(version()) > 0; count @@ -582,18 +592,19 @@ SET max_parallel_workers_per_gather TO 1; Finalize Aggregate -> Gather Workers Planned: 1 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk -(14 rows) +(15 rows) SELECT count(*) FROM "test" WHERE length(version()) > 0; count @@ -609,11 +620,11 @@ SET max_parallel_workers_per_gather TO 2; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk @@ -637,20 +648,21 @@ ALTER TABLE :CHUNK2 SET (parallel_workers=2); Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Index Only Scan using _hyper_1_1_chunk_test_i_idx on _hyper_1_1_chunk Index Cond: (i > 400000) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk Filter: (i > 400000) -(16 rows) +(17 rows) ALTER TABLE :CHUNK1 SET (parallel_workers=2); ALTER TABLE :CHUNK2 SET (parallel_workers=0); @@ -660,20 +672,21 @@ ALTER TABLE :CHUNK2 SET (parallel_workers=0); Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Index Only Scan using _hyper_1_2_chunk_test_i_idx on _hyper_1_2_chunk Index Cond: (i < 600000) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_1_chunk Filter: (i < 600000) -(16 rows) +(17 rows) ALTER TABLE :CHUNK1 RESET (parallel_workers); ALTER TABLE :CHUNK2 RESET (parallel_workers); diff --git a/test/expected/parallel-15.out b/test/expected/parallel-15.out index dd0be964a1b..617f64fee53 100644 --- a/test/expected/parallel-15.out +++ b/test/expected/parallel-15.out @@ -30,11 +30,12 @@ EXPLAIN (costs off) SELECT first(i, j) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT first(i, j) FROM "test"; first @@ -48,11 +49,12 @@ EXPLAIN (costs off) SELECT last(i, j) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT last(i, j) FROM "test"; last @@ -132,11 +134,12 @@ EXPLAIN (costs off) SELECT histogram(i, 1, 1000000, 2) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT histogram(i, 1, 1000000, 2) FROM "test"; histogram @@ -150,11 +153,12 @@ EXPLAIN (costs off) SELECT histogram(i, 1,1000001,10) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT histogram(i, 1, 1000001, 10) FROM "test"; histogram @@ -168,11 +172,12 @@ EXPLAIN (costs off) SELECT histogram(i, 0,100000,5) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT histogram(i, 0, 100000, 5) FROM "test"; histogram @@ -186,11 +191,12 @@ EXPLAIN (costs off) SELECT histogram(i, 10,100000,5) FROM "test"; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk -(7 rows) +(8 rows) SELECT histogram(i, 10, 100000, 5) FROM "test"; histogram @@ -204,13 +210,14 @@ EXPLAIN (costs off) SELECT histogram(NULL, 10,100000,5) FROM "test" WHERE i = c Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Parallel Append + -> Parallel Append + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_1_chunk Filter: ((i)::double precision = '-1'::double precision) + -> Partial Aggregate -> Parallel Seq Scan on _hyper_1_2_chunk Filter: ((i)::double precision = '-1'::double precision) -(9 rows) +(10 rows) SELECT histogram(NULL, 10,100000,5) FROM "test" WHERE i = coalesce(-1,j); histogram @@ -243,20 +250,21 @@ SELECT histogram(NULL, 10,100000,5) FROM "test" WHERE i = coalesce(-1,j); Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_1_chunk Filter: (i > 1) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk Filter: (i > 1) -(16 rows) +(17 rows) SELECT count(*) FROM "test" WHERE i > 1 AND length(version()) > 0; count @@ -525,20 +533,21 @@ SET max_parallel_workers_per_gather TO 2; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Index Only Scan using _hyper_1_1_chunk_test_i_idx on _hyper_1_1_chunk Index Cond: (i >= 400000) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk Filter: (i >= 400000) -(16 rows) +(17 rows) SELECT count(*) FROM "test" WHERE i >= 400000 AND length(version()) > 0; count @@ -554,20 +563,21 @@ SELECT count(*) FROM "test" WHERE i >= 400000 AND length(version()) > 0; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Index Only Scan using _hyper_1_2_chunk_test_i_idx on _hyper_1_2_chunk Index Cond: (i < 600000) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_1_chunk Filter: (i < 600000) -(16 rows) +(17 rows) SELECT count(*) FROM "test" WHERE i < 600000 AND length(version()) > 0; count @@ -583,18 +593,19 @@ SET max_parallel_workers_per_gather TO 1; Finalize Aggregate -> Gather Workers Planned: 1 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_1_chunk + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk -(14 rows) +(15 rows) SELECT count(*) FROM "test" WHERE length(version()) > 0; count @@ -610,11 +621,11 @@ SET max_parallel_workers_per_gather TO 2; Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk @@ -638,20 +649,21 @@ ALTER TABLE :CHUNK2 SET (parallel_workers=2); Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Index Only Scan using _hyper_1_1_chunk_test_i_idx on _hyper_1_1_chunk Index Cond: (i > 400000) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_2_chunk Filter: (i > 400000) -(16 rows) +(17 rows) ALTER TABLE :CHUNK1 SET (parallel_workers=2); ALTER TABLE :CHUNK2 SET (parallel_workers=0); @@ -661,20 +673,21 @@ ALTER TABLE :CHUNK2 SET (parallel_workers=0); Finalize Aggregate -> Gather Workers Planned: 2 - -> Partial Aggregate - -> Result - One-Time Filter: (length(version()) > 0) - -> Parallel Custom Scan (ChunkAppend) on test - Chunks excluded during startup: 0 + -> Result + One-Time Filter: (length(version()) > 0) + -> Parallel Custom Scan (ChunkAppend) on test + Chunks excluded during startup: 0 + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Index Only Scan using _hyper_1_2_chunk_test_i_idx on _hyper_1_2_chunk Index Cond: (i < 600000) + -> Partial Aggregate -> Result One-Time Filter: (length(version()) > 0) -> Parallel Seq Scan on _hyper_1_1_chunk Filter: (i < 600000) -(16 rows) +(17 rows) ALTER TABLE :CHUNK1 RESET (parallel_workers); ALTER TABLE :CHUNK2 RESET (parallel_workers); diff --git a/test/expected/partitionwise.out b/test/expected/partitionwise.out index c307681a859..1ebfaecc3e5 100644 --- a/test/expected/partitionwise.out +++ b/test/expected/partitionwise.out @@ -314,24 +314,36 @@ SELECT device, avg(temp) FROM hyper GROUP BY 1 ORDER BY 1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------- Sort Output: _hyper_1_1_chunk.device, (avg(_hyper_1_1_chunk.temp)) Sort Key: _hyper_1_1_chunk.device - -> HashAggregate + -> Finalize HashAggregate Output: _hyper_1_1_chunk.device, avg(_hyper_1_1_chunk.temp) Group Key: _hyper_1_1_chunk.device -> Append - -> Seq Scan on _timescaledb_internal._hyper_1_1_chunk - Output: _hyper_1_1_chunk.device, _hyper_1_1_chunk.temp - -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk - Output: _hyper_1_2_chunk.device, _hyper_1_2_chunk.temp - -> Seq Scan on _timescaledb_internal._hyper_1_3_chunk - Output: _hyper_1_3_chunk.device, _hyper_1_3_chunk.temp - -> Seq Scan on _timescaledb_internal._hyper_1_4_chunk - Output: _hyper_1_4_chunk.device, _hyper_1_4_chunk.temp -(15 rows) + -> Partial HashAggregate + Output: _hyper_1_1_chunk.device, PARTIAL avg(_hyper_1_1_chunk.temp) + Group Key: _hyper_1_1_chunk.device + -> Seq Scan on _timescaledb_internal._hyper_1_1_chunk + Output: _hyper_1_1_chunk.device, _hyper_1_1_chunk.temp + -> Partial HashAggregate + Output: _hyper_1_2_chunk.device, PARTIAL avg(_hyper_1_2_chunk.temp) + Group Key: _hyper_1_2_chunk.device + -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk + Output: _hyper_1_2_chunk.device, _hyper_1_2_chunk.temp + -> Partial HashAggregate + Output: _hyper_1_3_chunk.device, PARTIAL avg(_hyper_1_3_chunk.temp) + Group Key: _hyper_1_3_chunk.device + -> Seq Scan on _timescaledb_internal._hyper_1_3_chunk + Output: _hyper_1_3_chunk.device, _hyper_1_3_chunk.temp + -> Partial HashAggregate + Output: _hyper_1_4_chunk.device, PARTIAL avg(_hyper_1_4_chunk.temp) + Group Key: _hyper_1_4_chunk.device + -> Seq Scan on _timescaledb_internal._hyper_1_4_chunk + Output: _hyper_1_4_chunk.device, _hyper_1_4_chunk.temp +(27 rows) SET enable_partitionwise_aggregate = 'on'; :PREFIX @@ -377,24 +389,56 @@ SELECT time, device, avg(temp) FROM hyper GROUP BY 1, 2 ORDER BY 1, 2; - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Sort - Output: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device, (avg(_hyper_1_1_chunk.temp)) - Sort Key: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device - -> HashAggregate - Output: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device, avg(_hyper_1_1_chunk.temp) - Group Key: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device - -> Append - -> Seq Scan on _timescaledb_internal._hyper_1_1_chunk - Output: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device, _hyper_1_1_chunk.temp - -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk - Output: _hyper_1_2_chunk."time", _hyper_1_2_chunk.device, _hyper_1_2_chunk.temp - -> Seq Scan on _timescaledb_internal._hyper_1_3_chunk - Output: _hyper_1_3_chunk."time", _hyper_1_3_chunk.device, _hyper_1_3_chunk.temp - -> Seq Scan on _timescaledb_internal._hyper_1_4_chunk - Output: _hyper_1_4_chunk."time", _hyper_1_4_chunk.device, _hyper_1_4_chunk.temp -(15 rows) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------- + Finalize GroupAggregate + Output: hyper."time", hyper.device, avg(hyper.temp) + Group Key: hyper."time", hyper.device + -> Sort + Output: hyper."time", hyper.device, (PARTIAL avg(hyper.temp)) + Sort Key: hyper."time", hyper.device + -> Custom Scan (ChunkAppend) on public.hyper + Output: hyper."time", hyper.device, (PARTIAL avg(hyper.temp)) + Order: hyper."time" + Startup Exclusion: false + Runtime Exclusion: false + -> Merge Append + Sort Key: _hyper_1_1_chunk."time" + -> Partial GroupAggregate + Output: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device, PARTIAL avg(_hyper_1_1_chunk.temp) + Group Key: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device + -> Sort + Output: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device, _hyper_1_1_chunk.temp + Sort Key: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device + -> Index Scan Backward using _hyper_1_1_chunk_hyper_time_idx on _timescaledb_internal._hyper_1_1_chunk + Output: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device, _hyper_1_1_chunk.temp + -> Partial GroupAggregate + Output: _hyper_1_2_chunk."time", _hyper_1_2_chunk.device, PARTIAL avg(_hyper_1_2_chunk.temp) + Group Key: _hyper_1_2_chunk."time", _hyper_1_2_chunk.device + -> Sort + Output: _hyper_1_2_chunk."time", _hyper_1_2_chunk.device, _hyper_1_2_chunk.temp + Sort Key: _hyper_1_2_chunk."time", _hyper_1_2_chunk.device + -> Index Scan Backward using _hyper_1_2_chunk_hyper_time_idx on _timescaledb_internal._hyper_1_2_chunk + Output: _hyper_1_2_chunk."time", _hyper_1_2_chunk.device, _hyper_1_2_chunk.temp + -> Merge Append + Sort Key: _hyper_1_3_chunk."time" + -> Partial GroupAggregate + Output: _hyper_1_3_chunk."time", _hyper_1_3_chunk.device, PARTIAL avg(_hyper_1_3_chunk.temp) + Group Key: _hyper_1_3_chunk."time", _hyper_1_3_chunk.device + -> Sort + Output: _hyper_1_3_chunk."time", _hyper_1_3_chunk.device, _hyper_1_3_chunk.temp + Sort Key: _hyper_1_3_chunk."time", _hyper_1_3_chunk.device + -> Index Scan Backward using _hyper_1_3_chunk_hyper_time_idx on _timescaledb_internal._hyper_1_3_chunk + Output: _hyper_1_3_chunk."time", _hyper_1_3_chunk.device, _hyper_1_3_chunk.temp + -> Partial GroupAggregate + Output: _hyper_1_4_chunk."time", _hyper_1_4_chunk.device, PARTIAL avg(_hyper_1_4_chunk.temp) + Group Key: _hyper_1_4_chunk."time", _hyper_1_4_chunk.device + -> Sort + Output: _hyper_1_4_chunk."time", _hyper_1_4_chunk.device, _hyper_1_4_chunk.temp + Sort Key: _hyper_1_4_chunk."time", _hyper_1_4_chunk.device + -> Index Scan Backward using _hyper_1_4_chunk_hyper_time_idx on _timescaledb_internal._hyper_1_4_chunk + Output: _hyper_1_4_chunk."time", _hyper_1_4_chunk.device, _hyper_1_4_chunk.temp +(47 rows) SET enable_partitionwise_aggregate = 'on'; :PREFIX @@ -402,33 +446,36 @@ SELECT time, device, avg(temp) FROM hyper GROUP BY 1, 2 ORDER BY 1, 2; - QUERY PLAN ------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------------------------ Sort Output: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device, (avg(_hyper_1_1_chunk.temp)) Sort Key: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device - -> Append - -> HashAggregate - Output: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device, avg(_hyper_1_1_chunk.temp) - Group Key: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device - -> Seq Scan on _timescaledb_internal._hyper_1_1_chunk - Output: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device, _hyper_1_1_chunk.temp - -> HashAggregate - Output: _hyper_1_2_chunk."time", _hyper_1_2_chunk.device, avg(_hyper_1_2_chunk.temp) - Group Key: _hyper_1_2_chunk."time", _hyper_1_2_chunk.device - -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk - Output: _hyper_1_2_chunk."time", _hyper_1_2_chunk.device, _hyper_1_2_chunk.temp - -> HashAggregate - Output: _hyper_1_3_chunk."time", _hyper_1_3_chunk.device, avg(_hyper_1_3_chunk.temp) - Group Key: _hyper_1_3_chunk."time", _hyper_1_3_chunk.device - -> Seq Scan on _timescaledb_internal._hyper_1_3_chunk - Output: _hyper_1_3_chunk."time", _hyper_1_3_chunk.device, _hyper_1_3_chunk.temp - -> HashAggregate - Output: _hyper_1_4_chunk."time", _hyper_1_4_chunk.device, avg(_hyper_1_4_chunk.temp) - Group Key: _hyper_1_4_chunk."time", _hyper_1_4_chunk.device - -> Seq Scan on _timescaledb_internal._hyper_1_4_chunk - Output: _hyper_1_4_chunk."time", _hyper_1_4_chunk.device, _hyper_1_4_chunk.temp -(24 rows) + -> Finalize HashAggregate + Output: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device, avg(_hyper_1_1_chunk.temp) + Group Key: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device + -> Append + -> Partial HashAggregate + Output: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device, PARTIAL avg(_hyper_1_1_chunk.temp) + Group Key: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device + -> Seq Scan on _timescaledb_internal._hyper_1_1_chunk + Output: _hyper_1_1_chunk."time", _hyper_1_1_chunk.device, _hyper_1_1_chunk.temp + -> Partial HashAggregate + Output: _hyper_1_2_chunk."time", _hyper_1_2_chunk.device, PARTIAL avg(_hyper_1_2_chunk.temp) + Group Key: _hyper_1_2_chunk."time", _hyper_1_2_chunk.device + -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk + Output: _hyper_1_2_chunk."time", _hyper_1_2_chunk.device, _hyper_1_2_chunk.temp + -> Partial HashAggregate + Output: _hyper_1_3_chunk."time", _hyper_1_3_chunk.device, PARTIAL avg(_hyper_1_3_chunk.temp) + Group Key: _hyper_1_3_chunk."time", _hyper_1_3_chunk.device + -> Seq Scan on _timescaledb_internal._hyper_1_3_chunk + Output: _hyper_1_3_chunk."time", _hyper_1_3_chunk.device, _hyper_1_3_chunk.temp + -> Partial HashAggregate + Output: _hyper_1_4_chunk."time", _hyper_1_4_chunk.device, PARTIAL avg(_hyper_1_4_chunk.temp) + Group Key: _hyper_1_4_chunk."time", _hyper_1_4_chunk.device + -> Seq Scan on _timescaledb_internal._hyper_1_4_chunk + Output: _hyper_1_4_chunk."time", _hyper_1_4_chunk.device, _hyper_1_4_chunk.temp +(27 rows) -- Partial aggregation since date_trunc(time) is not a partition key SET enable_partitionwise_aggregate = 'off'; @@ -743,22 +790,28 @@ FROM hyper_timepart GROUP BY 1, 2 ORDER BY 1, 2 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------ Limit Output: _hyper_3_7_chunk."time", _hyper_3_7_chunk.device, (avg(_hyper_3_7_chunk.temp)) -> Sort Output: _hyper_3_7_chunk."time", _hyper_3_7_chunk.device, (avg(_hyper_3_7_chunk.temp)) Sort Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.device - -> HashAggregate + -> Finalize HashAggregate Output: _hyper_3_7_chunk."time", _hyper_3_7_chunk.device, avg(_hyper_3_7_chunk.temp) Group Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.device -> Append - -> Seq Scan on _timescaledb_internal._hyper_3_7_chunk - Output: _hyper_3_7_chunk."time", _hyper_3_7_chunk.device, _hyper_3_7_chunk.temp - -> Seq Scan on _timescaledb_internal._hyper_3_8_chunk - Output: _hyper_3_8_chunk."time", _hyper_3_8_chunk.device, _hyper_3_8_chunk.temp -(13 rows) + -> Partial HashAggregate + Output: _hyper_3_7_chunk."time", _hyper_3_7_chunk.device, PARTIAL avg(_hyper_3_7_chunk.temp) + Group Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.device + -> Seq Scan on _timescaledb_internal._hyper_3_7_chunk + Output: _hyper_3_7_chunk."time", _hyper_3_7_chunk.device, _hyper_3_7_chunk.temp + -> Partial HashAggregate + Output: _hyper_3_8_chunk."time", _hyper_3_8_chunk.device, PARTIAL avg(_hyper_3_8_chunk.temp) + Group Key: _hyper_3_8_chunk."time", _hyper_3_8_chunk.device + -> Seq Scan on _timescaledb_internal._hyper_3_8_chunk + Output: _hyper_3_8_chunk."time", _hyper_3_8_chunk.device, _hyper_3_8_chunk.temp +(19 rows) :PREFIX SELECT time_func(time), device, avg(temp) diff --git a/test/expected/sql_query.out b/test/expected/sql_query.out index 26f9ef07d69..4adff1be1f8 100644 --- a/test/expected/sql_query.out +++ b/test/expected/sql_query.out @@ -220,29 +220,41 @@ EXPLAIN (verbose ON, costs off)SELECT * FROM PUBLIC."two_Partitions" WHERE serie --note that without time transform things work too EXPLAIN (verbose ON, costs off)SELECT "timeCustom" t, min(series_0) FROM PUBLIC."two_Partitions" GROUP BY t ORDER BY t DESC NULLS LAST limit 2; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------- Limit Output: "two_Partitions"."timeCustom", (min("two_Partitions".series_0)) - -> GroupAggregate + -> Finalize GroupAggregate Output: "two_Partitions"."timeCustom", min("two_Partitions".series_0) Group Key: "two_Partitions"."timeCustom" -> Custom Scan (ChunkAppend) on public."two_Partitions" - Output: "two_Partitions"."timeCustom", "two_Partitions".series_0 + Output: "two_Partitions"."timeCustom", (PARTIAL min("two_Partitions".series_0)) Order: "two_Partitions"."timeCustom" DESC NULLS LAST Startup Exclusion: false Runtime Exclusion: false - -> Index Scan using "_hyper_1_3_chunk_two_Partitions_timeCustom_device_id_idx" on _timescaledb_internal._hyper_1_3_chunk - Output: _hyper_1_3_chunk."timeCustom", _hyper_1_3_chunk.series_0 - -> Index Scan using "_hyper_1_2_chunk_two_Partitions_timeCustom_device_id_idx" on _timescaledb_internal._hyper_1_2_chunk - Output: _hyper_1_2_chunk."timeCustom", _hyper_1_2_chunk.series_0 + -> Partial GroupAggregate + Output: _hyper_1_3_chunk."timeCustom", PARTIAL min(_hyper_1_3_chunk.series_0) + Group Key: _hyper_1_3_chunk."timeCustom" + -> Index Scan using "_hyper_1_3_chunk_two_Partitions_timeCustom_device_id_idx" on _timescaledb_internal._hyper_1_3_chunk + Output: _hyper_1_3_chunk."timeCustom", _hyper_1_3_chunk.series_0 + -> Partial GroupAggregate + Output: _hyper_1_2_chunk."timeCustom", PARTIAL min(_hyper_1_2_chunk.series_0) + Group Key: _hyper_1_2_chunk."timeCustom" + -> Index Scan using "_hyper_1_2_chunk_two_Partitions_timeCustom_device_id_idx" on _timescaledb_internal._hyper_1_2_chunk + Output: _hyper_1_2_chunk."timeCustom", _hyper_1_2_chunk.series_0 -> Merge Append Sort Key: _hyper_1_4_chunk."timeCustom" DESC NULLS LAST - -> Index Scan using "_hyper_1_4_chunk_two_Partitions_timeCustom_device_id_idx" on _timescaledb_internal._hyper_1_4_chunk - Output: _hyper_1_4_chunk."timeCustom", _hyper_1_4_chunk.series_0 - -> Index Scan using "_hyper_1_1_chunk_two_Partitions_timeCustom_device_id_idx" on _timescaledb_internal._hyper_1_1_chunk - Output: _hyper_1_1_chunk."timeCustom", _hyper_1_1_chunk.series_0 -(20 rows) + -> Partial GroupAggregate + Output: _hyper_1_4_chunk."timeCustom", PARTIAL min(_hyper_1_4_chunk.series_0) + Group Key: _hyper_1_4_chunk."timeCustom" + -> Index Scan using "_hyper_1_4_chunk_two_Partitions_timeCustom_device_id_idx" on _timescaledb_internal._hyper_1_4_chunk + Output: _hyper_1_4_chunk."timeCustom", _hyper_1_4_chunk.series_0 + -> Partial GroupAggregate + Output: _hyper_1_1_chunk."timeCustom", PARTIAL min(_hyper_1_1_chunk.series_0) + Group Key: _hyper_1_1_chunk."timeCustom" + -> Index Scan using "_hyper_1_1_chunk_two_Partitions_timeCustom_device_id_idx" on _timescaledb_internal._hyper_1_1_chunk + Output: _hyper_1_1_chunk."timeCustom", _hyper_1_1_chunk.series_0 +(32 rows) --The query should still use the index on timeCustom, even though the GROUP BY/ORDER BY is on the transformed time 't'. --However, current query plans show that it does not. diff --git a/tsl/src/nodes/decompress_chunk/decompress_chunk.c b/tsl/src/nodes/decompress_chunk/decompress_chunk.c index 1cfc7124b50..8e06940ed97 100644 --- a/tsl/src/nodes/decompress_chunk/decompress_chunk.c +++ b/tsl/src/nodes/decompress_chunk/decompress_chunk.c @@ -892,6 +892,7 @@ ts_decompress_chunk_generate_paths(PlannerInfo *root, RelOptInfo *chunk_rel, Hyp NIL, path->rows + uncompressed_path->rows); } + add_partial_path(chunk_rel, path); } /* the chunk_rel now owns the paths, remove them from the compressed_rel so they can't be @@ -1970,3 +1971,11 @@ build_sortinfo(Chunk *chunk, RelOptInfo *chunk_rel, CompressionInfo *info, List sort_info.can_pushdown_sort = true; return sort_info; } + +/* Check if the provided path is a DecompressChunkPath */ +bool +ts_is_decompress_chunk_path(Path *path) +{ + return IsA(path, CustomPath) && + castNode(CustomPath, path)->methods == &decompress_chunk_path_methods; +} diff --git a/tsl/src/nodes/decompress_chunk/decompress_chunk.h b/tsl/src/nodes/decompress_chunk/decompress_chunk.h index c42332a277a..01661e2efb9 100644 --- a/tsl/src/nodes/decompress_chunk/decompress_chunk.h +++ b/tsl/src/nodes/decompress_chunk/decompress_chunk.h @@ -99,4 +99,6 @@ void ts_decompress_chunk_generate_paths(PlannerInfo *root, RelOptInfo *rel, Hype FormData_hypertable_compression *get_column_compressioninfo(List *hypertable_compression_info, char *column_name); +extern bool ts_is_decompress_chunk_path(Path *path); + #endif /* TIMESCALEDB_DECOMPRESS_CHUNK_H */ diff --git a/tsl/test/expected/agg_partials_pushdown.out b/tsl/test/expected/agg_partials_pushdown.out new file mode 100644 index 00000000000..4b8a4875678 --- /dev/null +++ b/tsl/test/expected/agg_partials_pushdown.out @@ -0,0 +1,424 @@ +-- This file and its contents are licensed under the Timescale License. +-- Please see the included NOTICE for copyright information and +-- LICENSE-TIMESCALE for a copy of the license. +\set PREFIX 'EXPLAIN (analyze, verbose, costs off, timing off, summary off)' +CREATE TABLE testtable(filter_1 int, filler_2 int, filler_3 int, time timestamptz NOT NULL, device_id int, v0 int, v1 int, v2 float, v3 float); +SELECT create_hypertable('testtable', 'time'); + create_hypertable +------------------------ + (1,public,testtable,t) +(1 row) + +ALTER TABLE testtable SET (timescaledb.compress, timescaledb.compress_orderby='time DESC', timescaledb.compress_segmentby='device_id'); +INSERT INTO testtable(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-01 0:00:00+0'::timestamptz,'2000-01-10 23:55:00+0','1day') gtime(time), generate_series(1,5,1) gdevice(device_id); +SELECT compress_chunk(c) FROM show_chunks('testtable') c; + compress_chunk +---------------------------------------- + _timescaledb_internal._hyper_1_1_chunk + _timescaledb_internal._hyper_1_2_chunk +(2 rows) + +-- Pushdown aggregation to the chunk level +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0' AND time <= '2000-02-01 00:00:00+0'; + count | sum | sum | sum | sum +-------+-----+-----+-----+----- + 50 | 200 | 250 | 175 | +(1 row) + +:PREFIX +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0' AND time <= '2000-02-01 00:00:00+0'; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) + Output: count(*), sum(_hyper_1_1_chunk.v0), sum(_hyper_1_1_chunk.v1), sum(_hyper_1_1_chunk.v2), sum(_hyper_1_1_chunk.v3) + -> Append (actual rows=2 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*), PARTIAL sum(_hyper_1_1_chunk.v0), PARTIAL sum(_hyper_1_1_chunk.v1), PARTIAL sum(_hyper_1_1_chunk.v2), PARTIAL sum(_hyper_1_1_chunk.v3) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk (actual rows=25 loops=1) + Output: _hyper_1_1_chunk.v0, _hyper_1_1_chunk.v1, _hyper_1_1_chunk.v2, _hyper_1_1_chunk.v3 + Vectorized Filter: ((_hyper_1_1_chunk."time" >= 'Fri Dec 31 16:00:00 1999 PST'::timestamp with time zone) AND (_hyper_1_1_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone)) + Bulk Decompression: true + -> Seq Scan on _timescaledb_internal.compress_hyper_2_3_chunk (actual rows=5 loops=1) + Output: compress_hyper_2_3_chunk.filter_1, compress_hyper_2_3_chunk.filler_2, compress_hyper_2_3_chunk.filler_3, compress_hyper_2_3_chunk."time", compress_hyper_2_3_chunk.device_id, compress_hyper_2_3_chunk.v0, compress_hyper_2_3_chunk.v1, compress_hyper_2_3_chunk.v2, compress_hyper_2_3_chunk.v3, compress_hyper_2_3_chunk._ts_meta_count, compress_hyper_2_3_chunk._ts_meta_sequence_num, compress_hyper_2_3_chunk._ts_meta_min_1, compress_hyper_2_3_chunk._ts_meta_max_1 + Filter: ((compress_hyper_2_3_chunk._ts_meta_max_1 >= 'Fri Dec 31 16:00:00 1999 PST'::timestamp with time zone) AND (compress_hyper_2_3_chunk._ts_meta_min_1 <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone)) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*), PARTIAL sum(_hyper_1_2_chunk.v0), PARTIAL sum(_hyper_1_2_chunk.v1), PARTIAL sum(_hyper_1_2_chunk.v2), PARTIAL sum(_hyper_1_2_chunk.v3) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_2_chunk (actual rows=25 loops=1) + Output: _hyper_1_2_chunk.v0, _hyper_1_2_chunk.v1, _hyper_1_2_chunk.v2, _hyper_1_2_chunk.v3 + Vectorized Filter: ((_hyper_1_2_chunk."time" >= 'Fri Dec 31 16:00:00 1999 PST'::timestamp with time zone) AND (_hyper_1_2_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone)) + Bulk Decompression: true + -> Seq Scan on _timescaledb_internal.compress_hyper_2_4_chunk (actual rows=5 loops=1) + Output: compress_hyper_2_4_chunk.filter_1, compress_hyper_2_4_chunk.filler_2, compress_hyper_2_4_chunk.filler_3, compress_hyper_2_4_chunk."time", compress_hyper_2_4_chunk.device_id, compress_hyper_2_4_chunk.v0, compress_hyper_2_4_chunk.v1, compress_hyper_2_4_chunk.v2, compress_hyper_2_4_chunk.v3, compress_hyper_2_4_chunk._ts_meta_count, compress_hyper_2_4_chunk._ts_meta_sequence_num, compress_hyper_2_4_chunk._ts_meta_min_1, compress_hyper_2_4_chunk._ts_meta_max_1 + Filter: ((compress_hyper_2_4_chunk._ts_meta_max_1 >= 'Fri Dec 31 16:00:00 1999 PST'::timestamp with time zone) AND (compress_hyper_2_4_chunk._ts_meta_min_1 <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone)) +(21 rows) + +-- Create partially compressed chunk +INSERT INTO testtable(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-01 0:00:00+0'::timestamptz,'2000-01-10 23:55:00+0','1day') gtime(time), generate_series(1,5,1) gdevice(device_id); +-- Pushdown aggregation to the chunk level +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0' AND time <= '2000-02-01 00:00:00+0'; + count | sum | sum | sum | sum +-------+-----+-----+-----+----- + 100 | 400 | 500 | 350 | +(1 row) + +:PREFIX +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0' AND time <= '2000-02-01 00:00:00+0'; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) + Output: count(*), sum(_hyper_1_1_chunk.v0), sum(_hyper_1_1_chunk.v1), sum(_hyper_1_1_chunk.v2), sum(_hyper_1_1_chunk.v3) + -> Append (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*), PARTIAL sum(_hyper_1_1_chunk.v0), PARTIAL sum(_hyper_1_1_chunk.v1), PARTIAL sum(_hyper_1_1_chunk.v2), PARTIAL sum(_hyper_1_1_chunk.v3) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk (actual rows=25 loops=1) + Output: _hyper_1_1_chunk.v0, _hyper_1_1_chunk.v1, _hyper_1_1_chunk.v2, _hyper_1_1_chunk.v3 + Vectorized Filter: ((_hyper_1_1_chunk."time" >= 'Fri Dec 31 16:00:00 1999 PST'::timestamp with time zone) AND (_hyper_1_1_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone)) + Bulk Decompression: true + -> Seq Scan on _timescaledb_internal.compress_hyper_2_3_chunk (actual rows=5 loops=1) + Output: compress_hyper_2_3_chunk.filter_1, compress_hyper_2_3_chunk.filler_2, compress_hyper_2_3_chunk.filler_3, compress_hyper_2_3_chunk."time", compress_hyper_2_3_chunk.device_id, compress_hyper_2_3_chunk.v0, compress_hyper_2_3_chunk.v1, compress_hyper_2_3_chunk.v2, compress_hyper_2_3_chunk.v3, compress_hyper_2_3_chunk._ts_meta_count, compress_hyper_2_3_chunk._ts_meta_sequence_num, compress_hyper_2_3_chunk._ts_meta_min_1, compress_hyper_2_3_chunk._ts_meta_max_1 + Filter: ((compress_hyper_2_3_chunk._ts_meta_max_1 >= 'Fri Dec 31 16:00:00 1999 PST'::timestamp with time zone) AND (compress_hyper_2_3_chunk._ts_meta_min_1 <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone)) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*), PARTIAL sum(_hyper_1_1_chunk.v0), PARTIAL sum(_hyper_1_1_chunk.v1), PARTIAL sum(_hyper_1_1_chunk.v2), PARTIAL sum(_hyper_1_1_chunk.v3) + -> Seq Scan on _timescaledb_internal._hyper_1_1_chunk (actual rows=25 loops=1) + Output: _hyper_1_1_chunk.v0, _hyper_1_1_chunk.v1, _hyper_1_1_chunk.v2, _hyper_1_1_chunk.v3 + Filter: ((_hyper_1_1_chunk."time" >= 'Fri Dec 31 16:00:00 1999 PST'::timestamp with time zone) AND (_hyper_1_1_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone)) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*), PARTIAL sum(_hyper_1_2_chunk.v0), PARTIAL sum(_hyper_1_2_chunk.v1), PARTIAL sum(_hyper_1_2_chunk.v2), PARTIAL sum(_hyper_1_2_chunk.v3) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_2_chunk (actual rows=25 loops=1) + Output: _hyper_1_2_chunk.v0, _hyper_1_2_chunk.v1, _hyper_1_2_chunk.v2, _hyper_1_2_chunk.v3 + Vectorized Filter: ((_hyper_1_2_chunk."time" >= 'Fri Dec 31 16:00:00 1999 PST'::timestamp with time zone) AND (_hyper_1_2_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone)) + Bulk Decompression: true + -> Seq Scan on _timescaledb_internal.compress_hyper_2_4_chunk (actual rows=5 loops=1) + Output: compress_hyper_2_4_chunk.filter_1, compress_hyper_2_4_chunk.filler_2, compress_hyper_2_4_chunk.filler_3, compress_hyper_2_4_chunk."time", compress_hyper_2_4_chunk.device_id, compress_hyper_2_4_chunk.v0, compress_hyper_2_4_chunk.v1, compress_hyper_2_4_chunk.v2, compress_hyper_2_4_chunk.v3, compress_hyper_2_4_chunk._ts_meta_count, compress_hyper_2_4_chunk._ts_meta_sequence_num, compress_hyper_2_4_chunk._ts_meta_min_1, compress_hyper_2_4_chunk._ts_meta_max_1 + Filter: ((compress_hyper_2_4_chunk._ts_meta_max_1 >= 'Fri Dec 31 16:00:00 1999 PST'::timestamp with time zone) AND (compress_hyper_2_4_chunk._ts_meta_min_1 <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone)) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*), PARTIAL sum(_hyper_1_2_chunk.v0), PARTIAL sum(_hyper_1_2_chunk.v1), PARTIAL sum(_hyper_1_2_chunk.v2), PARTIAL sum(_hyper_1_2_chunk.v3) + -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (actual rows=25 loops=1) + Output: _hyper_1_2_chunk.v0, _hyper_1_2_chunk.v1, _hyper_1_2_chunk.v2, _hyper_1_2_chunk.v3 + Filter: ((_hyper_1_2_chunk."time" >= 'Fri Dec 31 16:00:00 1999 PST'::timestamp with time zone) AND (_hyper_1_2_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone)) +(31 rows) + +-- Same query using chunk append +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0'::text::timestamptz AND time <= '2000-02-01 00:00:00+0'; + count | sum | sum | sum | sum +-------+-----+-----+-----+----- + 100 | 400 | 500 | 350 | +(1 row) + +:PREFIX +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0'::text::timestamptz AND time <= '2000-02-01 00:00:00+0'; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) + Output: count(*), sum(testtable.v0), sum(testtable.v1), sum(testtable.v2), sum(testtable.v3) + -> Custom Scan (ChunkAppend) on public.testtable (actual rows=4 loops=1) + Output: (PARTIAL count(*)), (PARTIAL sum(testtable.v0)), (PARTIAL sum(testtable.v1)), (PARTIAL sum(testtable.v2)), (PARTIAL sum(testtable.v3)) + Startup Exclusion: true + Runtime Exclusion: false + Chunks excluded during startup: 0 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*), PARTIAL sum(_hyper_1_1_chunk.v0), PARTIAL sum(_hyper_1_1_chunk.v1), PARTIAL sum(_hyper_1_1_chunk.v2), PARTIAL sum(_hyper_1_1_chunk.v3) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk (actual rows=25 loops=1) + Output: _hyper_1_1_chunk.v0, _hyper_1_1_chunk.v1, _hyper_1_1_chunk.v2, _hyper_1_1_chunk.v3 + Filter: (_hyper_1_1_chunk."time" >= ('2000-01-01 00:00:00+0'::cstring)::timestamp with time zone) + Vectorized Filter: (_hyper_1_1_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone) + Bulk Decompression: true + -> Seq Scan on _timescaledb_internal.compress_hyper_2_3_chunk (actual rows=5 loops=1) + Output: compress_hyper_2_3_chunk.filter_1, compress_hyper_2_3_chunk.filler_2, compress_hyper_2_3_chunk.filler_3, compress_hyper_2_3_chunk."time", compress_hyper_2_3_chunk.device_id, compress_hyper_2_3_chunk.v0, compress_hyper_2_3_chunk.v1, compress_hyper_2_3_chunk.v2, compress_hyper_2_3_chunk.v3, compress_hyper_2_3_chunk._ts_meta_count, compress_hyper_2_3_chunk._ts_meta_sequence_num, compress_hyper_2_3_chunk._ts_meta_min_1, compress_hyper_2_3_chunk._ts_meta_max_1 + Filter: ((compress_hyper_2_3_chunk._ts_meta_min_1 <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone) AND (compress_hyper_2_3_chunk._ts_meta_max_1 >= ('2000-01-01 00:00:00+0'::cstring)::timestamp with time zone)) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*), PARTIAL sum(_hyper_1_1_chunk.v0), PARTIAL sum(_hyper_1_1_chunk.v1), PARTIAL sum(_hyper_1_1_chunk.v2), PARTIAL sum(_hyper_1_1_chunk.v3) + -> Seq Scan on _timescaledb_internal._hyper_1_1_chunk (actual rows=25 loops=1) + Output: _hyper_1_1_chunk.v0, _hyper_1_1_chunk.v1, _hyper_1_1_chunk.v2, _hyper_1_1_chunk.v3 + Filter: ((_hyper_1_1_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone) AND (_hyper_1_1_chunk."time" >= ('2000-01-01 00:00:00+0'::cstring)::timestamp with time zone)) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*), PARTIAL sum(_hyper_1_2_chunk.v0), PARTIAL sum(_hyper_1_2_chunk.v1), PARTIAL sum(_hyper_1_2_chunk.v2), PARTIAL sum(_hyper_1_2_chunk.v3) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_2_chunk (actual rows=25 loops=1) + Output: _hyper_1_2_chunk.v0, _hyper_1_2_chunk.v1, _hyper_1_2_chunk.v2, _hyper_1_2_chunk.v3 + Filter: (_hyper_1_2_chunk."time" >= ('2000-01-01 00:00:00+0'::cstring)::timestamp with time zone) + Vectorized Filter: (_hyper_1_2_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone) + Bulk Decompression: true + -> Seq Scan on _timescaledb_internal.compress_hyper_2_4_chunk (actual rows=5 loops=1) + Output: compress_hyper_2_4_chunk.filter_1, compress_hyper_2_4_chunk.filler_2, compress_hyper_2_4_chunk.filler_3, compress_hyper_2_4_chunk."time", compress_hyper_2_4_chunk.device_id, compress_hyper_2_4_chunk.v0, compress_hyper_2_4_chunk.v1, compress_hyper_2_4_chunk.v2, compress_hyper_2_4_chunk.v3, compress_hyper_2_4_chunk._ts_meta_count, compress_hyper_2_4_chunk._ts_meta_sequence_num, compress_hyper_2_4_chunk._ts_meta_min_1, compress_hyper_2_4_chunk._ts_meta_max_1 + Filter: ((compress_hyper_2_4_chunk._ts_meta_min_1 <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone) AND (compress_hyper_2_4_chunk._ts_meta_max_1 >= ('2000-01-01 00:00:00+0'::cstring)::timestamp with time zone)) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*), PARTIAL sum(_hyper_1_2_chunk.v0), PARTIAL sum(_hyper_1_2_chunk.v1), PARTIAL sum(_hyper_1_2_chunk.v2), PARTIAL sum(_hyper_1_2_chunk.v3) + -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (actual rows=25 loops=1) + Output: _hyper_1_2_chunk.v0, _hyper_1_2_chunk.v1, _hyper_1_2_chunk.v2, _hyper_1_2_chunk.v3 + Filter: ((_hyper_1_2_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone) AND (_hyper_1_2_chunk."time" >= ('2000-01-01 00:00:00+0'::cstring)::timestamp with time zone)) +(37 rows) + +-- Force plain / sorted aggregation +SET enable_hashagg = OFF; +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0'::text::timestamptz AND time <= '2000-02-01 00:00:00+0'; + count | sum | sum | sum | sum +-------+-----+-----+-----+----- + 100 | 400 | 500 | 350 | +(1 row) + +:PREFIX +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0'::text::timestamptz AND time <= '2000-02-01 00:00:00+0'; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) + Output: count(*), sum(testtable.v0), sum(testtable.v1), sum(testtable.v2), sum(testtable.v3) + -> Custom Scan (ChunkAppend) on public.testtable (actual rows=4 loops=1) + Output: (PARTIAL count(*)), (PARTIAL sum(testtable.v0)), (PARTIAL sum(testtable.v1)), (PARTIAL sum(testtable.v2)), (PARTIAL sum(testtable.v3)) + Startup Exclusion: true + Runtime Exclusion: false + Chunks excluded during startup: 0 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*), PARTIAL sum(_hyper_1_1_chunk.v0), PARTIAL sum(_hyper_1_1_chunk.v1), PARTIAL sum(_hyper_1_1_chunk.v2), PARTIAL sum(_hyper_1_1_chunk.v3) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk (actual rows=25 loops=1) + Output: _hyper_1_1_chunk.v0, _hyper_1_1_chunk.v1, _hyper_1_1_chunk.v2, _hyper_1_1_chunk.v3 + Filter: (_hyper_1_1_chunk."time" >= ('2000-01-01 00:00:00+0'::cstring)::timestamp with time zone) + Vectorized Filter: (_hyper_1_1_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone) + Bulk Decompression: true + -> Seq Scan on _timescaledb_internal.compress_hyper_2_3_chunk (actual rows=5 loops=1) + Output: compress_hyper_2_3_chunk.filter_1, compress_hyper_2_3_chunk.filler_2, compress_hyper_2_3_chunk.filler_3, compress_hyper_2_3_chunk."time", compress_hyper_2_3_chunk.device_id, compress_hyper_2_3_chunk.v0, compress_hyper_2_3_chunk.v1, compress_hyper_2_3_chunk.v2, compress_hyper_2_3_chunk.v3, compress_hyper_2_3_chunk._ts_meta_count, compress_hyper_2_3_chunk._ts_meta_sequence_num, compress_hyper_2_3_chunk._ts_meta_min_1, compress_hyper_2_3_chunk._ts_meta_max_1 + Filter: ((compress_hyper_2_3_chunk._ts_meta_min_1 <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone) AND (compress_hyper_2_3_chunk._ts_meta_max_1 >= ('2000-01-01 00:00:00+0'::cstring)::timestamp with time zone)) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*), PARTIAL sum(_hyper_1_1_chunk.v0), PARTIAL sum(_hyper_1_1_chunk.v1), PARTIAL sum(_hyper_1_1_chunk.v2), PARTIAL sum(_hyper_1_1_chunk.v3) + -> Seq Scan on _timescaledb_internal._hyper_1_1_chunk (actual rows=25 loops=1) + Output: _hyper_1_1_chunk.v0, _hyper_1_1_chunk.v1, _hyper_1_1_chunk.v2, _hyper_1_1_chunk.v3 + Filter: ((_hyper_1_1_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone) AND (_hyper_1_1_chunk."time" >= ('2000-01-01 00:00:00+0'::cstring)::timestamp with time zone)) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*), PARTIAL sum(_hyper_1_2_chunk.v0), PARTIAL sum(_hyper_1_2_chunk.v1), PARTIAL sum(_hyper_1_2_chunk.v2), PARTIAL sum(_hyper_1_2_chunk.v3) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_2_chunk (actual rows=25 loops=1) + Output: _hyper_1_2_chunk.v0, _hyper_1_2_chunk.v1, _hyper_1_2_chunk.v2, _hyper_1_2_chunk.v3 + Filter: (_hyper_1_2_chunk."time" >= ('2000-01-01 00:00:00+0'::cstring)::timestamp with time zone) + Vectorized Filter: (_hyper_1_2_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone) + Bulk Decompression: true + -> Seq Scan on _timescaledb_internal.compress_hyper_2_4_chunk (actual rows=5 loops=1) + Output: compress_hyper_2_4_chunk.filter_1, compress_hyper_2_4_chunk.filler_2, compress_hyper_2_4_chunk.filler_3, compress_hyper_2_4_chunk."time", compress_hyper_2_4_chunk.device_id, compress_hyper_2_4_chunk.v0, compress_hyper_2_4_chunk.v1, compress_hyper_2_4_chunk.v2, compress_hyper_2_4_chunk.v3, compress_hyper_2_4_chunk._ts_meta_count, compress_hyper_2_4_chunk._ts_meta_sequence_num, compress_hyper_2_4_chunk._ts_meta_min_1, compress_hyper_2_4_chunk._ts_meta_max_1 + Filter: ((compress_hyper_2_4_chunk._ts_meta_min_1 <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone) AND (compress_hyper_2_4_chunk._ts_meta_max_1 >= ('2000-01-01 00:00:00+0'::cstring)::timestamp with time zone)) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*), PARTIAL sum(_hyper_1_2_chunk.v0), PARTIAL sum(_hyper_1_2_chunk.v1), PARTIAL sum(_hyper_1_2_chunk.v2), PARTIAL sum(_hyper_1_2_chunk.v3) + -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (actual rows=25 loops=1) + Output: _hyper_1_2_chunk.v0, _hyper_1_2_chunk.v1, _hyper_1_2_chunk.v2, _hyper_1_2_chunk.v3 + Filter: ((_hyper_1_2_chunk."time" <= 'Mon Jan 31 16:00:00 2000 PST'::timestamp with time zone) AND (_hyper_1_2_chunk."time" >= ('2000-01-01 00:00:00+0'::cstring)::timestamp with time zone)) +(37 rows) + +RESET enable_hashagg; +-- Check Append Node under ChunkAppend +RESET enable_hashagg; +RESET timescaledb.enable_chunkwise_aggregation; +CREATE TABLE testtable2 ( + timecustom BIGINT NOT NULL, + device_id TEXT NOT NULL, + series_0 DOUBLE PRECISION NULL, + series_1 DOUBLE PRECISION NULL, + series_2 DOUBLE PRECISION NULL, + series_bool BOOLEAN NULL +); +CREATE INDEX ON testtable2 (timeCustom DESC NULLS LAST, device_id); +SELECT * FROM create_hypertable('testtable2', 'timecustom', 'device_id', number_partitions => 2, chunk_time_interval=>_timescaledb_functions.interval_to_usec('1 month')); + hypertable_id | schema_name | table_name | created +---------------+-------------+------------+--------- + 3 | public | testtable2 | t +(1 row) + +INSERT INTO testtable2 VALUES +(1257894000000000000, 'dev1', 1.5, 1, 2, true), +(1257894000000000000, 'dev1', 1.5, 2, NULL, NULL), +(1257894000000001000, 'dev1', 2.5, 3, NULL, NULL), +(1257894001000000000, 'dev1', 3.5, 4, NULL, NULL), +(1257897600000000000, 'dev1', 4.5, 5, NULL, false), +(1257894002000000000, 'dev1', 5.5, 6, NULL, true), +(1257894002000000000, 'dev1', 5.5, 7, NULL, false); +INSERT INTO testtable2(timeCustom, device_id, series_0, series_1) VALUES +(1257987600000000000, 'dev1', 1.5, 1), +(1257987600000000000, 'dev1', 1.5, 2), +(1257894000000000000, 'dev2', 1.5, 1), +(1257894002000000000, 'dev1', 2.5, 3); +SELECT timeCustom t, min(series_0) FROM PUBLIC.testtable2 GROUP BY t ORDER BY t DESC NULLS LAST limit 2; + t | min +---------------------+----- + 1257987600000000000 | 1.5 + 1257897600000000000 | 4.5 +(2 rows) + +:PREFIX +SELECT timeCustom t, min(series_0) FROM PUBLIC.testtable2 GROUP BY t ORDER BY t DESC NULLS LAST limit 2; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit (actual rows=2 loops=1) + Output: testtable2.timecustom, (min(testtable2.series_0)) + -> Finalize GroupAggregate (actual rows=2 loops=1) + Output: testtable2.timecustom, min(testtable2.series_0) + Group Key: testtable2.timecustom + -> Custom Scan (ChunkAppend) on public.testtable2 (actual rows=3 loops=1) + Output: testtable2.timecustom, (PARTIAL min(testtable2.series_0)) + Order: testtable2.timecustom DESC NULLS LAST + Startup Exclusion: false + Runtime Exclusion: false + -> Partial GroupAggregate (actual rows=1 loops=1) + Output: _hyper_3_7_chunk.timecustom, PARTIAL min(_hyper_3_7_chunk.series_0) + Group Key: _hyper_3_7_chunk.timecustom + -> Index Scan using _hyper_3_7_chunk_testtable2_timecustom_device_id_idx on _timescaledb_internal._hyper_3_7_chunk (actual rows=2 loops=1) + Output: _hyper_3_7_chunk.timecustom, _hyper_3_7_chunk.series_0 + -> Partial GroupAggregate (actual rows=1 loops=1) + Output: _hyper_3_6_chunk.timecustom, PARTIAL min(_hyper_3_6_chunk.series_0) + Group Key: _hyper_3_6_chunk.timecustom + -> Index Scan using _hyper_3_6_chunk_testtable2_timecustom_device_id_idx on _timescaledb_internal._hyper_3_6_chunk (actual rows=1 loops=1) + Output: _hyper_3_6_chunk.timecustom, _hyper_3_6_chunk.series_0 + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_3_8_chunk.timecustom DESC NULLS LAST + -> Partial GroupAggregate (actual rows=1 loops=1) + Output: _hyper_3_8_chunk.timecustom, PARTIAL min(_hyper_3_8_chunk.series_0) + Group Key: _hyper_3_8_chunk.timecustom + -> Index Scan using _hyper_3_8_chunk_testtable2_timecustom_device_id_idx on _timescaledb_internal._hyper_3_8_chunk (actual rows=1 loops=1) + Output: _hyper_3_8_chunk.timecustom, _hyper_3_8_chunk.series_0 + -> Partial GroupAggregate (actual rows=1 loops=1) + Output: _hyper_3_5_chunk.timecustom, PARTIAL min(_hyper_3_5_chunk.series_0) + Group Key: _hyper_3_5_chunk.timecustom + -> Index Scan using _hyper_3_5_chunk_testtable2_timecustom_device_id_idx on _timescaledb_internal._hyper_3_5_chunk (actual rows=4 loops=1) + Output: _hyper_3_5_chunk.timecustom, _hyper_3_5_chunk.series_0 +(32 rows) + +-- Force parallel query +SET force_parallel_mode = 'on'; +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; +SELECT timeCustom t, min(series_0) FROM PUBLIC.testtable2 GROUP BY t ORDER BY t DESC NULLS LAST limit 2; + t | min +---------------------+----- + 1257987600000000000 | 1.5 + 1257897600000000000 | 4.5 +(2 rows) + +:PREFIX +SELECT timeCustom t, min(series_0) FROM PUBLIC.testtable2 GROUP BY t ORDER BY t DESC NULLS LAST limit 2; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Gather (actual rows=2 loops=1) + Output: testtable2.timecustom, (min(testtable2.series_0)) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Limit (actual rows=2 loops=1) + Output: testtable2.timecustom, (min(testtable2.series_0)) + Worker 0: actual rows=2 loops=1 + -> Finalize GroupAggregate (actual rows=2 loops=1) + Output: testtable2.timecustom, min(testtable2.series_0) + Group Key: testtable2.timecustom + Worker 0: actual rows=2 loops=1 + -> Custom Scan (ChunkAppend) on public.testtable2 (actual rows=3 loops=1) + Output: testtable2.timecustom, (PARTIAL min(testtable2.series_0)) + Order: testtable2.timecustom DESC NULLS LAST + Startup Exclusion: false + Runtime Exclusion: false + Worker 0: actual rows=3 loops=1 + -> Partial GroupAggregate (actual rows=1 loops=1) + Output: _hyper_3_7_chunk.timecustom, PARTIAL min(_hyper_3_7_chunk.series_0) + Group Key: _hyper_3_7_chunk.timecustom + Worker 0: actual rows=1 loops=1 + -> Index Scan using _hyper_3_7_chunk_testtable2_timecustom_device_id_idx on _timescaledb_internal._hyper_3_7_chunk (actual rows=2 loops=1) + Output: _hyper_3_7_chunk.timecustom, _hyper_3_7_chunk.series_0 + Worker 0: actual rows=2 loops=1 + -> Partial GroupAggregate (actual rows=1 loops=1) + Output: _hyper_3_6_chunk.timecustom, PARTIAL min(_hyper_3_6_chunk.series_0) + Group Key: _hyper_3_6_chunk.timecustom + Worker 0: actual rows=1 loops=1 + -> Index Scan using _hyper_3_6_chunk_testtable2_timecustom_device_id_idx on _timescaledb_internal._hyper_3_6_chunk (actual rows=1 loops=1) + Output: _hyper_3_6_chunk.timecustom, _hyper_3_6_chunk.series_0 + Worker 0: actual rows=1 loops=1 + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_3_8_chunk.timecustom DESC NULLS LAST + Worker 0: actual rows=1 loops=1 + -> Partial GroupAggregate (actual rows=1 loops=1) + Output: _hyper_3_8_chunk.timecustom, PARTIAL min(_hyper_3_8_chunk.series_0) + Group Key: _hyper_3_8_chunk.timecustom + Worker 0: actual rows=1 loops=1 + -> Index Scan using _hyper_3_8_chunk_testtable2_timecustom_device_id_idx on _timescaledb_internal._hyper_3_8_chunk (actual rows=1 loops=1) + Output: _hyper_3_8_chunk.timecustom, _hyper_3_8_chunk.series_0 + Worker 0: actual rows=1 loops=1 + -> Partial GroupAggregate (actual rows=1 loops=1) + Output: _hyper_3_5_chunk.timecustom, PARTIAL min(_hyper_3_5_chunk.series_0) + Group Key: _hyper_3_5_chunk.timecustom + Worker 0: actual rows=1 loops=1 + -> Index Scan using _hyper_3_5_chunk_testtable2_timecustom_device_id_idx on _timescaledb_internal._hyper_3_5_chunk (actual rows=4 loops=1) + Output: _hyper_3_5_chunk.timecustom, _hyper_3_5_chunk.series_0 + Worker 0: actual rows=4 loops=1 +(49 rows) + +-- Test that we don't process groupingSets +:PREFIX +SELECT timeCustom t, min(series_0) FROM PUBLIC.testtable2 GROUP BY ROLLUP(t); + QUERY PLAN +------------------------------------------------------------------------------------------------------- + MixedAggregate (actual rows=7 loops=1) + Output: _hyper_3_5_chunk.timecustom, min(_hyper_3_5_chunk.series_0) + Hash Key: _hyper_3_5_chunk.timecustom + Group Key: () + Batches: 1 + -> Gather (actual rows=11 loops=1) + Output: _hyper_3_5_chunk.timecustom, _hyper_3_5_chunk.series_0 + Workers Planned: 2 + Workers Launched: 2 + -> Parallel Append (actual rows=4 loops=3) + Worker 0: actual rows=0 loops=1 + Worker 1: actual rows=0 loops=1 + -> Parallel Seq Scan on _timescaledb_internal._hyper_3_5_chunk (actual rows=7 loops=1) + Output: _hyper_3_5_chunk.timecustom, _hyper_3_5_chunk.series_0 + -> Parallel Seq Scan on _timescaledb_internal._hyper_3_6_chunk (actual rows=1 loops=1) + Output: _hyper_3_6_chunk.timecustom, _hyper_3_6_chunk.series_0 + -> Parallel Seq Scan on _timescaledb_internal._hyper_3_7_chunk (actual rows=2 loops=1) + Output: _hyper_3_7_chunk.timecustom, _hyper_3_7_chunk.series_0 + -> Parallel Seq Scan on _timescaledb_internal._hyper_3_8_chunk (actual rows=1 loops=1) + Output: _hyper_3_8_chunk.timecustom, _hyper_3_8_chunk.series_0 +(20 rows) + +-- Check parallel fallback into a non-partial aggregation +SET timescaledb.enable_chunkwise_aggregation = OFF; +SET enable_hashagg = OFF; +SELECT timeCustom t, min(series_0) FROM PUBLIC.testtable2 GROUP BY t ORDER BY t DESC NULLS LAST limit 2; + t | min +---------------------+----- + 1257987600000000000 | 1.5 + 1257897600000000000 | 4.5 +(2 rows) + +:PREFIX +SELECT timeCustom t, min(series_0) FROM PUBLIC.testtable2 GROUP BY t ORDER BY t DESC NULLS LAST limit 2; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Gather (actual rows=2 loops=1) + Output: testtable2.timecustom, (min(testtable2.series_0)) + Workers Planned: 1 + Workers Launched: 1 + Single Copy: true + -> Limit (actual rows=2 loops=1) + Output: testtable2.timecustom, (min(testtable2.series_0)) + Worker 0: actual rows=2 loops=1 + -> GroupAggregate (actual rows=2 loops=1) + Output: testtable2.timecustom, min(testtable2.series_0) + Group Key: testtable2.timecustom + Worker 0: actual rows=2 loops=1 + -> Custom Scan (ChunkAppend) on public.testtable2 (actual rows=4 loops=1) + Output: testtable2.timecustom, testtable2.series_0 + Order: testtable2.timecustom DESC NULLS LAST + Startup Exclusion: false + Runtime Exclusion: false + Worker 0: actual rows=4 loops=1 + -> Index Scan using _hyper_3_7_chunk_testtable2_timecustom_device_id_idx on _timescaledb_internal._hyper_3_7_chunk (actual rows=2 loops=1) + Output: _hyper_3_7_chunk.timecustom, _hyper_3_7_chunk.series_0 + Worker 0: actual rows=2 loops=1 + -> Index Scan using _hyper_3_6_chunk_testtable2_timecustom_device_id_idx on _timescaledb_internal._hyper_3_6_chunk (actual rows=1 loops=1) + Output: _hyper_3_6_chunk.timecustom, _hyper_3_6_chunk.series_0 + Worker 0: actual rows=1 loops=1 + -> Merge Append (actual rows=1 loops=1) + Sort Key: _hyper_3_8_chunk.timecustom DESC NULLS LAST + Worker 0: actual rows=1 loops=1 + -> Index Scan using _hyper_3_8_chunk_testtable2_timecustom_device_id_idx on _timescaledb_internal._hyper_3_8_chunk (actual rows=1 loops=1) + Output: _hyper_3_8_chunk.timecustom, _hyper_3_8_chunk.series_0 + Worker 0: actual rows=1 loops=1 + -> Index Scan using _hyper_3_5_chunk_testtable2_timecustom_device_id_idx on _timescaledb_internal._hyper_3_5_chunk (actual rows=1 loops=1) + Output: _hyper_3_5_chunk.timecustom, _hyper_3_5_chunk.series_0 + Worker 0: actual rows=1 loops=1 +(33 rows) + diff --git a/tsl/test/expected/compression.out b/tsl/test/expected/compression.out index e9e625d2f72..f368f96a112 100644 --- a/tsl/test/expected/compression.out +++ b/tsl/test/expected/compression.out @@ -536,6 +536,8 @@ ALTER TABLE plan_inval SET (timescaledb.compress,timescaledb.compress_orderby='t -- create 2 chunks INSERT INTO plan_inval SELECT * FROM (VALUES ('2000-01-01'::timestamptz,1), ('2000-01-07'::timestamptz,1)) v(time,device_id); SET max_parallel_workers_per_gather to 0; +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; PREPARE prep_plan AS SELECT count(*) FROM plan_inval; EXECUTE prep_plan; count @@ -571,15 +573,18 @@ EXECUTE prep_plan; (1 row) EXPLAIN (COSTS OFF) EXECUTE prep_plan; - QUERY PLAN ----------------------------------------------------------------- - Aggregate + QUERY PLAN +---------------------------------------------------------------------- + Finalize Aggregate -> Append - -> Custom Scan (DecompressChunk) on _hyper_7_16_chunk - -> Seq Scan on compress_hyper_8_18_chunk - -> Seq Scan on _hyper_7_17_chunk -(5 rows) + -> Partial Aggregate + -> Custom Scan (DecompressChunk) on _hyper_7_16_chunk + -> Seq Scan on compress_hyper_8_18_chunk + -> Partial Aggregate + -> Seq Scan on _hyper_7_17_chunk +(7 rows) +SET enable_hashagg = ON; CREATE TABLE test_collation ( time TIMESTAMPTZ NOT NULL, device_id TEXT COLLATE "C" NULL, @@ -1862,16 +1867,18 @@ SELECT sum(cpu) FROM f_sensor_data; -> Gather Output: (PARTIAL sum(_hyper_37_71_chunk.cpu)) Workers Planned: 4 - -> Partial Aggregate - Output: PARTIAL sum(_hyper_37_71_chunk.cpu) - -> Parallel Append + -> Parallel Append + -> Partial Aggregate + Output: PARTIAL sum(_hyper_37_71_chunk.cpu) -> Parallel Seq Scan on _timescaledb_internal._hyper_37_71_chunk Output: _hyper_37_71_chunk.cpu + -> Partial Aggregate + Output: PARTIAL sum(_hyper_37_71_chunk.cpu) -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_37_71_chunk Output: _hyper_37_71_chunk.cpu -> Parallel Seq Scan on _timescaledb_internal.compress_hyper_38_72_chunk Output: compress_hyper_38_72_chunk."time", compress_hyper_38_72_chunk.sensor_id, compress_hyper_38_72_chunk.cpu, compress_hyper_38_72_chunk.temperature, compress_hyper_38_72_chunk._ts_meta_count, compress_hyper_38_72_chunk._ts_meta_sequence_num, compress_hyper_38_72_chunk._ts_meta_min_1, compress_hyper_38_72_chunk._ts_meta_max_1 -(14 rows) +(16 rows) :explain SELECT * FROM f_sensor_data WHERE sensor_id > 100; diff --git a/tsl/test/expected/compression_ddl.out b/tsl/test/expected/compression_ddl.out index 2f4aeb35fe4..ac9a0d6041e 100644 --- a/tsl/test/expected/compression_ddl.out +++ b/tsl/test/expected/compression_ddl.out @@ -1473,17 +1473,21 @@ EXPLAIN (costs off) SELECT device_id, count(*) FROM compression_insert GROUP BY device_id ORDER BY device_id; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ - Sort - Sort Key: _hyper_32_107_chunk.device_id - -> HashAggregate - Group Key: _hyper_32_107_chunk.device_id + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Finalize GroupAggregate + Group Key: _hyper_32_107_chunk.device_id + -> Sort + Sort Key: _hyper_32_107_chunk.device_id -> Append - -> Custom Scan (DecompressChunk) on _hyper_32_107_chunk - -> Index Scan using compress_hyper_33_108_chunk__compressed_hypertable_33_device_id on compress_hyper_33_108_chunk - -> Index Only Scan using _hyper_32_107_chunk_compression_insert_device_id_time_idx on _hyper_32_107_chunk -(8 rows) + -> Partial GroupAggregate + Group Key: _hyper_32_107_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_107_chunk + -> Index Scan using compress_hyper_33_108_chunk__compressed_hypertable_33_device_id on compress_hyper_33_108_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_107_chunk.device_id + -> Index Only Scan using _hyper_32_107_chunk_compression_insert_device_id_time_idx on _hyper_32_107_chunk +(12 rows) SELECT device_id, count(*) FROM compression_insert @@ -1551,19 +1555,25 @@ EXPLAIN (costs off) SELECT device_id, count(*) FROM compression_insert GROUP BY device_id ORDER BY device_id; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ - Sort - Sort Key: _hyper_32_107_chunk.device_id - -> HashAggregate - Group Key: _hyper_32_107_chunk.device_id + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Finalize GroupAggregate + Group Key: _hyper_32_107_chunk.device_id + -> Sort + Sort Key: _hyper_32_107_chunk.device_id -> Append - -> Custom Scan (DecompressChunk) on _hyper_32_107_chunk - -> Index Scan using compress_hyper_33_108_chunk__compressed_hypertable_33_device_id on compress_hyper_33_108_chunk - -> Custom Scan (DecompressChunk) on _hyper_32_109_chunk - -> Index Scan using compress_hyper_33_110_chunk__compressed_hypertable_33_device_id on compress_hyper_33_110_chunk - -> Index Only Scan using _hyper_32_109_chunk_compression_insert_device_id_time_idx on _hyper_32_109_chunk -(10 rows) + -> Partial GroupAggregate + Group Key: _hyper_32_107_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_107_chunk + -> Index Scan using compress_hyper_33_108_chunk__compressed_hypertable_33_device_id on compress_hyper_33_108_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_109_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_109_chunk + -> Index Scan using compress_hyper_33_110_chunk__compressed_hypertable_33_device_id on compress_hyper_33_110_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_109_chunk.device_id + -> Index Only Scan using _hyper_32_109_chunk_compression_insert_device_id_time_idx on _hyper_32_109_chunk +(16 rows) SELECT device_id, count(*) FROM compression_insert @@ -1631,21 +1641,29 @@ EXPLAIN (costs off) SELECT device_id, count(*) FROM compression_insert GROUP BY device_id ORDER BY device_id; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ - Sort - Sort Key: _hyper_32_107_chunk.device_id - -> HashAggregate - Group Key: _hyper_32_107_chunk.device_id + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Finalize GroupAggregate + Group Key: _hyper_32_107_chunk.device_id + -> Sort + Sort Key: _hyper_32_107_chunk.device_id -> Append - -> Custom Scan (DecompressChunk) on _hyper_32_107_chunk - -> Index Scan using compress_hyper_33_108_chunk__compressed_hypertable_33_device_id on compress_hyper_33_108_chunk - -> Custom Scan (DecompressChunk) on _hyper_32_109_chunk - -> Index Scan using compress_hyper_33_110_chunk__compressed_hypertable_33_device_id on compress_hyper_33_110_chunk - -> Custom Scan (DecompressChunk) on _hyper_32_111_chunk - -> Index Scan using compress_hyper_33_112_chunk__compressed_hypertable_33_device_id on compress_hyper_33_112_chunk - -> Index Only Scan using _hyper_32_111_chunk_compression_insert_device_id_time_idx on _hyper_32_111_chunk -(12 rows) + -> Partial GroupAggregate + Group Key: _hyper_32_107_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_107_chunk + -> Index Scan using compress_hyper_33_108_chunk__compressed_hypertable_33_device_id on compress_hyper_33_108_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_109_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_109_chunk + -> Index Scan using compress_hyper_33_110_chunk__compressed_hypertable_33_device_id on compress_hyper_33_110_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_111_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_111_chunk + -> Index Scan using compress_hyper_33_112_chunk__compressed_hypertable_33_device_id on compress_hyper_33_112_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_111_chunk.device_id + -> Index Only Scan using _hyper_32_111_chunk_compression_insert_device_id_time_idx on _hyper_32_111_chunk +(20 rows) SELECT device_id, count(*) FROM compression_insert @@ -1713,23 +1731,33 @@ EXPLAIN (costs off) SELECT device_id, count(*) FROM compression_insert GROUP BY device_id ORDER BY device_id; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ - Sort - Sort Key: _hyper_32_107_chunk.device_id - -> HashAggregate - Group Key: _hyper_32_107_chunk.device_id + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Finalize GroupAggregate + Group Key: _hyper_32_107_chunk.device_id + -> Sort + Sort Key: _hyper_32_107_chunk.device_id -> Append - -> Custom Scan (DecompressChunk) on _hyper_32_107_chunk - -> Index Scan using compress_hyper_33_108_chunk__compressed_hypertable_33_device_id on compress_hyper_33_108_chunk - -> Custom Scan (DecompressChunk) on _hyper_32_109_chunk - -> Index Scan using compress_hyper_33_110_chunk__compressed_hypertable_33_device_id on compress_hyper_33_110_chunk - -> Custom Scan (DecompressChunk) on _hyper_32_111_chunk - -> Index Scan using compress_hyper_33_112_chunk__compressed_hypertable_33_device_id on compress_hyper_33_112_chunk - -> Custom Scan (DecompressChunk) on _hyper_32_113_chunk - -> Index Scan using compress_hyper_33_114_chunk__compressed_hypertable_33_device_id on compress_hyper_33_114_chunk - -> Index Only Scan using _hyper_32_113_chunk_compression_insert_device_id_time_idx on _hyper_32_113_chunk -(14 rows) + -> Partial GroupAggregate + Group Key: _hyper_32_107_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_107_chunk + -> Index Scan using compress_hyper_33_108_chunk__compressed_hypertable_33_device_id on compress_hyper_33_108_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_109_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_109_chunk + -> Index Scan using compress_hyper_33_110_chunk__compressed_hypertable_33_device_id on compress_hyper_33_110_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_111_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_111_chunk + -> Index Scan using compress_hyper_33_112_chunk__compressed_hypertable_33_device_id on compress_hyper_33_112_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_113_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_113_chunk + -> Index Scan using compress_hyper_33_114_chunk__compressed_hypertable_33_device_id on compress_hyper_33_114_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_113_chunk.device_id + -> Index Only Scan using _hyper_32_113_chunk_compression_insert_device_id_time_idx on _hyper_32_113_chunk +(24 rows) SELECT device_id, count(*) FROM compression_insert @@ -1797,25 +1825,37 @@ EXPLAIN (costs off) SELECT device_id, count(*) FROM compression_insert GROUP BY device_id ORDER BY device_id; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ - Sort - Sort Key: _hyper_32_107_chunk.device_id - -> HashAggregate - Group Key: _hyper_32_107_chunk.device_id + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Finalize GroupAggregate + Group Key: _hyper_32_107_chunk.device_id + -> Sort + Sort Key: _hyper_32_107_chunk.device_id -> Append - -> Custom Scan (DecompressChunk) on _hyper_32_107_chunk - -> Index Scan using compress_hyper_33_108_chunk__compressed_hypertable_33_device_id on compress_hyper_33_108_chunk - -> Custom Scan (DecompressChunk) on _hyper_32_109_chunk - -> Index Scan using compress_hyper_33_110_chunk__compressed_hypertable_33_device_id on compress_hyper_33_110_chunk - -> Custom Scan (DecompressChunk) on _hyper_32_111_chunk - -> Index Scan using compress_hyper_33_112_chunk__compressed_hypertable_33_device_id on compress_hyper_33_112_chunk - -> Custom Scan (DecompressChunk) on _hyper_32_113_chunk - -> Index Scan using compress_hyper_33_114_chunk__compressed_hypertable_33_device_id on compress_hyper_33_114_chunk - -> Custom Scan (DecompressChunk) on _hyper_32_115_chunk - -> Index Scan using compress_hyper_33_116_chunk__compressed_hypertable_33_device_id on compress_hyper_33_116_chunk - -> Index Only Scan using _hyper_32_115_chunk_compression_insert_device_id_time_idx on _hyper_32_115_chunk -(16 rows) + -> Partial GroupAggregate + Group Key: _hyper_32_107_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_107_chunk + -> Index Scan using compress_hyper_33_108_chunk__compressed_hypertable_33_device_id on compress_hyper_33_108_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_109_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_109_chunk + -> Index Scan using compress_hyper_33_110_chunk__compressed_hypertable_33_device_id on compress_hyper_33_110_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_111_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_111_chunk + -> Index Scan using compress_hyper_33_112_chunk__compressed_hypertable_33_device_id on compress_hyper_33_112_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_113_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_113_chunk + -> Index Scan using compress_hyper_33_114_chunk__compressed_hypertable_33_device_id on compress_hyper_33_114_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_115_chunk.device_id + -> Custom Scan (DecompressChunk) on _hyper_32_115_chunk + -> Index Scan using compress_hyper_33_116_chunk__compressed_hypertable_33_device_id on compress_hyper_33_116_chunk + -> Partial GroupAggregate + Group Key: _hyper_32_115_chunk.device_id + -> Index Only Scan using _hyper_32_115_chunk_compression_insert_device_id_time_idx on _hyper_32_115_chunk +(28 rows) SELECT device_id, count(*) FROM compression_insert diff --git a/tsl/test/expected/compression_qualpushdown.out b/tsl/test/expected/compression_qualpushdown.out index 7219e0acc1f..bc372ba82b5 100644 --- a/tsl/test/expected/compression_qualpushdown.out +++ b/tsl/test/expected/compression_qualpushdown.out @@ -289,22 +289,24 @@ SELECT compress_chunk(i) FROM show_chunks('deleteme') i; (1 row) EXPLAIN (costs off) SELECT sum(data) FROM deleteme WHERE segment::text like '%4%'; - QUERY PLAN ---------------------------------------------------------- - Aggregate - -> Custom Scan (DecompressChunk) on _hyper_7_8_chunk - -> Seq Scan on compress_hyper_8_9_chunk - Filter: ((segment)::text ~~ '%4%'::text) -(4 rows) + QUERY PLAN +--------------------------------------------------------------- + Finalize Aggregate + -> Partial Aggregate + -> Custom Scan (DecompressChunk) on _hyper_7_8_chunk + -> Seq Scan on compress_hyper_8_9_chunk + Filter: ((segment)::text ~~ '%4%'::text) +(5 rows) EXPLAIN (costs off) SELECT sum(data) FROM deleteme WHERE '4' = segment::text; - QUERY PLAN ---------------------------------------------------------- - Aggregate - -> Custom Scan (DecompressChunk) on _hyper_7_8_chunk - -> Seq Scan on compress_hyper_8_9_chunk - Filter: ('4'::text = (segment)::text) -(4 rows) + QUERY PLAN +--------------------------------------------------------------- + Finalize Aggregate + -> Partial Aggregate + -> Custom Scan (DecompressChunk) on _hyper_7_8_chunk + -> Seq Scan on compress_hyper_8_9_chunk + Filter: ('4'::text = (segment)::text) +(5 rows) CREATE TABLE deleteme_with_bytea(time bigint NOT NULL, bdata bytea); SELECT create_hypertable('deleteme_with_bytea', 'time', chunk_time_interval => 1000000); diff --git a/tsl/test/expected/merge_append_partially_compressed-13.out b/tsl/test/expected/merge_append_partially_compressed-13.out index 49989d7d5d1..fd209572a6f 100644 --- a/tsl/test/expected/merge_append_partially_compressed-13.out +++ b/tsl/test/expected/merge_append_partially_compressed-13.out @@ -692,20 +692,35 @@ SELECT * FROM test1 ORDER BY time ASC NULLS FIRST, x3 DESC NULLS LAST, x4 ASC; :PREFIX SELECT x1, x2, max(time) FROM test1 GROUP BY x1, x2, time ORDER BY time limit 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- Limit (actual rows=5 loops=1) -> Sort (actual rows=5 loops=1) - Sort Key: _hyper_3_7_chunk."time" + Sort Key: test1."time" Sort Method: quicksort - -> HashAggregate (actual rows=5 loops=1) - Group Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 + -> Finalize HashAggregate (actual rows=5 loops=1) + Group Key: test1."time", test1.x1, test1.x2 Batches: 1 - -> Append (actual rows=5 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_3_7_chunk (actual rows=4 loops=1) - -> Seq Scan on compress_hyper_4_8_chunk (actual rows=3 loops=1) - -> Seq Scan on _hyper_3_7_chunk (actual rows=1 loops=1) -(11 rows) + -> Custom Scan (ChunkAppend) on test1 (actual rows=5 loops=1) + Order: test1."time", test1.x1, test1.x2 + -> Merge Append (actual rows=5 loops=1) + Sort Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 + -> Sort (actual rows=4 loops=1) + Sort Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 + Sort Method: quicksort + -> Partial HashAggregate (actual rows=4 loops=1) + Group Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 + Batches: 1 + -> Custom Scan (DecompressChunk) on _hyper_3_7_chunk (actual rows=4 loops=1) + -> Seq Scan on compress_hyper_4_8_chunk (actual rows=3 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 + Sort Method: quicksort + -> Partial HashAggregate (actual rows=1 loops=1) + Group Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 + Batches: 1 + -> Seq Scan on _hyper_3_7_chunk (actual rows=1 loops=1) +(26 rows) :PREFIX SELECT * FROM test1 ORDER BY x1, x2, x5, x4, time LIMIT 10; diff --git a/tsl/test/expected/merge_append_partially_compressed-14.out b/tsl/test/expected/merge_append_partially_compressed-14.out index d52bea26d64..581c40679dd 100644 --- a/tsl/test/expected/merge_append_partially_compressed-14.out +++ b/tsl/test/expected/merge_append_partially_compressed-14.out @@ -692,25 +692,35 @@ SELECT * FROM test1 ORDER BY time ASC NULLS FIRST, x3 DESC NULLS LAST, x4 ASC; :PREFIX SELECT x1, x2, max(time) FROM test1 GROUP BY x1, x2, time ORDER BY time limit 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- Limit (actual rows=5 loops=1) - -> GroupAggregate (actual rows=5 loops=1) - Group Key: test1."time", test1.x1, test1.x2 - -> Custom Scan (ChunkAppend) on test1 (actual rows=5 loops=1) - Order: test1."time", test1.x1, test1.x2 - -> Merge Append (actual rows=5 loops=1) - Sort Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 - -> Sort (actual rows=4 loops=1) - Sort Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 - Sort Method: quicksort - -> Custom Scan (DecompressChunk) on _hyper_3_7_chunk (actual rows=4 loops=1) - -> Seq Scan on compress_hyper_4_8_chunk (actual rows=3 loops=1) - -> Sort (actual rows=1 loops=1) + -> Sort (actual rows=5 loops=1) + Sort Key: test1."time" + Sort Method: quicksort + -> Finalize HashAggregate (actual rows=5 loops=1) + Group Key: test1."time", test1.x1, test1.x2 + Batches: 1 + -> Custom Scan (ChunkAppend) on test1 (actual rows=5 loops=1) + Order: test1."time", test1.x1, test1.x2 + -> Merge Append (actual rows=5 loops=1) Sort Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 - Sort Method: quicksort - -> Seq Scan on _hyper_3_7_chunk (actual rows=1 loops=1) -(16 rows) + -> Sort (actual rows=4 loops=1) + Sort Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 + Sort Method: quicksort + -> Partial HashAggregate (actual rows=4 loops=1) + Group Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 + Batches: 1 + -> Custom Scan (DecompressChunk) on _hyper_3_7_chunk (actual rows=4 loops=1) + -> Seq Scan on compress_hyper_4_8_chunk (actual rows=3 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 + Sort Method: quicksort + -> Partial HashAggregate (actual rows=1 loops=1) + Group Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 + Batches: 1 + -> Seq Scan on _hyper_3_7_chunk (actual rows=1 loops=1) +(26 rows) :PREFIX SELECT * FROM test1 ORDER BY x1, x2, x5, x4, time LIMIT 10; diff --git a/tsl/test/expected/merge_append_partially_compressed-15.out b/tsl/test/expected/merge_append_partially_compressed-15.out index eb13e13c1a3..7d33ba0f2a1 100644 --- a/tsl/test/expected/merge_append_partially_compressed-15.out +++ b/tsl/test/expected/merge_append_partially_compressed-15.out @@ -698,25 +698,35 @@ SELECT * FROM test1 ORDER BY time ASC NULLS FIRST, x3 DESC NULLS LAST, x4 ASC; :PREFIX SELECT x1, x2, max(time) FROM test1 GROUP BY x1, x2, time ORDER BY time limit 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- Limit (actual rows=5 loops=1) - -> GroupAggregate (actual rows=5 loops=1) - Group Key: test1."time", test1.x1, test1.x2 - -> Custom Scan (ChunkAppend) on test1 (actual rows=5 loops=1) - Order: test1."time", test1.x1, test1.x2 - -> Merge Append (actual rows=5 loops=1) - Sort Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 - -> Sort (actual rows=4 loops=1) - Sort Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 - Sort Method: quicksort - -> Custom Scan (DecompressChunk) on _hyper_3_7_chunk (actual rows=4 loops=1) - -> Seq Scan on compress_hyper_4_8_chunk (actual rows=3 loops=1) - -> Sort (actual rows=1 loops=1) + -> Sort (actual rows=5 loops=1) + Sort Key: test1."time" + Sort Method: quicksort + -> Finalize HashAggregate (actual rows=5 loops=1) + Group Key: test1."time", test1.x1, test1.x2 + Batches: 1 + -> Custom Scan (ChunkAppend) on test1 (actual rows=5 loops=1) + Order: test1."time", test1.x1, test1.x2 + -> Merge Append (actual rows=5 loops=1) Sort Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 - Sort Method: quicksort - -> Seq Scan on _hyper_3_7_chunk (actual rows=1 loops=1) -(16 rows) + -> Sort (actual rows=4 loops=1) + Sort Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 + Sort Method: quicksort + -> Partial HashAggregate (actual rows=4 loops=1) + Group Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 + Batches: 1 + -> Custom Scan (DecompressChunk) on _hyper_3_7_chunk (actual rows=4 loops=1) + -> Seq Scan on compress_hyper_4_8_chunk (actual rows=3 loops=1) + -> Sort (actual rows=1 loops=1) + Sort Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 + Sort Method: quicksort + -> Partial HashAggregate (actual rows=1 loops=1) + Group Key: _hyper_3_7_chunk."time", _hyper_3_7_chunk.x1, _hyper_3_7_chunk.x2 + Batches: 1 + -> Seq Scan on _hyper_3_7_chunk (actual rows=1 loops=1) +(26 rows) :PREFIX SELECT * FROM test1 ORDER BY x1, x2, x5, x4, time LIMIT 10; diff --git a/tsl/test/expected/partialize_finalize.out b/tsl/test/expected/partialize_finalize.out index f04de07bd5f..fc3b1c60d7b 100644 --- a/tsl/test/expected/partialize_finalize.out +++ b/tsl/test/expected/partialize_finalize.out @@ -426,212 +426,412 @@ EXPLAIN (VERBOSE, COSTS OFF) -> Gather Output: (PARTIAL sum(_hyper_2_4_chunk.value)), (PARTIAL avg(_hyper_2_4_chunk.value)), (PARTIAL min(_hyper_2_4_chunk.value)), (PARTIAL max(_hyper_2_4_chunk.value)), (PARTIAL count(*)) Workers Planned: 2 - -> Partial Aggregate - Output: PARTIAL sum(_hyper_2_4_chunk.value), PARTIAL avg(_hyper_2_4_chunk.value), PARTIAL min(_hyper_2_4_chunk.value), PARTIAL max(_hyper_2_4_chunk.value), PARTIAL count(*) - -> Parallel Append + -> Parallel Append + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_4_chunk.value), PARTIAL avg(_hyper_2_4_chunk.value), PARTIAL min(_hyper_2_4_chunk.value), PARTIAL max(_hyper_2_4_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_4_chunk Output: _hyper_2_4_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_5_chunk.value), PARTIAL avg(_hyper_2_5_chunk.value), PARTIAL min(_hyper_2_5_chunk.value), PARTIAL max(_hyper_2_5_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_5_chunk Output: _hyper_2_5_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_6_chunk.value), PARTIAL avg(_hyper_2_6_chunk.value), PARTIAL min(_hyper_2_6_chunk.value), PARTIAL max(_hyper_2_6_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_6_chunk Output: _hyper_2_6_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_7_chunk.value), PARTIAL avg(_hyper_2_7_chunk.value), PARTIAL min(_hyper_2_7_chunk.value), PARTIAL max(_hyper_2_7_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_7_chunk Output: _hyper_2_7_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_8_chunk.value), PARTIAL avg(_hyper_2_8_chunk.value), PARTIAL min(_hyper_2_8_chunk.value), PARTIAL max(_hyper_2_8_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_8_chunk Output: _hyper_2_8_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_9_chunk.value), PARTIAL avg(_hyper_2_9_chunk.value), PARTIAL min(_hyper_2_9_chunk.value), PARTIAL max(_hyper_2_9_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_9_chunk Output: _hyper_2_9_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_10_chunk.value), PARTIAL avg(_hyper_2_10_chunk.value), PARTIAL min(_hyper_2_10_chunk.value), PARTIAL max(_hyper_2_10_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_10_chunk Output: _hyper_2_10_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_11_chunk.value), PARTIAL avg(_hyper_2_11_chunk.value), PARTIAL min(_hyper_2_11_chunk.value), PARTIAL max(_hyper_2_11_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_11_chunk Output: _hyper_2_11_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_12_chunk.value), PARTIAL avg(_hyper_2_12_chunk.value), PARTIAL min(_hyper_2_12_chunk.value), PARTIAL max(_hyper_2_12_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_12_chunk Output: _hyper_2_12_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_13_chunk.value), PARTIAL avg(_hyper_2_13_chunk.value), PARTIAL min(_hyper_2_13_chunk.value), PARTIAL max(_hyper_2_13_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_13_chunk Output: _hyper_2_13_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_14_chunk.value), PARTIAL avg(_hyper_2_14_chunk.value), PARTIAL min(_hyper_2_14_chunk.value), PARTIAL max(_hyper_2_14_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_14_chunk Output: _hyper_2_14_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_15_chunk.value), PARTIAL avg(_hyper_2_15_chunk.value), PARTIAL min(_hyper_2_15_chunk.value), PARTIAL max(_hyper_2_15_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_15_chunk Output: _hyper_2_15_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_16_chunk.value), PARTIAL avg(_hyper_2_16_chunk.value), PARTIAL min(_hyper_2_16_chunk.value), PARTIAL max(_hyper_2_16_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_16_chunk Output: _hyper_2_16_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_17_chunk.value), PARTIAL avg(_hyper_2_17_chunk.value), PARTIAL min(_hyper_2_17_chunk.value), PARTIAL max(_hyper_2_17_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_17_chunk Output: _hyper_2_17_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_18_chunk.value), PARTIAL avg(_hyper_2_18_chunk.value), PARTIAL min(_hyper_2_18_chunk.value), PARTIAL max(_hyper_2_18_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_18_chunk Output: _hyper_2_18_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_19_chunk.value), PARTIAL avg(_hyper_2_19_chunk.value), PARTIAL min(_hyper_2_19_chunk.value), PARTIAL max(_hyper_2_19_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_19_chunk Output: _hyper_2_19_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_20_chunk.value), PARTIAL avg(_hyper_2_20_chunk.value), PARTIAL min(_hyper_2_20_chunk.value), PARTIAL max(_hyper_2_20_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_20_chunk Output: _hyper_2_20_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_21_chunk.value), PARTIAL avg(_hyper_2_21_chunk.value), PARTIAL min(_hyper_2_21_chunk.value), PARTIAL max(_hyper_2_21_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_21_chunk Output: _hyper_2_21_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_22_chunk.value), PARTIAL avg(_hyper_2_22_chunk.value), PARTIAL min(_hyper_2_22_chunk.value), PARTIAL max(_hyper_2_22_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_22_chunk Output: _hyper_2_22_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_23_chunk.value), PARTIAL avg(_hyper_2_23_chunk.value), PARTIAL min(_hyper_2_23_chunk.value), PARTIAL max(_hyper_2_23_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_23_chunk Output: _hyper_2_23_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_24_chunk.value), PARTIAL avg(_hyper_2_24_chunk.value), PARTIAL min(_hyper_2_24_chunk.value), PARTIAL max(_hyper_2_24_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_24_chunk Output: _hyper_2_24_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_25_chunk.value), PARTIAL avg(_hyper_2_25_chunk.value), PARTIAL min(_hyper_2_25_chunk.value), PARTIAL max(_hyper_2_25_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_25_chunk Output: _hyper_2_25_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_26_chunk.value), PARTIAL avg(_hyper_2_26_chunk.value), PARTIAL min(_hyper_2_26_chunk.value), PARTIAL max(_hyper_2_26_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_26_chunk Output: _hyper_2_26_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_27_chunk.value), PARTIAL avg(_hyper_2_27_chunk.value), PARTIAL min(_hyper_2_27_chunk.value), PARTIAL max(_hyper_2_27_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_27_chunk Output: _hyper_2_27_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_28_chunk.value), PARTIAL avg(_hyper_2_28_chunk.value), PARTIAL min(_hyper_2_28_chunk.value), PARTIAL max(_hyper_2_28_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_28_chunk Output: _hyper_2_28_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_29_chunk.value), PARTIAL avg(_hyper_2_29_chunk.value), PARTIAL min(_hyper_2_29_chunk.value), PARTIAL max(_hyper_2_29_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_29_chunk Output: _hyper_2_29_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_30_chunk.value), PARTIAL avg(_hyper_2_30_chunk.value), PARTIAL min(_hyper_2_30_chunk.value), PARTIAL max(_hyper_2_30_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_30_chunk Output: _hyper_2_30_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_31_chunk.value), PARTIAL avg(_hyper_2_31_chunk.value), PARTIAL min(_hyper_2_31_chunk.value), PARTIAL max(_hyper_2_31_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_31_chunk Output: _hyper_2_31_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_32_chunk.value), PARTIAL avg(_hyper_2_32_chunk.value), PARTIAL min(_hyper_2_32_chunk.value), PARTIAL max(_hyper_2_32_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_32_chunk Output: _hyper_2_32_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_33_chunk.value), PARTIAL avg(_hyper_2_33_chunk.value), PARTIAL min(_hyper_2_33_chunk.value), PARTIAL max(_hyper_2_33_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_33_chunk Output: _hyper_2_33_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_34_chunk.value), PARTIAL avg(_hyper_2_34_chunk.value), PARTIAL min(_hyper_2_34_chunk.value), PARTIAL max(_hyper_2_34_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_34_chunk Output: _hyper_2_34_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_35_chunk.value), PARTIAL avg(_hyper_2_35_chunk.value), PARTIAL min(_hyper_2_35_chunk.value), PARTIAL max(_hyper_2_35_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_35_chunk Output: _hyper_2_35_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_36_chunk.value), PARTIAL avg(_hyper_2_36_chunk.value), PARTIAL min(_hyper_2_36_chunk.value), PARTIAL max(_hyper_2_36_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_36_chunk Output: _hyper_2_36_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_37_chunk.value), PARTIAL avg(_hyper_2_37_chunk.value), PARTIAL min(_hyper_2_37_chunk.value), PARTIAL max(_hyper_2_37_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_37_chunk Output: _hyper_2_37_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_38_chunk.value), PARTIAL avg(_hyper_2_38_chunk.value), PARTIAL min(_hyper_2_38_chunk.value), PARTIAL max(_hyper_2_38_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_38_chunk Output: _hyper_2_38_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_39_chunk.value), PARTIAL avg(_hyper_2_39_chunk.value), PARTIAL min(_hyper_2_39_chunk.value), PARTIAL max(_hyper_2_39_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_39_chunk Output: _hyper_2_39_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_40_chunk.value), PARTIAL avg(_hyper_2_40_chunk.value), PARTIAL min(_hyper_2_40_chunk.value), PARTIAL max(_hyper_2_40_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_40_chunk Output: _hyper_2_40_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_41_chunk.value), PARTIAL avg(_hyper_2_41_chunk.value), PARTIAL min(_hyper_2_41_chunk.value), PARTIAL max(_hyper_2_41_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_41_chunk Output: _hyper_2_41_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_42_chunk.value), PARTIAL avg(_hyper_2_42_chunk.value), PARTIAL min(_hyper_2_42_chunk.value), PARTIAL max(_hyper_2_42_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_42_chunk Output: _hyper_2_42_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_43_chunk.value), PARTIAL avg(_hyper_2_43_chunk.value), PARTIAL min(_hyper_2_43_chunk.value), PARTIAL max(_hyper_2_43_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_43_chunk Output: _hyper_2_43_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_44_chunk.value), PARTIAL avg(_hyper_2_44_chunk.value), PARTIAL min(_hyper_2_44_chunk.value), PARTIAL max(_hyper_2_44_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_44_chunk Output: _hyper_2_44_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_45_chunk.value), PARTIAL avg(_hyper_2_45_chunk.value), PARTIAL min(_hyper_2_45_chunk.value), PARTIAL max(_hyper_2_45_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_45_chunk Output: _hyper_2_45_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_46_chunk.value), PARTIAL avg(_hyper_2_46_chunk.value), PARTIAL min(_hyper_2_46_chunk.value), PARTIAL max(_hyper_2_46_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_46_chunk Output: _hyper_2_46_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_47_chunk.value), PARTIAL avg(_hyper_2_47_chunk.value), PARTIAL min(_hyper_2_47_chunk.value), PARTIAL max(_hyper_2_47_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_47_chunk Output: _hyper_2_47_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_48_chunk.value), PARTIAL avg(_hyper_2_48_chunk.value), PARTIAL min(_hyper_2_48_chunk.value), PARTIAL max(_hyper_2_48_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_48_chunk Output: _hyper_2_48_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_49_chunk.value), PARTIAL avg(_hyper_2_49_chunk.value), PARTIAL min(_hyper_2_49_chunk.value), PARTIAL max(_hyper_2_49_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_49_chunk Output: _hyper_2_49_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_50_chunk.value), PARTIAL avg(_hyper_2_50_chunk.value), PARTIAL min(_hyper_2_50_chunk.value), PARTIAL max(_hyper_2_50_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_50_chunk Output: _hyper_2_50_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_51_chunk.value), PARTIAL avg(_hyper_2_51_chunk.value), PARTIAL min(_hyper_2_51_chunk.value), PARTIAL max(_hyper_2_51_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_51_chunk Output: _hyper_2_51_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_52_chunk.value), PARTIAL avg(_hyper_2_52_chunk.value), PARTIAL min(_hyper_2_52_chunk.value), PARTIAL max(_hyper_2_52_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_52_chunk Output: _hyper_2_52_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_53_chunk.value), PARTIAL avg(_hyper_2_53_chunk.value), PARTIAL min(_hyper_2_53_chunk.value), PARTIAL max(_hyper_2_53_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_53_chunk Output: _hyper_2_53_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_54_chunk.value), PARTIAL avg(_hyper_2_54_chunk.value), PARTIAL min(_hyper_2_54_chunk.value), PARTIAL max(_hyper_2_54_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_54_chunk Output: _hyper_2_54_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_55_chunk.value), PARTIAL avg(_hyper_2_55_chunk.value), PARTIAL min(_hyper_2_55_chunk.value), PARTIAL max(_hyper_2_55_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_55_chunk Output: _hyper_2_55_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_56_chunk.value), PARTIAL avg(_hyper_2_56_chunk.value), PARTIAL min(_hyper_2_56_chunk.value), PARTIAL max(_hyper_2_56_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_56_chunk Output: _hyper_2_56_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_57_chunk.value), PARTIAL avg(_hyper_2_57_chunk.value), PARTIAL min(_hyper_2_57_chunk.value), PARTIAL max(_hyper_2_57_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_57_chunk Output: _hyper_2_57_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_58_chunk.value), PARTIAL avg(_hyper_2_58_chunk.value), PARTIAL min(_hyper_2_58_chunk.value), PARTIAL max(_hyper_2_58_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_58_chunk Output: _hyper_2_58_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_59_chunk.value), PARTIAL avg(_hyper_2_59_chunk.value), PARTIAL min(_hyper_2_59_chunk.value), PARTIAL max(_hyper_2_59_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_59_chunk Output: _hyper_2_59_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_60_chunk.value), PARTIAL avg(_hyper_2_60_chunk.value), PARTIAL min(_hyper_2_60_chunk.value), PARTIAL max(_hyper_2_60_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_60_chunk Output: _hyper_2_60_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_61_chunk.value), PARTIAL avg(_hyper_2_61_chunk.value), PARTIAL min(_hyper_2_61_chunk.value), PARTIAL max(_hyper_2_61_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_61_chunk Output: _hyper_2_61_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_62_chunk.value), PARTIAL avg(_hyper_2_62_chunk.value), PARTIAL min(_hyper_2_62_chunk.value), PARTIAL max(_hyper_2_62_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_62_chunk Output: _hyper_2_62_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_63_chunk.value), PARTIAL avg(_hyper_2_63_chunk.value), PARTIAL min(_hyper_2_63_chunk.value), PARTIAL max(_hyper_2_63_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_63_chunk Output: _hyper_2_63_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_64_chunk.value), PARTIAL avg(_hyper_2_64_chunk.value), PARTIAL min(_hyper_2_64_chunk.value), PARTIAL max(_hyper_2_64_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_64_chunk Output: _hyper_2_64_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_65_chunk.value), PARTIAL avg(_hyper_2_65_chunk.value), PARTIAL min(_hyper_2_65_chunk.value), PARTIAL max(_hyper_2_65_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_65_chunk Output: _hyper_2_65_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_66_chunk.value), PARTIAL avg(_hyper_2_66_chunk.value), PARTIAL min(_hyper_2_66_chunk.value), PARTIAL max(_hyper_2_66_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_66_chunk Output: _hyper_2_66_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_67_chunk.value), PARTIAL avg(_hyper_2_67_chunk.value), PARTIAL min(_hyper_2_67_chunk.value), PARTIAL max(_hyper_2_67_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_67_chunk Output: _hyper_2_67_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_68_chunk.value), PARTIAL avg(_hyper_2_68_chunk.value), PARTIAL min(_hyper_2_68_chunk.value), PARTIAL max(_hyper_2_68_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_68_chunk Output: _hyper_2_68_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_69_chunk.value), PARTIAL avg(_hyper_2_69_chunk.value), PARTIAL min(_hyper_2_69_chunk.value), PARTIAL max(_hyper_2_69_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_69_chunk Output: _hyper_2_69_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_70_chunk.value), PARTIAL avg(_hyper_2_70_chunk.value), PARTIAL min(_hyper_2_70_chunk.value), PARTIAL max(_hyper_2_70_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_70_chunk Output: _hyper_2_70_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_71_chunk.value), PARTIAL avg(_hyper_2_71_chunk.value), PARTIAL min(_hyper_2_71_chunk.value), PARTIAL max(_hyper_2_71_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_71_chunk Output: _hyper_2_71_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_72_chunk.value), PARTIAL avg(_hyper_2_72_chunk.value), PARTIAL min(_hyper_2_72_chunk.value), PARTIAL max(_hyper_2_72_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_72_chunk Output: _hyper_2_72_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_73_chunk.value), PARTIAL avg(_hyper_2_73_chunk.value), PARTIAL min(_hyper_2_73_chunk.value), PARTIAL max(_hyper_2_73_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_73_chunk Output: _hyper_2_73_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_74_chunk.value), PARTIAL avg(_hyper_2_74_chunk.value), PARTIAL min(_hyper_2_74_chunk.value), PARTIAL max(_hyper_2_74_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_74_chunk Output: _hyper_2_74_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_75_chunk.value), PARTIAL avg(_hyper_2_75_chunk.value), PARTIAL min(_hyper_2_75_chunk.value), PARTIAL max(_hyper_2_75_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_75_chunk Output: _hyper_2_75_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_76_chunk.value), PARTIAL avg(_hyper_2_76_chunk.value), PARTIAL min(_hyper_2_76_chunk.value), PARTIAL max(_hyper_2_76_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_76_chunk Output: _hyper_2_76_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_77_chunk.value), PARTIAL avg(_hyper_2_77_chunk.value), PARTIAL min(_hyper_2_77_chunk.value), PARTIAL max(_hyper_2_77_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_77_chunk Output: _hyper_2_77_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_78_chunk.value), PARTIAL avg(_hyper_2_78_chunk.value), PARTIAL min(_hyper_2_78_chunk.value), PARTIAL max(_hyper_2_78_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_78_chunk Output: _hyper_2_78_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_79_chunk.value), PARTIAL avg(_hyper_2_79_chunk.value), PARTIAL min(_hyper_2_79_chunk.value), PARTIAL max(_hyper_2_79_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_79_chunk Output: _hyper_2_79_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_80_chunk.value), PARTIAL avg(_hyper_2_80_chunk.value), PARTIAL min(_hyper_2_80_chunk.value), PARTIAL max(_hyper_2_80_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_80_chunk Output: _hyper_2_80_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_81_chunk.value), PARTIAL avg(_hyper_2_81_chunk.value), PARTIAL min(_hyper_2_81_chunk.value), PARTIAL max(_hyper_2_81_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_81_chunk Output: _hyper_2_81_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_82_chunk.value), PARTIAL avg(_hyper_2_82_chunk.value), PARTIAL min(_hyper_2_82_chunk.value), PARTIAL max(_hyper_2_82_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_82_chunk Output: _hyper_2_82_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_83_chunk.value), PARTIAL avg(_hyper_2_83_chunk.value), PARTIAL min(_hyper_2_83_chunk.value), PARTIAL max(_hyper_2_83_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_83_chunk Output: _hyper_2_83_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_84_chunk.value), PARTIAL avg(_hyper_2_84_chunk.value), PARTIAL min(_hyper_2_84_chunk.value), PARTIAL max(_hyper_2_84_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_84_chunk Output: _hyper_2_84_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_85_chunk.value), PARTIAL avg(_hyper_2_85_chunk.value), PARTIAL min(_hyper_2_85_chunk.value), PARTIAL max(_hyper_2_85_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_85_chunk Output: _hyper_2_85_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_86_chunk.value), PARTIAL avg(_hyper_2_86_chunk.value), PARTIAL min(_hyper_2_86_chunk.value), PARTIAL max(_hyper_2_86_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_86_chunk Output: _hyper_2_86_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_87_chunk.value), PARTIAL avg(_hyper_2_87_chunk.value), PARTIAL min(_hyper_2_87_chunk.value), PARTIAL max(_hyper_2_87_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_87_chunk Output: _hyper_2_87_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_88_chunk.value), PARTIAL avg(_hyper_2_88_chunk.value), PARTIAL min(_hyper_2_88_chunk.value), PARTIAL max(_hyper_2_88_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_88_chunk Output: _hyper_2_88_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_89_chunk.value), PARTIAL avg(_hyper_2_89_chunk.value), PARTIAL min(_hyper_2_89_chunk.value), PARTIAL max(_hyper_2_89_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_89_chunk Output: _hyper_2_89_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_90_chunk.value), PARTIAL avg(_hyper_2_90_chunk.value), PARTIAL min(_hyper_2_90_chunk.value), PARTIAL max(_hyper_2_90_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_90_chunk Output: _hyper_2_90_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_91_chunk.value), PARTIAL avg(_hyper_2_91_chunk.value), PARTIAL min(_hyper_2_91_chunk.value), PARTIAL max(_hyper_2_91_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_91_chunk Output: _hyper_2_91_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_92_chunk.value), PARTIAL avg(_hyper_2_92_chunk.value), PARTIAL min(_hyper_2_92_chunk.value), PARTIAL max(_hyper_2_92_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_92_chunk Output: _hyper_2_92_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_93_chunk.value), PARTIAL avg(_hyper_2_93_chunk.value), PARTIAL min(_hyper_2_93_chunk.value), PARTIAL max(_hyper_2_93_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_93_chunk Output: _hyper_2_93_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_94_chunk.value), PARTIAL avg(_hyper_2_94_chunk.value), PARTIAL min(_hyper_2_94_chunk.value), PARTIAL max(_hyper_2_94_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_94_chunk Output: _hyper_2_94_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_95_chunk.value), PARTIAL avg(_hyper_2_95_chunk.value), PARTIAL min(_hyper_2_95_chunk.value), PARTIAL max(_hyper_2_95_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_95_chunk Output: _hyper_2_95_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_96_chunk.value), PARTIAL avg(_hyper_2_96_chunk.value), PARTIAL min(_hyper_2_96_chunk.value), PARTIAL max(_hyper_2_96_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_96_chunk Output: _hyper_2_96_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_97_chunk.value), PARTIAL avg(_hyper_2_97_chunk.value), PARTIAL min(_hyper_2_97_chunk.value), PARTIAL max(_hyper_2_97_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_97_chunk Output: _hyper_2_97_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_98_chunk.value), PARTIAL avg(_hyper_2_98_chunk.value), PARTIAL min(_hyper_2_98_chunk.value), PARTIAL max(_hyper_2_98_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_98_chunk Output: _hyper_2_98_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_99_chunk.value), PARTIAL avg(_hyper_2_99_chunk.value), PARTIAL min(_hyper_2_99_chunk.value), PARTIAL max(_hyper_2_99_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_99_chunk Output: _hyper_2_99_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_100_chunk.value), PARTIAL avg(_hyper_2_100_chunk.value), PARTIAL min(_hyper_2_100_chunk.value), PARTIAL max(_hyper_2_100_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_100_chunk Output: _hyper_2_100_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_101_chunk.value), PARTIAL avg(_hyper_2_101_chunk.value), PARTIAL min(_hyper_2_101_chunk.value), PARTIAL max(_hyper_2_101_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_101_chunk Output: _hyper_2_101_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_102_chunk.value), PARTIAL avg(_hyper_2_102_chunk.value), PARTIAL min(_hyper_2_102_chunk.value), PARTIAL max(_hyper_2_102_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_102_chunk Output: _hyper_2_102_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_103_chunk.value), PARTIAL avg(_hyper_2_103_chunk.value), PARTIAL min(_hyper_2_103_chunk.value), PARTIAL max(_hyper_2_103_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_103_chunk Output: _hyper_2_103_chunk.value + -> Partial Aggregate + Output: PARTIAL sum(_hyper_2_104_chunk.value), PARTIAL avg(_hyper_2_104_chunk.value), PARTIAL min(_hyper_2_104_chunk.value), PARTIAL max(_hyper_2_104_chunk.value), PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._hyper_2_104_chunk Output: _hyper_2_104_chunk.value -(210 rows) +(410 rows) CREATE MATERIALIZED VIEW issue4922_partials_parallel AS SELECT diff --git a/tsl/test/expected/transparent_decompression-13.out b/tsl/test/expected/transparent_decompression-13.out index 83c11d8be3a..f20245b447d 100644 --- a/tsl/test/expected/transparent_decompression-13.out +++ b/tsl/test/expected/transparent_decompression-13.out @@ -1665,38 +1665,57 @@ ORDER BY time, :PREFIX SELECT count(*) FROM :TEST_TABLE; - QUERY PLAN ------------------------------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=6840 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) - -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) - -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) -(7 rows) - --- test aggregate with GROUP BY -:PREFIX -SELECT count(*) -FROM :TEST_TABLE -GROUP BY device_id -ORDER BY device_id; QUERY PLAN ------------------------------------------------------------------------------------------------ - Sort (actual rows=5 loops=1) - Sort Key: _hyper_1_1_chunk.device_id - Sort Method: quicksort - -> HashAggregate (actual rows=5 loops=1) - Group Key: _hyper_1_1_chunk.device_id - Batches: 1 - -> Append (actual rows=6840 loops=1) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) -(12 rows) +(10 rows) + +-- test aggregate with GROUP BY +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; +:PREFIX +SELECT count(*) +FROM :TEST_TABLE +GROUP BY device_id +ORDER BY device_id; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Finalize GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_1_chunk.device_id + -> Sort (actual rows=15 loops=1) + Sort Key: _hyper_1_1_chunk.device_id + Sort Method: quicksort + -> Append (actual rows=15 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_1_chunk.device_id + -> Sort (actual rows=1800 loops=1) + Sort Key: _hyper_1_1_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) + -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_2_chunk.device_id + -> Sort (actual rows=2520 loops=1) + Sort Key: _hyper_1_2_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_3_chunk.device_id + -> Sort (actual rows=2520 loops=1) + Sort Key: _hyper_1_3_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) + -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) +(26 rows) -- test window functions with GROUP BY :PREFIX @@ -1704,23 +1723,38 @@ SELECT sum(count(*)) OVER () FROM :TEST_TABLE GROUP BY device_id ORDER BY device_id; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - Sort (actual rows=5 loops=1) - Sort Key: _hyper_1_1_chunk.device_id - Sort Method: quicksort - -> WindowAgg (actual rows=5 loops=1) - -> HashAggregate (actual rows=5 loops=1) - Group Key: _hyper_1_1_chunk.device_id - Batches: 1 - -> Append (actual rows=6840 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) - -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) - -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) -(13 rows) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------ + WindowAgg (actual rows=5 loops=1) + -> Finalize GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_1_chunk.device_id + -> Sort (actual rows=15 loops=1) + Sort Key: _hyper_1_1_chunk.device_id + Sort Method: quicksort + -> Append (actual rows=15 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_1_chunk.device_id + -> Sort (actual rows=1800 loops=1) + Sort Key: _hyper_1_1_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) + -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_2_chunk.device_id + -> Sort (actual rows=2520 loops=1) + Sort Key: _hyper_1_2_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_3_chunk.device_id + -> Sort (actual rows=2520 loops=1) + Sort Key: _hyper_1_3_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) + -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) +(27 rows) +SET enable_hashagg = ON; -- test CTE :PREFIX WITH q AS ( SELECT v1 @@ -1821,22 +1855,25 @@ SELECT count(time) FROM :TEST_TABLE WHERE device_id = 1; :PREFIX EXECUTE prep; - QUERY PLAN ------------------------------------------------------------------------------------------ - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=1368 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_5_15_chunk (actual rows=1 loops=1) - Filter: (device_id = 1) - Rows Removed by Filter: 4 - -> Seq Scan on _hyper_1_2_chunk (actual rows=504 loops=1) - Filter: (device_id = 1) - Rows Removed by Filter: 2016 - -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=504 loops=1) - -> Seq Scan on compress_hyper_5_16_chunk (actual rows=1 loops=1) + QUERY PLAN +----------------------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_5_15_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + Rows Removed by Filter: 4 + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_1_2_chunk (actual rows=504 loops=1) Filter: (device_id = 1) - Rows Removed by Filter: 4 -(13 rows) + Rows Removed by Filter: 2016 + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=504 loops=1) + -> Seq Scan on compress_hyper_5_16_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + Rows Removed by Filter: 4 +(16 rows) EXECUTE prep; count @@ -2024,27 +2061,33 @@ ORDER BY device_id; SELECT count(*) FROM :TEST_TABLE WHERE device_id = 1; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) Output: count(*) - -> Append (actual rows=1368 loops=1) - -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk (actual rows=360 loops=1) - Bulk Decompression: false - -> Index Only Scan using compress_hyper_5_15_chunk_c_index_2 on _timescaledb_internal.compress_hyper_5_15_chunk (actual rows=1 loops=1) - Output: compress_hyper_5_15_chunk.device_id, compress_hyper_5_15_chunk._ts_meta_count - Index Cond: (compress_hyper_5_15_chunk.device_id = 1) - Heap Fetches: 1 - -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (actual rows=504 loops=1) - Filter: (_hyper_1_2_chunk.device_id = 1) - Rows Removed by Filter: 2016 - -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_3_chunk (actual rows=504 loops=1) - Bulk Decompression: false - -> Index Only Scan using compress_hyper_5_16_chunk_c_index_2 on _timescaledb_internal.compress_hyper_5_16_chunk (actual rows=1 loops=1) - Output: compress_hyper_5_16_chunk.device_id, compress_hyper_5_16_chunk._ts_meta_count - Index Cond: (compress_hyper_5_16_chunk.device_id = 1) - Heap Fetches: 1 -(18 rows) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk (actual rows=360 loops=1) + Bulk Decompression: false + -> Index Only Scan using compress_hyper_5_15_chunk_c_index_2 on _timescaledb_internal.compress_hyper_5_15_chunk (actual rows=1 loops=1) + Output: compress_hyper_5_15_chunk.device_id, compress_hyper_5_15_chunk._ts_meta_count + Index Cond: (compress_hyper_5_15_chunk.device_id = 1) + Heap Fetches: 1 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (actual rows=504 loops=1) + Filter: (_hyper_1_2_chunk.device_id = 1) + Rows Removed by Filter: 2016 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_3_chunk (actual rows=504 loops=1) + Bulk Decompression: false + -> Index Only Scan using compress_hyper_5_16_chunk_c_index_2 on _timescaledb_internal.compress_hyper_5_16_chunk (actual rows=1 loops=1) + Output: compress_hyper_5_16_chunk.device_id, compress_hyper_5_16_chunk._ts_meta_count + Index Cond: (compress_hyper_5_16_chunk.device_id = 1) + Heap Fetches: 1 +(24 rows) -- should be able to order using an index CREATE INDEX tmp_idx ON :TEST_TABLE (device_id); @@ -5665,56 +5708,111 @@ ORDER BY time, :PREFIX SELECT count(*) FROM :TEST_TABLE; - QUERY PLAN -------------------------------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=6840 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) - -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) - -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) - -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) - -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) - -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) - -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) -(16 rows) - --- test aggregate with GROUP BY -:PREFIX -SELECT count(*) -FROM :TEST_TABLE -GROUP BY device_id -ORDER BY device_id; QUERY PLAN ------------------------------------------------------------------------------------------------- - Sort (actual rows=5 loops=1) - Sort Key: _hyper_2_4_chunk.device_id - Sort Method: quicksort - -> HashAggregate (actual rows=5 loops=1) - Group Key: _hyper_2_4_chunk.device_id - Batches: 1 - -> Append (actual rows=6840 loops=1) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) -(21 rows) +(25 rows) + +-- test aggregate with GROUP BY +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; +:PREFIX +SELECT count(*) +FROM :TEST_TABLE +GROUP BY device_id +ORDER BY device_id; + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Finalize GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_2_4_chunk.device_id + -> Sort (actual rows=15 loops=1) + Sort Key: _hyper_2_4_chunk.device_id + Sort Method: quicksort + -> Append (actual rows=15 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_4_chunk.device_id + -> Sort (actual rows=360 loops=1) + Sort Key: _hyper_2_4_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_5_chunk.device_id + -> Sort (actual rows=1080 loops=1) + Sort Key: _hyper_2_5_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) + -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_6_chunk.device_id + -> Sort (actual rows=360 loops=1) + Sort Key: _hyper_2_6_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_7_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_7_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_8_chunk.device_id + -> Sort (actual rows=1512 loops=1) + Sort Key: _hyper_2_8_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_9_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_9_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_10_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_10_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) + -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_11_chunk.device_id + -> Sort (actual rows=1512 loops=1) + Sort Key: _hyper_2_11_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) + -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_12_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_12_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) +(65 rows) -- test window functions with GROUP BY :PREFIX @@ -5722,32 +5820,77 @@ SELECT sum(count(*)) OVER () FROM :TEST_TABLE GROUP BY device_id ORDER BY device_id; - QUERY PLAN -------------------------------------------------------------------------------------------------------- - Sort (actual rows=5 loops=1) - Sort Key: _hyper_2_4_chunk.device_id - Sort Method: quicksort - -> WindowAgg (actual rows=5 loops=1) - -> HashAggregate (actual rows=5 loops=1) - Group Key: _hyper_2_4_chunk.device_id - Batches: 1 - -> Append (actual rows=6840 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) - -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) - -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) - -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) - -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) - -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) - -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) -(22 rows) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + WindowAgg (actual rows=5 loops=1) + -> Finalize GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_2_4_chunk.device_id + -> Sort (actual rows=15 loops=1) + Sort Key: _hyper_2_4_chunk.device_id + Sort Method: quicksort + -> Append (actual rows=15 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_4_chunk.device_id + -> Sort (actual rows=360 loops=1) + Sort Key: _hyper_2_4_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_5_chunk.device_id + -> Sort (actual rows=1080 loops=1) + Sort Key: _hyper_2_5_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) + -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_6_chunk.device_id + -> Sort (actual rows=360 loops=1) + Sort Key: _hyper_2_6_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_7_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_7_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_8_chunk.device_id + -> Sort (actual rows=1512 loops=1) + Sort Key: _hyper_2_8_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_9_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_9_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_10_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_10_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) + -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_11_chunk.device_id + -> Sort (actual rows=1512 loops=1) + Sort Key: _hyper_2_11_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) + -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_12_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_12_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) +(66 rows) +SET enable_hashagg = ON; -- test CTE :PREFIX WITH q AS ( SELECT v1 @@ -5883,19 +6026,22 @@ SELECT count(time) FROM :TEST_TABLE WHERE device_id = 1; :PREFIX EXECUTE prep; - QUERY PLAN ------------------------------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=1368 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) - Filter: (device_id = 1) - -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) - Filter: (device_id = 1) - -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) - -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + QUERY PLAN +------------------------------------------------------------------------------------------------ + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) Filter: (device_id = 1) -(10 rows) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) + -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) +(13 rows) EXECUTE prep; count @@ -6080,27 +6226,33 @@ ORDER BY device_id; SELECT count(*) FROM :TEST_TABLE WHERE device_id = 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - Aggregate (actual rows=1 loops=1) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) Output: count(*) - -> Append (actual rows=1368 loops=1) - -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_2_4_chunk (actual rows=360 loops=1) - Bulk Decompression: false - -> Index Only Scan using compress_hyper_6_17_chunk_c_space_index_2 on _timescaledb_internal.compress_hyper_6_17_chunk (actual rows=1 loops=1) - Output: compress_hyper_6_17_chunk.device_id, compress_hyper_6_17_chunk._ts_meta_count - Index Cond: (compress_hyper_6_17_chunk.device_id = 1) - Heap Fetches: 1 - -> Index Only Scan using _hyper_2_7_chunk_metrics_space_device_id_device_id_peer_v0_v1_2 on _timescaledb_internal._hyper_2_7_chunk (actual rows=504 loops=1) - Index Cond: (_hyper_2_7_chunk.device_id = 1) - Heap Fetches: 504 - -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_2_10_chunk (actual rows=504 loops=1) - Bulk Decompression: false - -> Index Only Scan using compress_hyper_6_20_chunk_c_space_index_2 on _timescaledb_internal.compress_hyper_6_20_chunk (actual rows=1 loops=1) - Output: compress_hyper_6_20_chunk.device_id, compress_hyper_6_20_chunk._ts_meta_count - Index Cond: (compress_hyper_6_20_chunk.device_id = 1) - Heap Fetches: 1 -(18 rows) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_2_4_chunk (actual rows=360 loops=1) + Bulk Decompression: false + -> Index Only Scan using compress_hyper_6_17_chunk_c_space_index_2 on _timescaledb_internal.compress_hyper_6_17_chunk (actual rows=1 loops=1) + Output: compress_hyper_6_17_chunk.device_id, compress_hyper_6_17_chunk._ts_meta_count + Index Cond: (compress_hyper_6_17_chunk.device_id = 1) + Heap Fetches: 1 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_device_id_device_id_peer_v0_v1_2 on _timescaledb_internal._hyper_2_7_chunk (actual rows=504 loops=1) + Index Cond: (_hyper_2_7_chunk.device_id = 1) + Heap Fetches: 504 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_2_10_chunk (actual rows=504 loops=1) + Bulk Decompression: false + -> Index Only Scan using compress_hyper_6_20_chunk_c_space_index_2 on _timescaledb_internal.compress_hyper_6_20_chunk (actual rows=1 loops=1) + Output: compress_hyper_6_20_chunk.device_id, compress_hyper_6_20_chunk._ts_meta_count + Index Cond: (compress_hyper_6_20_chunk.device_id = 1) + Heap Fetches: 1 +(24 rows) -- should be able to order using an index CREATE INDEX tmp_idx ON :TEST_TABLE (device_id); diff --git a/tsl/test/expected/transparent_decompression-14.out b/tsl/test/expected/transparent_decompression-14.out index ff969d000f4..40e35a338b1 100644 --- a/tsl/test/expected/transparent_decompression-14.out +++ b/tsl/test/expected/transparent_decompression-14.out @@ -1665,38 +1665,57 @@ ORDER BY time, :PREFIX SELECT count(*) FROM :TEST_TABLE; - QUERY PLAN ------------------------------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=6840 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) - -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) - -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) -(7 rows) - --- test aggregate with GROUP BY -:PREFIX -SELECT count(*) -FROM :TEST_TABLE -GROUP BY device_id -ORDER BY device_id; QUERY PLAN ------------------------------------------------------------------------------------------------ - Sort (actual rows=5 loops=1) - Sort Key: _hyper_1_1_chunk.device_id - Sort Method: quicksort - -> HashAggregate (actual rows=5 loops=1) - Group Key: _hyper_1_1_chunk.device_id - Batches: 1 - -> Append (actual rows=6840 loops=1) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) -(12 rows) +(10 rows) + +-- test aggregate with GROUP BY +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; +:PREFIX +SELECT count(*) +FROM :TEST_TABLE +GROUP BY device_id +ORDER BY device_id; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Finalize GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_1_chunk.device_id + -> Sort (actual rows=15 loops=1) + Sort Key: _hyper_1_1_chunk.device_id + Sort Method: quicksort + -> Append (actual rows=15 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_1_chunk.device_id + -> Sort (actual rows=1800 loops=1) + Sort Key: _hyper_1_1_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) + -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_2_chunk.device_id + -> Sort (actual rows=2520 loops=1) + Sort Key: _hyper_1_2_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_3_chunk.device_id + -> Sort (actual rows=2520 loops=1) + Sort Key: _hyper_1_3_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) + -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) +(26 rows) -- test window functions with GROUP BY :PREFIX @@ -1704,23 +1723,38 @@ SELECT sum(count(*)) OVER () FROM :TEST_TABLE GROUP BY device_id ORDER BY device_id; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - Sort (actual rows=5 loops=1) - Sort Key: _hyper_1_1_chunk.device_id - Sort Method: quicksort - -> WindowAgg (actual rows=5 loops=1) - -> HashAggregate (actual rows=5 loops=1) - Group Key: _hyper_1_1_chunk.device_id - Batches: 1 - -> Append (actual rows=6840 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) - -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) - -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) -(13 rows) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------ + WindowAgg (actual rows=5 loops=1) + -> Finalize GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_1_chunk.device_id + -> Sort (actual rows=15 loops=1) + Sort Key: _hyper_1_1_chunk.device_id + Sort Method: quicksort + -> Append (actual rows=15 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_1_chunk.device_id + -> Sort (actual rows=1800 loops=1) + Sort Key: _hyper_1_1_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) + -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_2_chunk.device_id + -> Sort (actual rows=2520 loops=1) + Sort Key: _hyper_1_2_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_3_chunk.device_id + -> Sort (actual rows=2520 loops=1) + Sort Key: _hyper_1_3_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) + -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) +(27 rows) +SET enable_hashagg = ON; -- test CTE :PREFIX WITH q AS ( SELECT v1 @@ -1821,22 +1855,25 @@ SELECT count(time) FROM :TEST_TABLE WHERE device_id = 1; :PREFIX EXECUTE prep; - QUERY PLAN ------------------------------------------------------------------------------------------ - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=1368 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_5_15_chunk (actual rows=1 loops=1) - Filter: (device_id = 1) - Rows Removed by Filter: 4 - -> Seq Scan on _hyper_1_2_chunk (actual rows=504 loops=1) - Filter: (device_id = 1) - Rows Removed by Filter: 2016 - -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=504 loops=1) - -> Seq Scan on compress_hyper_5_16_chunk (actual rows=1 loops=1) + QUERY PLAN +----------------------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_5_15_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + Rows Removed by Filter: 4 + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_1_2_chunk (actual rows=504 loops=1) Filter: (device_id = 1) - Rows Removed by Filter: 4 -(13 rows) + Rows Removed by Filter: 2016 + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=504 loops=1) + -> Seq Scan on compress_hyper_5_16_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + Rows Removed by Filter: 4 +(16 rows) EXECUTE prep; count @@ -2024,27 +2061,33 @@ ORDER BY device_id; SELECT count(*) FROM :TEST_TABLE WHERE device_id = 1; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) Output: count(*) - -> Append (actual rows=1368 loops=1) - -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk (actual rows=360 loops=1) - Bulk Decompression: false - -> Index Only Scan using compress_hyper_5_15_chunk_c_index_2 on _timescaledb_internal.compress_hyper_5_15_chunk (actual rows=1 loops=1) - Output: compress_hyper_5_15_chunk.device_id, compress_hyper_5_15_chunk._ts_meta_count - Index Cond: (compress_hyper_5_15_chunk.device_id = 1) - Heap Fetches: 1 - -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (actual rows=504 loops=1) - Filter: (_hyper_1_2_chunk.device_id = 1) - Rows Removed by Filter: 2016 - -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_3_chunk (actual rows=504 loops=1) - Bulk Decompression: false - -> Index Only Scan using compress_hyper_5_16_chunk_c_index_2 on _timescaledb_internal.compress_hyper_5_16_chunk (actual rows=1 loops=1) - Output: compress_hyper_5_16_chunk.device_id, compress_hyper_5_16_chunk._ts_meta_count - Index Cond: (compress_hyper_5_16_chunk.device_id = 1) - Heap Fetches: 1 -(18 rows) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk (actual rows=360 loops=1) + Bulk Decompression: false + -> Index Only Scan using compress_hyper_5_15_chunk_c_index_2 on _timescaledb_internal.compress_hyper_5_15_chunk (actual rows=1 loops=1) + Output: compress_hyper_5_15_chunk.device_id, compress_hyper_5_15_chunk._ts_meta_count + Index Cond: (compress_hyper_5_15_chunk.device_id = 1) + Heap Fetches: 1 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (actual rows=504 loops=1) + Filter: (_hyper_1_2_chunk.device_id = 1) + Rows Removed by Filter: 2016 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_3_chunk (actual rows=504 loops=1) + Bulk Decompression: false + -> Index Only Scan using compress_hyper_5_16_chunk_c_index_2 on _timescaledb_internal.compress_hyper_5_16_chunk (actual rows=1 loops=1) + Output: compress_hyper_5_16_chunk.device_id, compress_hyper_5_16_chunk._ts_meta_count + Index Cond: (compress_hyper_5_16_chunk.device_id = 1) + Heap Fetches: 1 +(24 rows) -- should be able to order using an index CREATE INDEX tmp_idx ON :TEST_TABLE (device_id); @@ -5858,56 +5901,111 @@ ORDER BY time, :PREFIX SELECT count(*) FROM :TEST_TABLE; - QUERY PLAN -------------------------------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=6840 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) - -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) - -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) - -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) - -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) - -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) - -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) -(16 rows) - --- test aggregate with GROUP BY -:PREFIX -SELECT count(*) -FROM :TEST_TABLE -GROUP BY device_id -ORDER BY device_id; QUERY PLAN ------------------------------------------------------------------------------------------------- - Sort (actual rows=5 loops=1) - Sort Key: _hyper_2_4_chunk.device_id - Sort Method: quicksort - -> HashAggregate (actual rows=5 loops=1) - Group Key: _hyper_2_4_chunk.device_id - Batches: 1 - -> Append (actual rows=6840 loops=1) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) -(21 rows) +(25 rows) + +-- test aggregate with GROUP BY +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; +:PREFIX +SELECT count(*) +FROM :TEST_TABLE +GROUP BY device_id +ORDER BY device_id; + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Finalize GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_2_4_chunk.device_id + -> Sort (actual rows=15 loops=1) + Sort Key: _hyper_2_4_chunk.device_id + Sort Method: quicksort + -> Append (actual rows=15 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_4_chunk.device_id + -> Sort (actual rows=360 loops=1) + Sort Key: _hyper_2_4_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_5_chunk.device_id + -> Sort (actual rows=1080 loops=1) + Sort Key: _hyper_2_5_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) + -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_6_chunk.device_id + -> Sort (actual rows=360 loops=1) + Sort Key: _hyper_2_6_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_7_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_7_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_8_chunk.device_id + -> Sort (actual rows=1512 loops=1) + Sort Key: _hyper_2_8_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_9_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_9_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_10_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_10_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) + -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_11_chunk.device_id + -> Sort (actual rows=1512 loops=1) + Sort Key: _hyper_2_11_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) + -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_12_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_12_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) +(65 rows) -- test window functions with GROUP BY :PREFIX @@ -5915,32 +6013,77 @@ SELECT sum(count(*)) OVER () FROM :TEST_TABLE GROUP BY device_id ORDER BY device_id; - QUERY PLAN -------------------------------------------------------------------------------------------------------- - Sort (actual rows=5 loops=1) - Sort Key: _hyper_2_4_chunk.device_id - Sort Method: quicksort - -> WindowAgg (actual rows=5 loops=1) - -> HashAggregate (actual rows=5 loops=1) - Group Key: _hyper_2_4_chunk.device_id - Batches: 1 - -> Append (actual rows=6840 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) - -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) - -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) - -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) - -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) - -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) - -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) -(22 rows) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + WindowAgg (actual rows=5 loops=1) + -> Finalize GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_2_4_chunk.device_id + -> Sort (actual rows=15 loops=1) + Sort Key: _hyper_2_4_chunk.device_id + Sort Method: quicksort + -> Append (actual rows=15 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_4_chunk.device_id + -> Sort (actual rows=360 loops=1) + Sort Key: _hyper_2_4_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_5_chunk.device_id + -> Sort (actual rows=1080 loops=1) + Sort Key: _hyper_2_5_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) + -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_6_chunk.device_id + -> Sort (actual rows=360 loops=1) + Sort Key: _hyper_2_6_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_7_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_7_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_8_chunk.device_id + -> Sort (actual rows=1512 loops=1) + Sort Key: _hyper_2_8_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_9_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_9_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_10_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_10_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) + -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_11_chunk.device_id + -> Sort (actual rows=1512 loops=1) + Sort Key: _hyper_2_11_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) + -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_12_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_12_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) +(66 rows) +SET enable_hashagg = ON; -- test CTE :PREFIX WITH q AS ( SELECT v1 @@ -6076,19 +6219,22 @@ SELECT count(time) FROM :TEST_TABLE WHERE device_id = 1; :PREFIX EXECUTE prep; - QUERY PLAN ------------------------------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=1368 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) - Filter: (device_id = 1) - -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) - Filter: (device_id = 1) - -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) - -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + QUERY PLAN +------------------------------------------------------------------------------------------------ + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) Filter: (device_id = 1) -(10 rows) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) + -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) +(13 rows) EXECUTE prep; count @@ -6273,27 +6419,33 @@ ORDER BY device_id; SELECT count(*) FROM :TEST_TABLE WHERE device_id = 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - Aggregate (actual rows=1 loops=1) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) Output: count(*) - -> Append (actual rows=1368 loops=1) - -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_2_4_chunk (actual rows=360 loops=1) - Bulk Decompression: false - -> Index Only Scan using compress_hyper_6_17_chunk_c_space_index_2 on _timescaledb_internal.compress_hyper_6_17_chunk (actual rows=1 loops=1) - Output: compress_hyper_6_17_chunk.device_id, compress_hyper_6_17_chunk._ts_meta_count - Index Cond: (compress_hyper_6_17_chunk.device_id = 1) - Heap Fetches: 1 - -> Index Only Scan using _hyper_2_7_chunk_metrics_space_device_id_device_id_peer_v0_v1_2 on _timescaledb_internal._hyper_2_7_chunk (actual rows=504 loops=1) - Index Cond: (_hyper_2_7_chunk.device_id = 1) - Heap Fetches: 504 - -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_2_10_chunk (actual rows=504 loops=1) - Bulk Decompression: false - -> Index Only Scan using compress_hyper_6_20_chunk_c_space_index_2 on _timescaledb_internal.compress_hyper_6_20_chunk (actual rows=1 loops=1) - Output: compress_hyper_6_20_chunk.device_id, compress_hyper_6_20_chunk._ts_meta_count - Index Cond: (compress_hyper_6_20_chunk.device_id = 1) - Heap Fetches: 1 -(18 rows) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_2_4_chunk (actual rows=360 loops=1) + Bulk Decompression: false + -> Index Only Scan using compress_hyper_6_17_chunk_c_space_index_2 on _timescaledb_internal.compress_hyper_6_17_chunk (actual rows=1 loops=1) + Output: compress_hyper_6_17_chunk.device_id, compress_hyper_6_17_chunk._ts_meta_count + Index Cond: (compress_hyper_6_17_chunk.device_id = 1) + Heap Fetches: 1 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_device_id_device_id_peer_v0_v1_2 on _timescaledb_internal._hyper_2_7_chunk (actual rows=504 loops=1) + Index Cond: (_hyper_2_7_chunk.device_id = 1) + Heap Fetches: 504 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_2_10_chunk (actual rows=504 loops=1) + Bulk Decompression: false + -> Index Only Scan using compress_hyper_6_20_chunk_c_space_index_2 on _timescaledb_internal.compress_hyper_6_20_chunk (actual rows=1 loops=1) + Output: compress_hyper_6_20_chunk.device_id, compress_hyper_6_20_chunk._ts_meta_count + Index Cond: (compress_hyper_6_20_chunk.device_id = 1) + Heap Fetches: 1 +(24 rows) -- should be able to order using an index CREATE INDEX tmp_idx ON :TEST_TABLE (device_id); diff --git a/tsl/test/expected/transparent_decompression-15.out b/tsl/test/expected/transparent_decompression-15.out index 867133ec27d..a7977d88063 100644 --- a/tsl/test/expected/transparent_decompression-15.out +++ b/tsl/test/expected/transparent_decompression-15.out @@ -1666,38 +1666,57 @@ ORDER BY time, :PREFIX SELECT count(*) FROM :TEST_TABLE; - QUERY PLAN ------------------------------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=6840 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) - -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) - -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) -(7 rows) - --- test aggregate with GROUP BY -:PREFIX -SELECT count(*) -FROM :TEST_TABLE -GROUP BY device_id -ORDER BY device_id; QUERY PLAN ------------------------------------------------------------------------------------------------ - Sort (actual rows=5 loops=1) - Sort Key: _hyper_1_1_chunk.device_id - Sort Method: quicksort - -> HashAggregate (actual rows=5 loops=1) - Group Key: _hyper_1_1_chunk.device_id - Batches: 1 - -> Append (actual rows=6840 loops=1) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) -(12 rows) +(10 rows) + +-- test aggregate with GROUP BY +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; +:PREFIX +SELECT count(*) +FROM :TEST_TABLE +GROUP BY device_id +ORDER BY device_id; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Finalize GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_1_chunk.device_id + -> Sort (actual rows=15 loops=1) + Sort Key: _hyper_1_1_chunk.device_id + Sort Method: quicksort + -> Append (actual rows=15 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_1_chunk.device_id + -> Sort (actual rows=1800 loops=1) + Sort Key: _hyper_1_1_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) + -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_2_chunk.device_id + -> Sort (actual rows=2520 loops=1) + Sort Key: _hyper_1_2_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_3_chunk.device_id + -> Sort (actual rows=2520 loops=1) + Sort Key: _hyper_1_3_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) + -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) +(26 rows) -- test window functions with GROUP BY :PREFIX @@ -1705,23 +1724,38 @@ SELECT sum(count(*)) OVER () FROM :TEST_TABLE GROUP BY device_id ORDER BY device_id; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - Sort (actual rows=5 loops=1) - Sort Key: _hyper_1_1_chunk.device_id - Sort Method: quicksort - -> WindowAgg (actual rows=5 loops=1) - -> HashAggregate (actual rows=5 loops=1) - Group Key: _hyper_1_1_chunk.device_id - Batches: 1 - -> Append (actual rows=6840 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) - -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) - -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) - -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) -(13 rows) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------ + WindowAgg (actual rows=5 loops=1) + -> Finalize GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_1_chunk.device_id + -> Sort (actual rows=15 loops=1) + Sort Key: _hyper_1_1_chunk.device_id + Sort Method: quicksort + -> Append (actual rows=15 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_1_chunk.device_id + -> Sort (actual rows=1800 loops=1) + Sort Key: _hyper_1_1_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=1800 loops=1) + -> Seq Scan on compress_hyper_5_15_chunk (actual rows=5 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_2_chunk.device_id + -> Sort (actual rows=2520 loops=1) + Sort Key: _hyper_1_2_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_1_2_chunk (actual rows=2520 loops=1) + -> Partial GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_1_3_chunk.device_id + -> Sort (actual rows=2520 loops=1) + Sort Key: _hyper_1_3_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=2520 loops=1) + -> Seq Scan on compress_hyper_5_16_chunk (actual rows=5 loops=1) +(27 rows) +SET enable_hashagg = ON; -- test CTE :PREFIX WITH q AS ( SELECT v1 @@ -1822,22 +1856,25 @@ SELECT count(time) FROM :TEST_TABLE WHERE device_id = 1; :PREFIX EXECUTE prep; - QUERY PLAN ------------------------------------------------------------------------------------------ - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=1368 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_5_15_chunk (actual rows=1 loops=1) - Filter: (device_id = 1) - Rows Removed by Filter: 4 - -> Seq Scan on _hyper_1_2_chunk (actual rows=504 loops=1) - Filter: (device_id = 1) - Rows Removed by Filter: 2016 - -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=504 loops=1) - -> Seq Scan on compress_hyper_5_16_chunk (actual rows=1 loops=1) + QUERY PLAN +----------------------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_1_1_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_5_15_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + Rows Removed by Filter: 4 + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_1_2_chunk (actual rows=504 loops=1) Filter: (device_id = 1) - Rows Removed by Filter: 4 -(13 rows) + Rows Removed by Filter: 2016 + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_1_3_chunk (actual rows=504 loops=1) + -> Seq Scan on compress_hyper_5_16_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + Rows Removed by Filter: 4 +(16 rows) EXECUTE prep; count @@ -2025,27 +2062,33 @@ ORDER BY device_id; SELECT count(*) FROM :TEST_TABLE WHERE device_id = 1; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) Output: count(*) - -> Append (actual rows=1368 loops=1) - -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk (actual rows=360 loops=1) - Bulk Decompression: false - -> Index Only Scan using compress_hyper_5_15_chunk_c_index_2 on _timescaledb_internal.compress_hyper_5_15_chunk (actual rows=1 loops=1) - Output: compress_hyper_5_15_chunk.device_id, compress_hyper_5_15_chunk._ts_meta_count - Index Cond: (compress_hyper_5_15_chunk.device_id = 1) - Heap Fetches: 1 - -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (actual rows=504 loops=1) - Filter: (_hyper_1_2_chunk.device_id = 1) - Rows Removed by Filter: 2016 - -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_3_chunk (actual rows=504 loops=1) - Bulk Decompression: false - -> Index Only Scan using compress_hyper_5_16_chunk_c_index_2 on _timescaledb_internal.compress_hyper_5_16_chunk (actual rows=1 loops=1) - Output: compress_hyper_5_16_chunk.device_id, compress_hyper_5_16_chunk._ts_meta_count - Index Cond: (compress_hyper_5_16_chunk.device_id = 1) - Heap Fetches: 1 -(18 rows) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_1_chunk (actual rows=360 loops=1) + Bulk Decompression: false + -> Index Only Scan using compress_hyper_5_15_chunk_c_index_2 on _timescaledb_internal.compress_hyper_5_15_chunk (actual rows=1 loops=1) + Output: compress_hyper_5_15_chunk.device_id, compress_hyper_5_15_chunk._ts_meta_count + Index Cond: (compress_hyper_5_15_chunk.device_id = 1) + Heap Fetches: 1 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Seq Scan on _timescaledb_internal._hyper_1_2_chunk (actual rows=504 loops=1) + Filter: (_hyper_1_2_chunk.device_id = 1) + Rows Removed by Filter: 2016 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_1_3_chunk (actual rows=504 loops=1) + Bulk Decompression: false + -> Index Only Scan using compress_hyper_5_16_chunk_c_index_2 on _timescaledb_internal.compress_hyper_5_16_chunk (actual rows=1 loops=1) + Output: compress_hyper_5_16_chunk.device_id, compress_hyper_5_16_chunk._ts_meta_count + Index Cond: (compress_hyper_5_16_chunk.device_id = 1) + Heap Fetches: 1 +(24 rows) -- should be able to order using an index CREATE INDEX tmp_idx ON :TEST_TABLE (device_id); @@ -5860,56 +5903,111 @@ ORDER BY time, :PREFIX SELECT count(*) FROM :TEST_TABLE; - QUERY PLAN -------------------------------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=6840 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) - -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) - -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) - -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) - -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) - -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) - -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) -(16 rows) - --- test aggregate with GROUP BY -:PREFIX -SELECT count(*) -FROM :TEST_TABLE -GROUP BY device_id -ORDER BY device_id; QUERY PLAN ------------------------------------------------------------------------------------------------- - Sort (actual rows=5 loops=1) - Sort Key: _hyper_2_4_chunk.device_id - Sort Method: quicksort - -> HashAggregate (actual rows=5 loops=1) - Group Key: _hyper_2_4_chunk.device_id - Batches: 1 - -> Append (actual rows=6840 loops=1) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) -(21 rows) +(25 rows) + +-- test aggregate with GROUP BY +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; +:PREFIX +SELECT count(*) +FROM :TEST_TABLE +GROUP BY device_id +ORDER BY device_id; + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Finalize GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_2_4_chunk.device_id + -> Sort (actual rows=15 loops=1) + Sort Key: _hyper_2_4_chunk.device_id + Sort Method: quicksort + -> Append (actual rows=15 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_4_chunk.device_id + -> Sort (actual rows=360 loops=1) + Sort Key: _hyper_2_4_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_5_chunk.device_id + -> Sort (actual rows=1080 loops=1) + Sort Key: _hyper_2_5_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) + -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_6_chunk.device_id + -> Sort (actual rows=360 loops=1) + Sort Key: _hyper_2_6_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_7_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_7_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_8_chunk.device_id + -> Sort (actual rows=1512 loops=1) + Sort Key: _hyper_2_8_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_9_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_9_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_10_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_10_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) + -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_11_chunk.device_id + -> Sort (actual rows=1512 loops=1) + Sort Key: _hyper_2_11_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) + -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_12_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_12_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) +(65 rows) -- test window functions with GROUP BY :PREFIX @@ -5917,32 +6015,77 @@ SELECT sum(count(*)) OVER () FROM :TEST_TABLE GROUP BY device_id ORDER BY device_id; - QUERY PLAN -------------------------------------------------------------------------------------------------------- - Sort (actual rows=5 loops=1) - Sort Key: _hyper_2_4_chunk.device_id - Sort Method: quicksort - -> WindowAgg (actual rows=5 loops=1) - -> HashAggregate (actual rows=5 loops=1) - Group Key: _hyper_2_4_chunk.device_id - Batches: 1 - -> Append (actual rows=6840 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) - -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) - -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) - -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) - -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) - -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) - -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) - -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) -(22 rows) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + WindowAgg (actual rows=5 loops=1) + -> Finalize GroupAggregate (actual rows=5 loops=1) + Group Key: _hyper_2_4_chunk.device_id + -> Sort (actual rows=15 loops=1) + Sort Key: _hyper_2_4_chunk.device_id + Sort Method: quicksort + -> Append (actual rows=15 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_4_chunk.device_id + -> Sort (actual rows=360 loops=1) + Sort Key: _hyper_2_4_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_5_chunk.device_id + -> Sort (actual rows=1080 loops=1) + Sort Key: _hyper_2_5_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_5_chunk (actual rows=1080 loops=1) + -> Seq Scan on compress_hyper_6_18_chunk (actual rows=3 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_6_chunk.device_id + -> Sort (actual rows=360 loops=1) + Sort Key: _hyper_2_6_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_6_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_19_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_7_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_7_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_8_chunk.device_id + -> Sort (actual rows=1512 loops=1) + Sort Key: _hyper_2_8_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_8_chunk (actual rows=1512 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_9_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_9_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_9_chunk (actual rows=504 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_10_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_10_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) + -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + -> Partial GroupAggregate (actual rows=3 loops=1) + Group Key: _hyper_2_11_chunk.device_id + -> Sort (actual rows=1512 loops=1) + Sort Key: _hyper_2_11_chunk.device_id + Sort Method: quicksort + -> Custom Scan (DecompressChunk) on _hyper_2_11_chunk (actual rows=1512 loops=1) + -> Seq Scan on compress_hyper_6_21_chunk (actual rows=3 loops=1) + -> Partial GroupAggregate (actual rows=1 loops=1) + Group Key: _hyper_2_12_chunk.device_id + -> Sort (actual rows=504 loops=1) + Sort Key: _hyper_2_12_chunk.device_id + Sort Method: quicksort + -> Seq Scan on _hyper_2_12_chunk (actual rows=504 loops=1) +(66 rows) +SET enable_hashagg = ON; -- test CTE :PREFIX WITH q AS ( SELECT v1 @@ -6078,19 +6221,22 @@ SELECT count(time) FROM :TEST_TABLE WHERE device_id = 1; :PREFIX EXECUTE prep; - QUERY PLAN ------------------------------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=1368 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) - -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) - Filter: (device_id = 1) - -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) - Filter: (device_id = 1) - -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) - -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + QUERY PLAN +------------------------------------------------------------------------------------------------ + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_2_4_chunk (actual rows=360 loops=1) + -> Seq Scan on compress_hyper_6_17_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Seq Scan on _hyper_2_7_chunk (actual rows=504 loops=1) Filter: (device_id = 1) -(10 rows) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_2_10_chunk (actual rows=504 loops=1) + -> Seq Scan on compress_hyper_6_20_chunk (actual rows=1 loops=1) + Filter: (device_id = 1) +(13 rows) EXECUTE prep; count @@ -6275,27 +6421,33 @@ ORDER BY device_id; SELECT count(*) FROM :TEST_TABLE WHERE device_id = 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - Aggregate (actual rows=1 loops=1) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) Output: count(*) - -> Append (actual rows=1368 loops=1) - -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_2_4_chunk (actual rows=360 loops=1) - Bulk Decompression: false - -> Index Only Scan using compress_hyper_6_17_chunk_c_space_index_2 on _timescaledb_internal.compress_hyper_6_17_chunk (actual rows=1 loops=1) - Output: compress_hyper_6_17_chunk.device_id, compress_hyper_6_17_chunk._ts_meta_count - Index Cond: (compress_hyper_6_17_chunk.device_id = 1) - Heap Fetches: 1 - -> Index Only Scan using _hyper_2_7_chunk_metrics_space_device_id_device_id_peer_v0_v1_2 on _timescaledb_internal._hyper_2_7_chunk (actual rows=504 loops=1) - Index Cond: (_hyper_2_7_chunk.device_id = 1) - Heap Fetches: 504 - -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_2_10_chunk (actual rows=504 loops=1) - Bulk Decompression: false - -> Index Only Scan using compress_hyper_6_20_chunk_c_space_index_2 on _timescaledb_internal.compress_hyper_6_20_chunk (actual rows=1 loops=1) - Output: compress_hyper_6_20_chunk.device_id, compress_hyper_6_20_chunk._ts_meta_count - Index Cond: (compress_hyper_6_20_chunk.device_id = 1) - Heap Fetches: 1 -(18 rows) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_2_4_chunk (actual rows=360 loops=1) + Bulk Decompression: false + -> Index Only Scan using compress_hyper_6_17_chunk_c_space_index_2 on _timescaledb_internal.compress_hyper_6_17_chunk (actual rows=1 loops=1) + Output: compress_hyper_6_17_chunk.device_id, compress_hyper_6_17_chunk._ts_meta_count + Index Cond: (compress_hyper_6_17_chunk.device_id = 1) + Heap Fetches: 1 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Index Only Scan using _hyper_2_7_chunk_metrics_space_device_id_device_id_peer_v0_v1_2 on _timescaledb_internal._hyper_2_7_chunk (actual rows=504 loops=1) + Index Cond: (_hyper_2_7_chunk.device_id = 1) + Heap Fetches: 504 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) + -> Custom Scan (DecompressChunk) on _timescaledb_internal._hyper_2_10_chunk (actual rows=504 loops=1) + Bulk Decompression: false + -> Index Only Scan using compress_hyper_6_20_chunk_c_space_index_2 on _timescaledb_internal.compress_hyper_6_20_chunk (actual rows=1 loops=1) + Output: compress_hyper_6_20_chunk.device_id, compress_hyper_6_20_chunk._ts_meta_count + Index Cond: (compress_hyper_6_20_chunk.device_id = 1) + Heap Fetches: 1 +(24 rows) -- should be able to order using an index CREATE INDEX tmp_idx ON :TEST_TABLE (device_id); diff --git a/tsl/test/shared/expected/constify_now-13.out b/tsl/test/shared/expected/constify_now-13.out index 54e890b1806..c95386da2b1 100644 --- a/tsl/test/shared/expected/constify_now-13.out +++ b/tsl/test/shared/expected/constify_now-13.out @@ -557,27 +557,41 @@ CREATE VIEW now_view AS SELECT time, device, avg(value) from now_view_test GROUP -- should have all 5 chunks in EXPLAIN :PREFIX SELECT * FROM now_view; QUERY PLAN - HashAggregate + Finalize HashAggregate Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device -> Append - -> Seq Scan on _hyper_X_X_chunk - -> Seq Scan on _hyper_X_X_chunk - -> Seq Scan on _hyper_X_X_chunk - -> Seq Scan on _hyper_X_X_chunk - -> Seq Scan on _hyper_X_X_chunk -(8 rows) + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk +(18 rows) -- should have 2 chunks in EXPLAIN :PREFIX SELECT * FROM now_view WHERE time > now() - '168h'::interval; QUERY PLAN - HashAggregate + Finalize HashAggregate Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device -> Append - -> Index Scan Backward using _hyper_X_X_chunk_now_view_test_time_idx on _hyper_X_X_chunk - Index Cond: ("time" > (now() - '@ 168 hours'::interval)) - -> Index Scan Backward using _hyper_X_X_chunk_now_view_test_time_idx on _hyper_X_X_chunk - Index Cond: ("time" > (now() - '@ 168 hours'::interval)) -(7 rows) + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Index Scan Backward using _hyper_X_X_chunk_now_view_test_time_idx on _hyper_X_X_chunk + Index Cond: ("time" > (now() - '@ 168 hours'::interval)) + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Index Scan Backward using _hyper_X_X_chunk_now_view_test_time_idx on _hyper_X_X_chunk + Index Cond: ("time" > (now() - '@ 168 hours'::interval)) +(11 rows) DROP TABLE now_view_test CASCADE; NOTICE: drop cascades to view now_view diff --git a/tsl/test/shared/expected/constify_now-14.out b/tsl/test/shared/expected/constify_now-14.out index 05a1a44f6dc..c529cf1e310 100644 --- a/tsl/test/shared/expected/constify_now-14.out +++ b/tsl/test/shared/expected/constify_now-14.out @@ -554,27 +554,41 @@ CREATE VIEW now_view AS SELECT time, device, avg(value) from now_view_test GROUP -- should have all 5 chunks in EXPLAIN :PREFIX SELECT * FROM now_view; QUERY PLAN - HashAggregate + Finalize HashAggregate Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device -> Append - -> Seq Scan on _hyper_X_X_chunk - -> Seq Scan on _hyper_X_X_chunk - -> Seq Scan on _hyper_X_X_chunk - -> Seq Scan on _hyper_X_X_chunk - -> Seq Scan on _hyper_X_X_chunk -(8 rows) + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk +(18 rows) -- should have 2 chunks in EXPLAIN :PREFIX SELECT * FROM now_view WHERE time > now() - '168h'::interval; QUERY PLAN - HashAggregate + Finalize HashAggregate Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device -> Append - -> Index Scan Backward using _hyper_X_X_chunk_now_view_test_time_idx on _hyper_X_X_chunk - Index Cond: ("time" > (now() - '@ 168 hours'::interval)) - -> Index Scan Backward using _hyper_X_X_chunk_now_view_test_time_idx on _hyper_X_X_chunk - Index Cond: ("time" > (now() - '@ 168 hours'::interval)) -(7 rows) + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Index Scan Backward using _hyper_X_X_chunk_now_view_test_time_idx on _hyper_X_X_chunk + Index Cond: ("time" > (now() - '@ 168 hours'::interval)) + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Index Scan Backward using _hyper_X_X_chunk_now_view_test_time_idx on _hyper_X_X_chunk + Index Cond: ("time" > (now() - '@ 168 hours'::interval)) +(11 rows) DROP TABLE now_view_test CASCADE; NOTICE: drop cascades to view now_view diff --git a/tsl/test/shared/expected/constify_now-15.out b/tsl/test/shared/expected/constify_now-15.out index 05a1a44f6dc..c529cf1e310 100644 --- a/tsl/test/shared/expected/constify_now-15.out +++ b/tsl/test/shared/expected/constify_now-15.out @@ -554,27 +554,41 @@ CREATE VIEW now_view AS SELECT time, device, avg(value) from now_view_test GROUP -- should have all 5 chunks in EXPLAIN :PREFIX SELECT * FROM now_view; QUERY PLAN - HashAggregate + Finalize HashAggregate Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device -> Append - -> Seq Scan on _hyper_X_X_chunk - -> Seq Scan on _hyper_X_X_chunk - -> Seq Scan on _hyper_X_X_chunk - -> Seq Scan on _hyper_X_X_chunk - -> Seq Scan on _hyper_X_X_chunk -(8 rows) + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Seq Scan on _hyper_X_X_chunk +(18 rows) -- should have 2 chunks in EXPLAIN :PREFIX SELECT * FROM now_view WHERE time > now() - '168h'::interval; QUERY PLAN - HashAggregate + Finalize HashAggregate Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device -> Append - -> Index Scan Backward using _hyper_X_X_chunk_now_view_test_time_idx on _hyper_X_X_chunk - Index Cond: ("time" > (now() - '@ 168 hours'::interval)) - -> Index Scan Backward using _hyper_X_X_chunk_now_view_test_time_idx on _hyper_X_X_chunk - Index Cond: ("time" > (now() - '@ 168 hours'::interval)) -(7 rows) + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Index Scan Backward using _hyper_X_X_chunk_now_view_test_time_idx on _hyper_X_X_chunk + Index Cond: ("time" > (now() - '@ 168 hours'::interval)) + -> Partial HashAggregate + Group Key: _hyper_X_X_chunk."time", _hyper_X_X_chunk.device + -> Index Scan Backward using _hyper_X_X_chunk_now_view_test_time_idx on _hyper_X_X_chunk + Index Cond: ("time" > (now() - '@ 168 hours'::interval)) +(11 rows) DROP TABLE now_view_test CASCADE; NOTICE: drop cascades to view now_view diff --git a/tsl/test/shared/expected/dist_parallel_agg.out b/tsl/test/shared/expected/dist_parallel_agg.out index 99ae493ee7c..8947fad8772 100644 --- a/tsl/test/shared/expected/dist_parallel_agg.out +++ b/tsl/test/shared/expected/dist_parallel_agg.out @@ -49,15 +49,16 @@ QUERY PLAN Output: (PARTIAL count(*)) Workers Planned: 1 Workers Launched: 1 - -> Partial Aggregate (actual rows=1 loops=2) - Output: PARTIAL count(*) - Worker 0: actual rows=1 loops=1 - -> Parallel Append (actual rows=10000 loops=2) - Worker 0: actual rows=0 loops=1 + -> Parallel Append (actual rows=1 loops=2) + Worker 0: actual rows=0 loops=1 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._dist_hyper_X_X_chunk (actual rows=17990 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL count(*) -> Parallel Seq Scan on _timescaledb_internal._dist_hyper_X_X_chunk (actual rows=2010 loops=1) -(22 rows) +(23 rows) :analyze select ts_debug_shippable_safe_count(*) from metrics_dist1; @@ -76,15 +77,16 @@ QUERY PLAN Output: (PARTIAL public.ts_debug_shippable_safe_count(*)) Workers Planned: 1 Workers Launched: 1 - -> Partial Aggregate (actual rows=1 loops=2) - Output: PARTIAL public.ts_debug_shippable_safe_count(*) - Worker 0: actual rows=1 loops=1 - -> Parallel Append (actual rows=10000 loops=2) - Worker 0: actual rows=0 loops=1 + -> Parallel Append (actual rows=1 loops=2) + Worker 0: actual rows=0 loops=1 + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL public.ts_debug_shippable_safe_count(*) -> Parallel Seq Scan on _timescaledb_internal._dist_hyper_X_X_chunk (actual rows=17990 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL public.ts_debug_shippable_safe_count(*) -> Parallel Seq Scan on _timescaledb_internal._dist_hyper_X_X_chunk (actual rows=2010 loops=1) -(22 rows) +(23 rows) :analyze select ts_debug_shippable_unsafe_count(*) from metrics_dist1; @@ -97,12 +99,16 @@ QUERY PLAN Chunks: _dist_hyper_X_X_chunk, _dist_hyper_X_X_chunk Remote SQL: SELECT public.ts_debug_shippable_unsafe_count(*) FROM public.metrics_dist1 WHERE _timescaledb_functions.chunks_in(public.metrics_dist1.*, ARRAY[..]) Remote EXPLAIN: - Aggregate (actual rows=1 loops=1) + Finalize Aggregate (actual rows=1 loops=1) Output: public.ts_debug_shippable_unsafe_count(*) - -> Append (actual rows=20000 loops=1) - -> Seq Scan on _timescaledb_internal._dist_hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on _timescaledb_internal._dist_hyper_X_X_chunk (actual rows=2010 loops=1) + -> Append (actual rows=2 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL public.ts_debug_shippable_unsafe_count(*) + -> Seq Scan on _timescaledb_internal._dist_hyper_X_X_chunk (actual rows=17990 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + Output: PARTIAL public.ts_debug_shippable_unsafe_count(*) + -> Seq Scan on _timescaledb_internal._dist_hyper_X_X_chunk (actual rows=2010 loops=1) -(14 rows) +(18 rows) commit; diff --git a/tsl/test/shared/expected/ordered_append-13.out b/tsl/test/shared/expected/ordered_append-13.out index c5aa866ae13..5b2d8fe7c8a 100644 --- a/tsl/test/shared/expected/ordered_append-13.out +++ b/tsl/test/shared/expected/ordered_append-13.out @@ -358,6 +358,8 @@ QUERY PLAN Heap Fetches: 1 (7 rows) +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; -- min/max queries :PREFIX SELECT max(time) @@ -1333,6 +1335,8 @@ QUERY PLAN Heap Fetches: 0 (25 rows) +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; -- min/max queries :PREFIX SELECT max(time) @@ -2518,63 +2522,77 @@ QUERY PLAN Rows Removed by Filter: 20 (13 rows) +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; -- min/max queries :PREFIX SELECT max(time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(8 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) :PREFIX SELECT min(time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(8 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) -- test first/last (doesn't use ordered append yet) :PREFIX SELECT first(time, time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(8 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) :PREFIX SELECT last(time, time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(8 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) -- test query with time_bucket :PREFIX @@ -2821,14 +2839,17 @@ QUERY PLAN Custom Scan (ChunkAppend) on metrics_compressed (actual rows=5 loops=1) Chunks excluded during runtime: 2 InitPlan 1 (returns $0) - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) Filter: ("time" = $0) -> Seq Scan on compress_hyper_X_X_chunk (never executed) @@ -2843,7 +2864,7 @@ QUERY PLAN -> Seq Scan on compress_hyper_X_X_chunk (actual rows=5 loops=1) Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) Rows Removed by Filter: 25 -(25 rows) +(28 rows) -- test ordered append with limit expression :PREFIX @@ -3685,111 +3706,149 @@ QUERY PLAN Rows Removed by Filter: 6 (46 rows) +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; -- min/max queries :PREFIX SELECT max(time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(20 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) :PREFIX SELECT min(time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(20 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) -- test first/last (doesn't use ordered append yet) :PREFIX SELECT first(time, time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(20 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) :PREFIX SELECT last(time, time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(20 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) -- test query with time_bucket :PREFIX @@ -4141,26 +4200,35 @@ ORDER BY time; QUERY PLAN Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=5 loops=1) InitPlan 1 (returns $0) - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) -> Merge Append (actual rows=0 loops=1) -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=0 loops=1) Filter: ("time" = $0) @@ -4212,7 +4280,7 @@ QUERY PLAN -> Seq Scan on compress_hyper_X_X_chunk (actual rows=1 loops=1) Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) Rows Removed by Filter: 5 -(73 rows) +(82 rows) -- test ordered append with limit expression :PREFIX diff --git a/tsl/test/shared/expected/ordered_append-14.out b/tsl/test/shared/expected/ordered_append-14.out index c5aa866ae13..5b2d8fe7c8a 100644 --- a/tsl/test/shared/expected/ordered_append-14.out +++ b/tsl/test/shared/expected/ordered_append-14.out @@ -358,6 +358,8 @@ QUERY PLAN Heap Fetches: 1 (7 rows) +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; -- min/max queries :PREFIX SELECT max(time) @@ -1333,6 +1335,8 @@ QUERY PLAN Heap Fetches: 0 (25 rows) +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; -- min/max queries :PREFIX SELECT max(time) @@ -2518,63 +2522,77 @@ QUERY PLAN Rows Removed by Filter: 20 (13 rows) +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; -- min/max queries :PREFIX SELECT max(time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(8 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) :PREFIX SELECT min(time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(8 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) -- test first/last (doesn't use ordered append yet) :PREFIX SELECT first(time, time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(8 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) :PREFIX SELECT last(time, time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(8 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) -- test query with time_bucket :PREFIX @@ -2821,14 +2839,17 @@ QUERY PLAN Custom Scan (ChunkAppend) on metrics_compressed (actual rows=5 loops=1) Chunks excluded during runtime: 2 InitPlan 1 (returns $0) - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) Filter: ("time" = $0) -> Seq Scan on compress_hyper_X_X_chunk (never executed) @@ -2843,7 +2864,7 @@ QUERY PLAN -> Seq Scan on compress_hyper_X_X_chunk (actual rows=5 loops=1) Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) Rows Removed by Filter: 25 -(25 rows) +(28 rows) -- test ordered append with limit expression :PREFIX @@ -3685,111 +3706,149 @@ QUERY PLAN Rows Removed by Filter: 6 (46 rows) +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; -- min/max queries :PREFIX SELECT max(time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(20 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) :PREFIX SELECT min(time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(20 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) -- test first/last (doesn't use ordered append yet) :PREFIX SELECT first(time, time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(20 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) :PREFIX SELECT last(time, time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(20 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) -- test query with time_bucket :PREFIX @@ -4141,26 +4200,35 @@ ORDER BY time; QUERY PLAN Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=5 loops=1) InitPlan 1 (returns $0) - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) -> Merge Append (actual rows=0 loops=1) -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=0 loops=1) Filter: ("time" = $0) @@ -4212,7 +4280,7 @@ QUERY PLAN -> Seq Scan on compress_hyper_X_X_chunk (actual rows=1 loops=1) Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) Rows Removed by Filter: 5 -(73 rows) +(82 rows) -- test ordered append with limit expression :PREFIX diff --git a/tsl/test/shared/expected/ordered_append-15.out b/tsl/test/shared/expected/ordered_append-15.out index c90315dc2f5..8b4b303f3e0 100644 --- a/tsl/test/shared/expected/ordered_append-15.out +++ b/tsl/test/shared/expected/ordered_append-15.out @@ -361,6 +361,8 @@ QUERY PLAN Heap Fetches: 1 (7 rows) +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; -- min/max queries :PREFIX SELECT max(time) @@ -1345,6 +1347,8 @@ QUERY PLAN Heap Fetches: 0 (25 rows) +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; -- min/max queries :PREFIX SELECT max(time) @@ -2537,63 +2541,77 @@ QUERY PLAN Rows Removed by Filter: 20 (13 rows) +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; -- min/max queries :PREFIX SELECT max(time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(8 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) :PREFIX SELECT min(time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(8 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) -- test first/last (doesn't use ordered append yet) :PREFIX SELECT first(time, time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(8 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) :PREFIX SELECT last(time, time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) -(8 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=30 loops=1) +(11 rows) -- test query with time_bucket :PREFIX @@ -2840,14 +2858,17 @@ QUERY PLAN Custom Scan (ChunkAppend) on metrics_compressed (actual rows=5 loops=1) Chunks excluded during runtime: 2 InitPlan 1 (returns $0) - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (never executed) Filter: ("time" = $0) -> Seq Scan on compress_hyper_X_X_chunk (never executed) @@ -2862,7 +2883,7 @@ QUERY PLAN -> Seq Scan on compress_hyper_X_X_chunk (actual rows=5 loops=1) Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) Rows Removed by Filter: 25 -(25 rows) +(28 rows) -- test ordered append with limit expression :PREFIX @@ -3705,111 +3726,149 @@ QUERY PLAN Rows Removed by Filter: 6 (46 rows) +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; -- min/max queries :PREFIX SELECT max(time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(20 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) :PREFIX SELECT min(time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(20 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) -- test first/last (doesn't use ordered append yet) :PREFIX SELECT first(time, time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(20 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) :PREFIX SELECT last(time, time) FROM :TEST_TABLE; QUERY PLAN - Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(20 rows) + Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(29 rows) -- test query with time_bucket :PREFIX @@ -4161,26 +4220,35 @@ ORDER BY time; QUERY PLAN Custom Scan (ChunkAppend) on metrics_space_compressed (actual rows=5 loops=1) InitPlan 1 (returns $0) - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk _hyper_X_X_chunk_1 (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) -> Merge Append (actual rows=0 loops=1) -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=0 loops=1) Filter: ("time" = $0) @@ -4232,7 +4300,7 @@ QUERY PLAN -> Seq Scan on compress_hyper_X_X_chunk (actual rows=1 loops=1) Filter: ((_ts_meta_min_1 <= $0) AND (_ts_meta_max_1 >= $0)) Rows Removed by Filter: 5 -(73 rows) +(82 rows) -- test ordered append with limit expression :PREFIX diff --git a/tsl/test/shared/expected/ordered_append_join-13.out b/tsl/test/shared/expected/ordered_append_join-13.out index 5ecd1344355..dbe71222e2d 100644 --- a/tsl/test/shared/expected/ordered_append_join-13.out +++ b/tsl/test/shared/expected/ordered_append_join-13.out @@ -245,6 +245,8 @@ QUERY PLAN -- test JOIN -- no exclusion on joined table because quals are not propagated yet +-- With PG 14 on i368, this query uses a nested loop join. Disable the nested loop join to get the same query plan in all tests +SET enable_nestloop TO off; :PREFIX SELECT o1.time, o2.time @@ -282,6 +284,7 @@ QUERY PLAN Heap Fetches: 5038 (25 rows) +RESET enable_nestloop; -- test JOIN -- last chunk of o2 should not be executed :PREFIX @@ -321,6 +324,8 @@ QUERY PLAN -- test join against max query -- not ChunkAppend so no chunk exclusion SET enable_hashjoin = FALSE; +SET enable_nestloop = FALSE; +SET enable_hashagg = FALSE; :PREFIX SELECT o1.time, o2.* @@ -331,10 +336,22 @@ FROM :TEST_TABLE o1 WHERE o1.device_id = 1 ORDER BY time; QUERY PLAN - Sort (actual rows=1 loops=1) - Sort Key: o1_1."time" - Sort Method: quicksort - -> Nested Loop (actual rows=1 loops=1) + Merge Join (actual rows=1 loops=1) + Merge Cond: (o1."time" = ($0)) + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=13674 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_1 (actual rows=3598 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 3598 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_2 (actual rows=5038 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 5038 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_3 (actual rows=5038 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 5038 + -> Sort (actual rows=1 loops=1) + Sort Key: ($0) + Sort Method: quicksort -> Result (actual rows=1 loops=1) InitPlan 1 (returns $0) -> Limit (actual rows=1 loops=1) @@ -349,19 +366,11 @@ QUERY PLAN -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) Index Cond: ("time" IS NOT NULL) Heap Fetches: 0 - -> Append (actual rows=1 loops=1) - -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_1 (actual rows=0 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 0 - -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_2 (actual rows=0 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 0 - -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_3 (actual rows=1 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 1 -(28 rows) +(30 rows) RESET enable_hashjoin; +RESET enable_nestloop; +RESET enable_hashagg; SET enable_seqscan TO false; -- test JOIN on time column -- should use 2 ChunkAppend @@ -1196,6 +1205,8 @@ QUERY PLAN -- test JOIN -- no exclusion on joined table because quals are not propagated yet +-- With PG 14 on i368, this query uses a nested loop join. Disable the nested loop join to get the same query plan in all tests +SET enable_nestloop TO off; :PREFIX SELECT o1.time, o2.time @@ -1233,6 +1244,7 @@ QUERY PLAN Heap Fetches: 5038 (25 rows) +RESET enable_nestloop; -- test JOIN -- last chunk of o2 should not be executed :PREFIX @@ -1306,6 +1318,8 @@ QUERY PLAN -- test join against max query -- not ChunkAppend so no chunk exclusion SET enable_hashjoin = FALSE; +SET enable_nestloop = FALSE; +SET enable_hashagg = FALSE; :PREFIX SELECT o1.time, o2.* @@ -1316,10 +1330,19 @@ FROM :TEST_TABLE o1 WHERE o1.device_id = 1 ORDER BY time; QUERY PLAN - Sort (actual rows=1 loops=1) - Sort Key: o1_1."time" - Sort Method: quicksort - -> Nested Loop (actual rows=1 loops=1) + Merge Join (actual rows=1 loops=1) + Merge Cond: (o1."time" = ($0)) + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=13674 loops=1) + Order: o1."time" + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk o1_1 (actual rows=3598 loops=1) + Filter: (device_id = 1) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk o1_2 (actual rows=5038 loops=1) + Filter: (device_id = 1) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk o1_3 (actual rows=5038 loops=1) + Filter: (device_id = 1) + -> Sort (actual rows=1 loops=1) + Sort Key: ($0) + Sort Method: quicksort -> Result (actual rows=1 loops=1) InitPlan 1 (returns $0) -> Limit (actual rows=1 loops=1) @@ -1358,19 +1381,11 @@ QUERY PLAN -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) Index Cond: ("time" IS NOT NULL) Heap Fetches: 0 - -> Append (actual rows=1 loops=1) - -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk o1_1 (actual rows=0 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 0 - -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk o1_2 (actual rows=0 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 0 - -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk o1_3 (actual rows=1 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 1 -(52 rows) +(51 rows) RESET enable_hashjoin; +RESET enable_nestloop; +RESET enable_hashagg; SET enable_seqscan TO false; -- test JOIN on time column -- should use 2 ChunkAppend @@ -2077,6 +2092,8 @@ QUERY PLAN -- test JOIN -- no exclusion on joined table because quals are not propagated yet +-- With PG 14 on i368, this query uses a nested loop join. Disable the nested loop join to get the same query plan in all tests +SET enable_nestloop TO off; :PREFIX SELECT o1.time, o2.time @@ -2126,6 +2143,7 @@ QUERY PLAN Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) (37 rows) +RESET enable_nestloop; -- test JOIN -- last chunk of o2 should not be executed :PREFIX @@ -2174,6 +2192,8 @@ QUERY PLAN -- test join against max query -- not ChunkAppend so no chunk exclusion SET enable_hashjoin = FALSE; +SET enable_nestloop = FALSE; +SET enable_hashagg = FALSE; :PREFIX SELECT o1.time, o2.* @@ -2200,17 +2220,22 @@ QUERY PLAN -> Sort (actual rows=1 loops=1) Sort Key: (max(_hyper_X_X_chunk."time")) Sort Method: quicksort - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) -(24 rows) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) +(27 rows) RESET enable_hashjoin; +RESET enable_nestloop; +RESET enable_hashagg; SET enable_seqscan TO false; -- test JOIN on time column -- should use 2 ChunkAppend @@ -3131,6 +3156,8 @@ QUERY PLAN -- test JOIN -- no exclusion on joined table because quals are not propagated yet +-- With PG 14 on i368, this query uses a nested loop join. Disable the nested loop join to get the same query plan in all tests +SET enable_nestloop TO off; :PREFIX SELECT o1.time, o2.time @@ -3180,6 +3207,7 @@ QUERY PLAN Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) (37 rows) +RESET enable_nestloop; -- test JOIN -- last chunk of o2 should not be executed :PREFIX @@ -3260,6 +3288,8 @@ QUERY PLAN -- test join against max query -- not ChunkAppend so no chunk exclusion SET enable_hashjoin = FALSE; +SET enable_nestloop = FALSE; +SET enable_hashagg = FALSE; :PREFIX SELECT o1.time, o2.* @@ -3286,29 +3316,40 @@ QUERY PLAN -> Sort (actual rows=1 loops=1) Sort Key: (max(_hyper_X_X_chunk."time")) Sort Method: quicksort - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(36 rows) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(45 rows) RESET enable_hashjoin; +RESET enable_nestloop; +RESET enable_hashagg; SET enable_seqscan TO false; -- test JOIN on time column -- should use 2 ChunkAppend @@ -3794,6 +3835,8 @@ QUERY PLAN (40 rows) RESET enable_seqscan; +-- Disable plain/sorted aggregation to get a deterministic test output +SET timescaledb.enable_chunkwise_aggregation = OFF; -- get results for all the queries -- run queries on uncompressed hypertable and store result \set PREFIX '' diff --git a/tsl/test/shared/expected/ordered_append_join-14.out b/tsl/test/shared/expected/ordered_append_join-14.out index 5ecd1344355..dbe71222e2d 100644 --- a/tsl/test/shared/expected/ordered_append_join-14.out +++ b/tsl/test/shared/expected/ordered_append_join-14.out @@ -245,6 +245,8 @@ QUERY PLAN -- test JOIN -- no exclusion on joined table because quals are not propagated yet +-- With PG 14 on i368, this query uses a nested loop join. Disable the nested loop join to get the same query plan in all tests +SET enable_nestloop TO off; :PREFIX SELECT o1.time, o2.time @@ -282,6 +284,7 @@ QUERY PLAN Heap Fetches: 5038 (25 rows) +RESET enable_nestloop; -- test JOIN -- last chunk of o2 should not be executed :PREFIX @@ -321,6 +324,8 @@ QUERY PLAN -- test join against max query -- not ChunkAppend so no chunk exclusion SET enable_hashjoin = FALSE; +SET enable_nestloop = FALSE; +SET enable_hashagg = FALSE; :PREFIX SELECT o1.time, o2.* @@ -331,10 +336,22 @@ FROM :TEST_TABLE o1 WHERE o1.device_id = 1 ORDER BY time; QUERY PLAN - Sort (actual rows=1 loops=1) - Sort Key: o1_1."time" - Sort Method: quicksort - -> Nested Loop (actual rows=1 loops=1) + Merge Join (actual rows=1 loops=1) + Merge Cond: (o1."time" = ($0)) + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=13674 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_1 (actual rows=3598 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 3598 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_2 (actual rows=5038 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 5038 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_3 (actual rows=5038 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 5038 + -> Sort (actual rows=1 loops=1) + Sort Key: ($0) + Sort Method: quicksort -> Result (actual rows=1 loops=1) InitPlan 1 (returns $0) -> Limit (actual rows=1 loops=1) @@ -349,19 +366,11 @@ QUERY PLAN -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) Index Cond: ("time" IS NOT NULL) Heap Fetches: 0 - -> Append (actual rows=1 loops=1) - -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_1 (actual rows=0 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 0 - -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_2 (actual rows=0 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 0 - -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_3 (actual rows=1 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 1 -(28 rows) +(30 rows) RESET enable_hashjoin; +RESET enable_nestloop; +RESET enable_hashagg; SET enable_seqscan TO false; -- test JOIN on time column -- should use 2 ChunkAppend @@ -1196,6 +1205,8 @@ QUERY PLAN -- test JOIN -- no exclusion on joined table because quals are not propagated yet +-- With PG 14 on i368, this query uses a nested loop join. Disable the nested loop join to get the same query plan in all tests +SET enable_nestloop TO off; :PREFIX SELECT o1.time, o2.time @@ -1233,6 +1244,7 @@ QUERY PLAN Heap Fetches: 5038 (25 rows) +RESET enable_nestloop; -- test JOIN -- last chunk of o2 should not be executed :PREFIX @@ -1306,6 +1318,8 @@ QUERY PLAN -- test join against max query -- not ChunkAppend so no chunk exclusion SET enable_hashjoin = FALSE; +SET enable_nestloop = FALSE; +SET enable_hashagg = FALSE; :PREFIX SELECT o1.time, o2.* @@ -1316,10 +1330,19 @@ FROM :TEST_TABLE o1 WHERE o1.device_id = 1 ORDER BY time; QUERY PLAN - Sort (actual rows=1 loops=1) - Sort Key: o1_1."time" - Sort Method: quicksort - -> Nested Loop (actual rows=1 loops=1) + Merge Join (actual rows=1 loops=1) + Merge Cond: (o1."time" = ($0)) + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=13674 loops=1) + Order: o1."time" + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk o1_1 (actual rows=3598 loops=1) + Filter: (device_id = 1) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk o1_2 (actual rows=5038 loops=1) + Filter: (device_id = 1) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk o1_3 (actual rows=5038 loops=1) + Filter: (device_id = 1) + -> Sort (actual rows=1 loops=1) + Sort Key: ($0) + Sort Method: quicksort -> Result (actual rows=1 loops=1) InitPlan 1 (returns $0) -> Limit (actual rows=1 loops=1) @@ -1358,19 +1381,11 @@ QUERY PLAN -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) Index Cond: ("time" IS NOT NULL) Heap Fetches: 0 - -> Append (actual rows=1 loops=1) - -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk o1_1 (actual rows=0 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 0 - -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk o1_2 (actual rows=0 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 0 - -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk o1_3 (actual rows=1 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 1 -(52 rows) +(51 rows) RESET enable_hashjoin; +RESET enable_nestloop; +RESET enable_hashagg; SET enable_seqscan TO false; -- test JOIN on time column -- should use 2 ChunkAppend @@ -2077,6 +2092,8 @@ QUERY PLAN -- test JOIN -- no exclusion on joined table because quals are not propagated yet +-- With PG 14 on i368, this query uses a nested loop join. Disable the nested loop join to get the same query plan in all tests +SET enable_nestloop TO off; :PREFIX SELECT o1.time, o2.time @@ -2126,6 +2143,7 @@ QUERY PLAN Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) (37 rows) +RESET enable_nestloop; -- test JOIN -- last chunk of o2 should not be executed :PREFIX @@ -2174,6 +2192,8 @@ QUERY PLAN -- test join against max query -- not ChunkAppend so no chunk exclusion SET enable_hashjoin = FALSE; +SET enable_nestloop = FALSE; +SET enable_hashagg = FALSE; :PREFIX SELECT o1.time, o2.* @@ -2200,17 +2220,22 @@ QUERY PLAN -> Sort (actual rows=1 loops=1) Sort Key: (max(_hyper_X_X_chunk."time")) Sort Method: quicksort - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) -(24 rows) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) +(27 rows) RESET enable_hashjoin; +RESET enable_nestloop; +RESET enable_hashagg; SET enable_seqscan TO false; -- test JOIN on time column -- should use 2 ChunkAppend @@ -3131,6 +3156,8 @@ QUERY PLAN -- test JOIN -- no exclusion on joined table because quals are not propagated yet +-- With PG 14 on i368, this query uses a nested loop join. Disable the nested loop join to get the same query plan in all tests +SET enable_nestloop TO off; :PREFIX SELECT o1.time, o2.time @@ -3180,6 +3207,7 @@ QUERY PLAN Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) (37 rows) +RESET enable_nestloop; -- test JOIN -- last chunk of o2 should not be executed :PREFIX @@ -3260,6 +3288,8 @@ QUERY PLAN -- test join against max query -- not ChunkAppend so no chunk exclusion SET enable_hashjoin = FALSE; +SET enable_nestloop = FALSE; +SET enable_hashagg = FALSE; :PREFIX SELECT o1.time, o2.* @@ -3286,29 +3316,40 @@ QUERY PLAN -> Sort (actual rows=1 loops=1) Sort Key: (max(_hyper_X_X_chunk."time")) Sort Method: quicksort - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(36 rows) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(45 rows) RESET enable_hashjoin; +RESET enable_nestloop; +RESET enable_hashagg; SET enable_seqscan TO false; -- test JOIN on time column -- should use 2 ChunkAppend @@ -3794,6 +3835,8 @@ QUERY PLAN (40 rows) RESET enable_seqscan; +-- Disable plain/sorted aggregation to get a deterministic test output +SET timescaledb.enable_chunkwise_aggregation = OFF; -- get results for all the queries -- run queries on uncompressed hypertable and store result \set PREFIX '' diff --git a/tsl/test/shared/expected/ordered_append_join-15.out b/tsl/test/shared/expected/ordered_append_join-15.out index 2e84799fd92..cd637bd48d2 100644 --- a/tsl/test/shared/expected/ordered_append_join-15.out +++ b/tsl/test/shared/expected/ordered_append_join-15.out @@ -250,6 +250,8 @@ QUERY PLAN -- test JOIN -- no exclusion on joined table because quals are not propagated yet +-- With PG 14 on i368, this query uses a nested loop join. Disable the nested loop join to get the same query plan in all tests +SET enable_nestloop TO off; :PREFIX SELECT o1.time, o2.time @@ -287,6 +289,7 @@ QUERY PLAN Heap Fetches: 5038 (25 rows) +RESET enable_nestloop; -- test JOIN -- last chunk of o2 should not be executed :PREFIX @@ -327,6 +330,8 @@ QUERY PLAN -- test join against max query -- not ChunkAppend so no chunk exclusion SET enable_hashjoin = FALSE; +SET enable_nestloop = FALSE; +SET enable_hashagg = FALSE; :PREFIX SELECT o1.time, o2.* @@ -337,10 +342,22 @@ FROM :TEST_TABLE o1 WHERE o1.device_id = 1 ORDER BY time; QUERY PLAN - Sort (actual rows=1 loops=1) - Sort Key: o1_1."time" - Sort Method: quicksort - -> Nested Loop (actual rows=1 loops=1) + Merge Join (actual rows=1 loops=1) + Merge Cond: (o1."time" = ($0)) + -> Custom Scan (ChunkAppend) on metrics o1 (actual rows=13674 loops=1) + Order: o1."time" + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_1 (actual rows=3598 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 3598 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_2 (actual rows=5038 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 5038 + -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_3 (actual rows=5038 loops=1) + Index Cond: (device_id = 1) + Heap Fetches: 5038 + -> Sort (actual rows=1 loops=1) + Sort Key: ($0) + Sort Method: quicksort -> Result (actual rows=1 loops=1) InitPlan 1 (returns $0) -> Limit (actual rows=1 loops=1) @@ -355,19 +372,11 @@ QUERY PLAN -> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed) Index Cond: ("time" IS NOT NULL) Heap Fetches: 0 - -> Append (actual rows=1 loops=1) - -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_1 (actual rows=0 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 0 - -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_2 (actual rows=0 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 0 - -> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk o1_3 (actual rows=1 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 1 -(28 rows) +(30 rows) RESET enable_hashjoin; +RESET enable_nestloop; +RESET enable_hashagg; SET enable_seqscan TO false; -- test JOIN on time column -- should use 2 ChunkAppend @@ -1207,6 +1216,8 @@ QUERY PLAN -- test JOIN -- no exclusion on joined table because quals are not propagated yet +-- With PG 14 on i368, this query uses a nested loop join. Disable the nested loop join to get the same query plan in all tests +SET enable_nestloop TO off; :PREFIX SELECT o1.time, o2.time @@ -1244,6 +1255,7 @@ QUERY PLAN Heap Fetches: 5038 (25 rows) +RESET enable_nestloop; -- test JOIN -- last chunk of o2 should not be executed :PREFIX @@ -1318,6 +1330,8 @@ QUERY PLAN -- test join against max query -- not ChunkAppend so no chunk exclusion SET enable_hashjoin = FALSE; +SET enable_nestloop = FALSE; +SET enable_hashagg = FALSE; :PREFIX SELECT o1.time, o2.* @@ -1328,10 +1342,19 @@ FROM :TEST_TABLE o1 WHERE o1.device_id = 1 ORDER BY time; QUERY PLAN - Sort (actual rows=1 loops=1) - Sort Key: o1_1."time" - Sort Method: quicksort - -> Nested Loop (actual rows=1 loops=1) + Merge Join (actual rows=1 loops=1) + Merge Cond: (o1."time" = ($0)) + -> Custom Scan (ChunkAppend) on metrics_space o1 (actual rows=13674 loops=1) + Order: o1."time" + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk o1_1 (actual rows=3598 loops=1) + Filter: (device_id = 1) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk o1_2 (actual rows=5038 loops=1) + Filter: (device_id = 1) + -> Index Scan using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk o1_3 (actual rows=5038 loops=1) + Filter: (device_id = 1) + -> Sort (actual rows=1 loops=1) + Sort Key: ($0) + Sort Method: quicksort -> Result (actual rows=1 loops=1) InitPlan 1 (returns $0) -> Limit (actual rows=1 loops=1) @@ -1370,19 +1393,11 @@ QUERY PLAN -> Index Only Scan Backward using _hyper_X_X_chunk_metrics_space_time_idx on _hyper_X_X_chunk (never executed) Index Cond: ("time" IS NOT NULL) Heap Fetches: 0 - -> Append (actual rows=1 loops=1) - -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk o1_1 (actual rows=0 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 0 - -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk o1_2 (actual rows=0 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 0 - -> Index Only Scan using _hyper_X_X_chunk_metrics_space_device_id_time_idx on _hyper_X_X_chunk o1_3 (actual rows=1 loops=1) - Index Cond: ((device_id = 1) AND ("time" = ($0))) - Heap Fetches: 1 -(52 rows) +(51 rows) RESET enable_hashjoin; +RESET enable_nestloop; +RESET enable_hashagg; SET enable_seqscan TO false; -- test JOIN on time column -- should use 2 ChunkAppend @@ -2093,6 +2108,8 @@ QUERY PLAN -- test JOIN -- no exclusion on joined table because quals are not propagated yet +-- With PG 14 on i368, this query uses a nested loop join. Disable the nested loop join to get the same query plan in all tests +SET enable_nestloop TO off; :PREFIX SELECT o1.time, o2.time @@ -2142,6 +2159,7 @@ QUERY PLAN Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) (37 rows) +RESET enable_nestloop; -- test JOIN -- last chunk of o2 should not be executed :PREFIX @@ -2190,6 +2208,8 @@ QUERY PLAN -- test join against max query -- not ChunkAppend so no chunk exclusion SET enable_hashjoin = FALSE; +SET enable_nestloop = FALSE; +SET enable_hashagg = FALSE; :PREFIX SELECT o1.time, o2.* @@ -2216,17 +2236,22 @@ QUERY PLAN -> Sort (actual rows=1 loops=1) Sort Key: (max(_hyper_X_X_chunk."time")) Sort Method: quicksort - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=20 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) -(24 rows) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=17990 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=20 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=25190 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=30 loops=1) +(27 rows) RESET enable_hashjoin; +RESET enable_nestloop; +RESET enable_hashagg; SET enable_seqscan TO false; -- test JOIN on time column -- should use 2 ChunkAppend @@ -3151,6 +3176,8 @@ QUERY PLAN -- test JOIN -- no exclusion on joined table because quals are not propagated yet +-- With PG 14 on i368, this query uses a nested loop join. Disable the nested loop join to get the same query plan in all tests +SET enable_nestloop TO off; :PREFIX SELECT o1.time, o2.time @@ -3200,6 +3227,7 @@ QUERY PLAN Filter: (_ts_meta_min_1 < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) (37 rows) +RESET enable_nestloop; -- test JOIN -- last chunk of o2 should not be executed :PREFIX @@ -3280,6 +3308,8 @@ QUERY PLAN -- test join against max query -- not ChunkAppend so no chunk exclusion SET enable_hashjoin = FALSE; +SET enable_nestloop = FALSE; +SET enable_hashagg = FALSE; :PREFIX SELECT o1.time, o2.* @@ -3306,29 +3336,40 @@ QUERY PLAN -> Sort (actual rows=1 loops=1) Sort Key: (max(_hyper_X_X_chunk."time")) Sort Method: quicksort - -> Aggregate (actual rows=1 loops=1) - -> Append (actual rows=68370 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) - -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) - -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) -(36 rows) + -> Finalize Aggregate (actual rows=1 loops=1) + -> Append (actual rows=9 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=10794 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=12 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=3598 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=4 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk compress_hyper_X_X_chunk_1 (actual rows=6 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=15114 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=18 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Custom Scan (DecompressChunk) on _hyper_X_X_chunk (actual rows=5038 loops=1) + -> Seq Scan on compress_hyper_X_X_chunk (actual rows=6 loops=1) +(45 rows) RESET enable_hashjoin; +RESET enable_nestloop; +RESET enable_hashagg; SET enable_seqscan TO false; -- test JOIN on time column -- should use 2 ChunkAppend @@ -3814,6 +3855,8 @@ QUERY PLAN (40 rows) RESET enable_seqscan; +-- Disable plain/sorted aggregation to get a deterministic test output +SET timescaledb.enable_chunkwise_aggregation = OFF; -- get results for all the queries -- run queries on uncompressed hypertable and store result \set PREFIX '' diff --git a/tsl/test/shared/sql/include/ordered_append.sql b/tsl/test/shared/sql/include/ordered_append.sql index f1c8954c5e1..652329b64d1 100644 --- a/tsl/test/shared/sql/include/ordered_append.sql +++ b/tsl/test/shared/sql/include/ordered_append.sql @@ -152,6 +152,9 @@ WHERE time < '2000-01-08'::text::timestamptz ORDER BY time ASC LIMIT 1; +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; + -- min/max queries :PREFIX SELECT max(time) @@ -170,6 +173,7 @@ FROM :TEST_TABLE; SELECT last(time, time) FROM :TEST_TABLE; + -- test query with time_bucket :PREFIX SELECT time_bucket('1d', time) diff --git a/tsl/test/shared/sql/include/ordered_append_join.sql b/tsl/test/shared/sql/include/ordered_append_join.sql index d698cb06364..e8626c9cd20 100644 --- a/tsl/test/shared/sql/include/ordered_append_join.sql +++ b/tsl/test/shared/sql/include/ordered_append_join.sql @@ -115,6 +115,10 @@ FROM generate_series('2000-01-01'::timestamptz, '2000-01-03', '1d') AS g (time) -- test JOIN -- no exclusion on joined table because quals are not propagated yet + +-- With PG 14 on i368, this query uses a nested loop join. Disable the nested loop join to get the same query plan in all tests +SET enable_nestloop TO off; + :PREFIX SELECT o1.time, o2.time @@ -125,6 +129,8 @@ WHERE o1.time < '2000-02-01' AND o2.device_id = 2 ORDER BY o1.time; +RESET enable_nestloop; + -- test JOIN -- last chunk of o2 should not be executed :PREFIX @@ -142,6 +148,8 @@ LIMIT 10; -- test join against max query -- not ChunkAppend so no chunk exclusion SET enable_hashjoin = FALSE; +SET enable_nestloop = FALSE; +SET enable_hashagg = FALSE; :PREFIX SELECT o1.time, @@ -154,6 +162,8 @@ WHERE o1.device_id = 1 ORDER BY time; RESET enable_hashjoin; +RESET enable_nestloop; +RESET enable_hashagg; SET enable_seqscan TO false; diff --git a/tsl/test/shared/sql/ordered_append_join.sql.in b/tsl/test/shared/sql/ordered_append_join.sql.in index 9777723ddef..277f49a96ef 100644 --- a/tsl/test/shared/sql/ordered_append_join.sql.in +++ b/tsl/test/shared/sql/ordered_append_join.sql.in @@ -28,6 +28,8 @@ set max_parallel_workers_per_gather to 0; \set TEST_TABLE 'metrics_space_compressed' \ir :TEST_QUERY_NAME +-- Disable plain/sorted aggregation to get a deterministic test output +SET timescaledb.enable_chunkwise_aggregation = OFF; -- get results for all the queries -- run queries on uncompressed hypertable and store result diff --git a/tsl/test/sql/CMakeLists.txt b/tsl/test/sql/CMakeLists.txt index 9a793a3b29e..dddf593c48e 100644 --- a/tsl/test/sql/CMakeLists.txt +++ b/tsl/test/sql/CMakeLists.txt @@ -3,6 +3,7 @@ include(GenerateTestSchedule) # These are the files for the 'postgresql' configuration. This is the default, # so unless you have a good reason, add new test files here. set(TEST_FILES + agg_partials_pushdown.sql bgw_custom.sql bgw_security.sql bgw_policy.sql diff --git a/tsl/test/sql/agg_partials_pushdown.sql b/tsl/test/sql/agg_partials_pushdown.sql new file mode 100644 index 00000000000..0720071f1c7 --- /dev/null +++ b/tsl/test/sql/agg_partials_pushdown.sql @@ -0,0 +1,109 @@ +-- This file and its contents are licensed under the Timescale License. +-- Please see the included NOTICE for copyright information and +-- LICENSE-TIMESCALE for a copy of the license. + +\set PREFIX 'EXPLAIN (analyze, verbose, costs off, timing off, summary off)' + +CREATE TABLE testtable(filter_1 int, filler_2 int, filler_3 int, time timestamptz NOT NULL, device_id int, v0 int, v1 int, v2 float, v3 float); +SELECT create_hypertable('testtable', 'time'); +ALTER TABLE testtable SET (timescaledb.compress, timescaledb.compress_orderby='time DESC', timescaledb.compress_segmentby='device_id'); + +INSERT INTO testtable(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-01 0:00:00+0'::timestamptz,'2000-01-10 23:55:00+0','1day') gtime(time), generate_series(1,5,1) gdevice(device_id); + +SELECT compress_chunk(c) FROM show_chunks('testtable') c; + +-- Pushdown aggregation to the chunk level +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0' AND time <= '2000-02-01 00:00:00+0'; + +:PREFIX +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0' AND time <= '2000-02-01 00:00:00+0'; + +-- Create partially compressed chunk +INSERT INTO testtable(time,device_id,v0,v1,v2,v3) +SELECT time, device_id, device_id+1, device_id + 2, device_id + 0.5, NULL +FROM generate_series('2000-01-01 0:00:00+0'::timestamptz,'2000-01-10 23:55:00+0','1day') gtime(time), generate_series(1,5,1) gdevice(device_id); + +-- Pushdown aggregation to the chunk level +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0' AND time <= '2000-02-01 00:00:00+0'; + +:PREFIX +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0' AND time <= '2000-02-01 00:00:00+0'; + + +-- Same query using chunk append +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0'::text::timestamptz AND time <= '2000-02-01 00:00:00+0'; + +:PREFIX +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0'::text::timestamptz AND time <= '2000-02-01 00:00:00+0'; + +-- Force plain / sorted aggregation +SET enable_hashagg = OFF; + +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0'::text::timestamptz AND time <= '2000-02-01 00:00:00+0'; + +:PREFIX +SELECT count(*), sum(v0), sum(v1), sum(v2), sum(v3) FROM testtable WHERE time >= '2000-01-01 00:00:00+0'::text::timestamptz AND time <= '2000-02-01 00:00:00+0'; + +RESET enable_hashagg; + +-- Check Append Node under ChunkAppend +RESET enable_hashagg; +RESET timescaledb.enable_chunkwise_aggregation; + +CREATE TABLE testtable2 ( + timecustom BIGINT NOT NULL, + device_id TEXT NOT NULL, + series_0 DOUBLE PRECISION NULL, + series_1 DOUBLE PRECISION NULL, + series_2 DOUBLE PRECISION NULL, + series_bool BOOLEAN NULL +); + +CREATE INDEX ON testtable2 (timeCustom DESC NULLS LAST, device_id); + +SELECT * FROM create_hypertable('testtable2', 'timecustom', 'device_id', number_partitions => 2, chunk_time_interval=>_timescaledb_functions.interval_to_usec('1 month')); + +INSERT INTO testtable2 VALUES +(1257894000000000000, 'dev1', 1.5, 1, 2, true), +(1257894000000000000, 'dev1', 1.5, 2, NULL, NULL), +(1257894000000001000, 'dev1', 2.5, 3, NULL, NULL), +(1257894001000000000, 'dev1', 3.5, 4, NULL, NULL), +(1257897600000000000, 'dev1', 4.5, 5, NULL, false), +(1257894002000000000, 'dev1', 5.5, 6, NULL, true), +(1257894002000000000, 'dev1', 5.5, 7, NULL, false); + +INSERT INTO testtable2(timeCustom, device_id, series_0, series_1) VALUES +(1257987600000000000, 'dev1', 1.5, 1), +(1257987600000000000, 'dev1', 1.5, 2), +(1257894000000000000, 'dev2', 1.5, 1), +(1257894002000000000, 'dev1', 2.5, 3); + +SELECT timeCustom t, min(series_0) FROM PUBLIC.testtable2 GROUP BY t ORDER BY t DESC NULLS LAST limit 2; + +:PREFIX +SELECT timeCustom t, min(series_0) FROM PUBLIC.testtable2 GROUP BY t ORDER BY t DESC NULLS LAST limit 2; + +-- Force parallel query +SET force_parallel_mode = 'on'; +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; + +SELECT timeCustom t, min(series_0) FROM PUBLIC.testtable2 GROUP BY t ORDER BY t DESC NULLS LAST limit 2; + +:PREFIX +SELECT timeCustom t, min(series_0) FROM PUBLIC.testtable2 GROUP BY t ORDER BY t DESC NULLS LAST limit 2; + +-- Test that we don't process groupingSets +:PREFIX +SELECT timeCustom t, min(series_0) FROM PUBLIC.testtable2 GROUP BY ROLLUP(t); + +-- Check parallel fallback into a non-partial aggregation +SET timescaledb.enable_chunkwise_aggregation = OFF; +SET enable_hashagg = OFF; + +SELECT timeCustom t, min(series_0) FROM PUBLIC.testtable2 GROUP BY t ORDER BY t DESC NULLS LAST limit 2; + +:PREFIX +SELECT timeCustom t, min(series_0) FROM PUBLIC.testtable2 GROUP BY t ORDER BY t DESC NULLS LAST limit 2; diff --git a/tsl/test/sql/compression.sql b/tsl/test/sql/compression.sql index cb049443e61..f33cff6c1f8 100644 --- a/tsl/test/sql/compression.sql +++ b/tsl/test/sql/compression.sql @@ -222,6 +222,10 @@ ALTER TABLE plan_inval SET (timescaledb.compress,timescaledb.compress_orderby='t -- create 2 chunks INSERT INTO plan_inval SELECT * FROM (VALUES ('2000-01-01'::timestamptz,1), ('2000-01-07'::timestamptz,1)) v(time,device_id); SET max_parallel_workers_per_gather to 0; + +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; + PREPARE prep_plan AS SELECT count(*) FROM plan_inval; EXECUTE prep_plan; EXECUTE prep_plan; @@ -235,6 +239,8 @@ SELECT compress_chunk(:'CHUNK_NAME'); EXECUTE prep_plan; EXPLAIN (COSTS OFF) EXECUTE prep_plan; +SET enable_hashagg = ON; + CREATE TABLE test_collation ( time TIMESTAMPTZ NOT NULL, device_id TEXT COLLATE "C" NULL, diff --git a/tsl/test/sql/include/transparent_decompression_query.sql b/tsl/test/sql/include/transparent_decompression_query.sql index 5de5ccd2ce3..e72a3651f1e 100644 --- a/tsl/test/sql/include/transparent_decompression_query.sql +++ b/tsl/test/sql/include/transparent_decompression_query.sql @@ -447,6 +447,8 @@ SELECT count(*) FROM :TEST_TABLE; -- test aggregate with GROUP BY +-- Disable hash aggregation to get a deterministic test output +SET enable_hashagg = OFF; :PREFIX SELECT count(*) FROM :TEST_TABLE @@ -460,6 +462,8 @@ FROM :TEST_TABLE GROUP BY device_id ORDER BY device_id; +SET enable_hashagg = ON; + -- test CTE :PREFIX WITH q AS ( SELECT v1