From 1e29cd1b8e869c4f80712344ec6e4df2d6027bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabr=C3=ADzio=20de=20Royes=20Mello?= Date: Mon, 22 Jul 2024 17:28:40 -0300 Subject: [PATCH] Fix segfault on CAggs with multiple JOINs Creating or changing to realtime a Continuous Aggregate with multiple joins was leading to a segfault. Fixed it by dealing properly with the `varno` when creating the `Quals` for the union view in realtime mode. Also get rid of some left over when we relaxed the CAggs join restrictions in #7111. --- tsl/src/continuous_aggs/common.c | 56 +++------- tsl/src/continuous_aggs/common.h | 2 +- tsl/src/continuous_aggs/finalize.c | 160 +++++---------------------- tsl/test/expected/cagg_joins.out | 59 +++++++++- tsl/test/expected/cagg_repair-14.out | 12 +- tsl/test/expected/cagg_repair-15.out | 12 +- tsl/test/expected/cagg_repair-16.out | 12 +- tsl/test/sql/cagg_joins.sql | 10 ++ 8 files changed, 128 insertions(+), 195 deletions(-) diff --git a/tsl/src/continuous_aggs/common.c b/tsl/src/continuous_aggs/common.c index d62dce4d05c..9361f5247b2 100644 --- a/tsl/src/continuous_aggs/common.c +++ b/tsl/src/continuous_aggs/common.c @@ -69,6 +69,7 @@ caggtimebucketinfo_init(CAggTimebucketInfo *src, int32 hypertable_id, Oid hypert src->htid = hypertable_id; src->parent_mat_hypertable_id = parent_mat_hypertable_id; src->htoid = hypertable_oid; + src->htoidparent = InvalidOid; src->htpartcolno = hypertable_partition_colno; src->htpartcoltype = hypertable_partition_coltype; src->htpartcol_interval_len = hypertable_partition_col_interval; @@ -1082,6 +1083,9 @@ cagg_validate_query(const Query *query, const bool finalized, const char *cagg_s } } + if (is_hierarchical) + bucket_info.htoidparent = cagg_parent->relid; + return bucket_info; } @@ -1332,55 +1336,27 @@ build_union_query(CAggTimebucketInfo *tbinfo, int matpartcolno, Query *q1, Query /* * If there is join in CAgg definition then adjust varno * to get time column from the hypertable in the join. - * - * In case of joins it is enough to check if the first node is not RangeTblRef, - * because the jointree has RangeTblRef as leaves and JoinExpr above them. - * So if JoinExpr is present, it is the first node. - * Other cases of join i.e. without explicit JOIN clause is confirmed - * by reading the length of rtable. */ - if (list_length(q2->rtable) == CONTINUOUS_AGG_MAX_JOIN_RELATIONS || - !IsA(linitial(q2->jointree->fromlist), RangeTblRef)) - { - Oid normal_table_id = InvalidOid; - RangeTblEntry *rte = NULL; - RangeTblEntry *rte_other = NULL; + varno = list_length(q2->rtable); - if (list_length(q2->rtable) == CONTINUOUS_AGG_MAX_JOIN_RELATIONS) - { - RangeTblRef *rtref = linitial_node(RangeTblRef, q2->jointree->fromlist); - rte = list_nth(q2->rtable, rtref->rtindex - 1); - RangeTblRef *rtref_other = lsecond_node(RangeTblRef, q2->jointree->fromlist); - rte_other = list_nth(q2->rtable, rtref_other->rtindex - 1); - } - else if (!IsA(linitial(q2->jointree->fromlist), RangeTblRef)) + if (list_length(q2->rtable) > 1 || !IsA(linitial(q2->jointree->fromlist), RangeTblRef)) + { + int nvarno = 1; + foreach (lc2, q2->rtable) { - ListCell *l; - foreach (l, q2->jointree->fromlist) + RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc2); + if (rte->rtekind == RTE_RELATION) { - Node *jtnode = (Node *) lfirst(l); - JoinExpr *join = NULL; - if (IsA(jtnode, JoinExpr)) + /* look for hypertable or parent hypertable in RangeTableEntry list */ + if (rte->relid == tbinfo->htoid || rte->relid == tbinfo->htoidparent) { - join = castNode(JoinExpr, jtnode); - rte = list_nth(q2->rtable, ((RangeTblRef *) join->larg)->rtindex - 1); - rte_other = list_nth(q2->rtable, ((RangeTblRef *) join->rarg)->rtindex - 1); + varno = nvarno; + break; } } + nvarno++; } - if (rte->relkind == RELKIND_VIEW) - normal_table_id = rte_other->relid; - else if (rte_other->relkind == RELKIND_VIEW) - normal_table_id = rte->relid; - else - normal_table_id = ts_is_hypertable(rte->relid) ? rte_other->relid : rte->relid; - if (normal_table_id == rte->relid) - varno = 2; - else - varno = 1; } - else - varno = list_length(q2->rtable); q2_quals = build_union_query_quals(materialize_htid, tbinfo->htpartcoltype, diff --git a/tsl/src/continuous_aggs/common.h b/tsl/src/continuous_aggs/common.h index d758104a1a8..d983446084f 100644 --- a/tsl/src/continuous_aggs/common.h +++ b/tsl/src/continuous_aggs/common.h @@ -36,7 +36,6 @@ #include "ts_catalog/catalog.h" #include "ts_catalog/continuous_agg.h" -#define CONTINUOUS_AGG_MAX_JOIN_RELATIONS 2 #define DEFAULT_MATPARTCOLUMN_NAME "time_partition_col" #define CAGG_INVALIDATION_THRESHOLD_NAME "invalidation threshold watermark" @@ -66,6 +65,7 @@ typedef struct CAggTimebucketInfo int32 htid; /* hypertable id */ int32 parent_mat_hypertable_id; /* parent materialization hypertable id */ Oid htoid; /* hypertable oid */ + Oid htoidparent; /* parent hypertable oid in case of hierarchical */ AttrNumber htpartcolno; /* primary partitioning column of raw hypertable */ /* This should also be the column used by time_bucket */ Oid htpartcoltype; /* The collation type */ diff --git a/tsl/src/continuous_aggs/finalize.c b/tsl/src/continuous_aggs/finalize.c index 16976254e71..2a92b235912 100644 --- a/tsl/src/continuous_aggs/finalize.c +++ b/tsl/src/continuous_aggs/finalize.c @@ -131,102 +131,17 @@ finalizequery_get_select_query(FinalizeQueryInfo *inp, List *matcollist, ObjectAddress *mattbladdress, char *relname) { Query *final_selquery = NULL; - ListCell *lc; - FromExpr *fromexpr; - RangeTblEntry *rte; -#if PG16_GE - RTEPermissionInfo *perminfo; -#endif CAGG_MAKEQUERY(final_selquery, inp->final_userquery); final_selquery->hasAggs = !inp->finalized; - /* - * For initial cagg creation rtable will have only 1 entry, - * for alter table rtable will have multiple entries with our - * RangeTblEntry as last member. - * For cagg with joins, we need to create a new RTE and jointree - * which contains the information of the materialised hypertable - * that is created for this cagg. - */ - if (list_length(inp->final_userquery->jointree->fromlist) >= - CONTINUOUS_AGG_MAX_JOIN_RELATIONS || - !IsA(linitial(inp->final_userquery->jointree->fromlist), RangeTblRef)) - { - rte = makeNode(RangeTblEntry); - rte->alias = makeAlias(relname, NIL); - rte->inFromCl = true; - rte->inh = true; - rte->rellockmode = 1; - rte->eref = copyObject(rte->alias); - rte->relid = mattbladdress->objectId; -#if PG16_GE - perminfo = addRTEPermissionInfo(&final_selquery->rteperminfos, rte); - perminfo->selectedCols = NULL; -#endif - ListCell *l; - foreach (l, inp->final_userquery->jointree->fromlist) - { - /* - * In case of joins, update the rte with all the join related struct. - */ - Node *jtnode = (Node *) lfirst(l); - JoinExpr *join = NULL; - if (IsA(jtnode, JoinExpr)) - { - join = castNode(JoinExpr, jtnode); - RangeTblEntry *jrte = rt_fetch(join->rtindex, inp->final_userquery->rtable); - rte->joinaliasvars = jrte->joinaliasvars; - rte->jointype = jrte->jointype; - rte->joinleftcols = jrte->joinleftcols; - rte->joinrightcols = jrte->joinrightcols; - rte->joinmergedcols = jrte->joinmergedcols; - rte->join_using_alias = jrte->join_using_alias; -#if PG16_LT - rte->selectedCols = jrte->selectedCols; -#else - if (jrte->perminfoindex > 0) - { - RTEPermissionInfo *jperminfo = - getRTEPermissionInfo(inp->final_userquery->rteperminfos, jrte); - perminfo->selectedCols = jperminfo->selectedCols; - } -#endif - } - } - } - else - { - rte = llast_node(RangeTblEntry, inp->final_userquery->rtable); - rte->eref->colnames = NIL; -#if PG16_LT - rte->selectedCols = NULL; -#else - perminfo = getRTEPermissionInfo(inp->final_userquery->rteperminfos, rte); - perminfo->selectedCols = NULL; -#endif - } - if (rte->eref->colnames == NIL) - { - /* - * We only need to do this for the case when there is no Join node in the query. - * In the case of join, rte->eref is already populated by jrte->eref and hence the - * relevant info, so need not to do this. - */ + /* New RangeTblEntry for the materialization hypertable */ + RangeTblEntry *rte = makeNode(RangeTblEntry); + rte->inFromCl = true; + rte->inh = true; + rte->rellockmode = 1; + rte->eref = makeAlias(relname, NIL); - /* Aliases for column names for the materialization table. */ - foreach (lc, matcollist) - { - ColumnDef *cdef = lfirst_node(ColumnDef, lc); - rte->eref->colnames = lappend(rte->eref->colnames, makeString(cdef->colname)); - int attno = list_length(rte->eref->colnames) - FirstLowInvalidHeapAttributeNumber; -#if PG16_LT - rte->selectedCols = bms_add_member(rte->selectedCols, attno); -#else - perminfo->selectedCols = bms_add_member(perminfo->selectedCols, attno); -#endif - } - } rte->relid = mattbladdress->objectId; rte->rtekind = RTE_RELATION; rte->relkind = RELKIND_RELATION; @@ -236,16 +151,33 @@ finalizequery_get_select_query(FinalizeQueryInfo *inp, List *matcollist, rte->insertedCols = NULL; rte->updatedCols = NULL; #else + RTEPermissionInfo *perminfo = addRTEPermissionInfo(&final_selquery->rteperminfos, rte); + perminfo->selectedCols = NULL; perminfo->relid = mattbladdress->objectId; perminfo->requiredPerms |= ACL_SELECT; perminfo->insertedCols = NULL; perminfo->updatedCols = NULL; #endif - /* 2. Fixup targetlist with the correct rel information. */ + /* Aliases for column names for the materialization hypertable. */ + ListCell *lc; + int attno = 0; + foreach (lc, matcollist) + { + ColumnDef *cdef = lfirst_node(ColumnDef, lc); + rte->eref->colnames = lappend(rte->eref->colnames, makeString(cdef->colname)); + attno = list_length(rte->eref->colnames) - FirstLowInvalidHeapAttributeNumber; +#if PG16_LT + rte->selectedCols = bms_add_member(rte->selectedCols, attno); +#else + perminfo->selectedCols = bms_add_member(perminfo->selectedCols, attno); +#endif + } + + /* Fixup targetlist with the correct rel information. */ foreach (lc, inp->final_seltlist) { - TargetEntry *tle = (TargetEntry *) lfirst(lc); + TargetEntry *tle = lfirst_node(TargetEntry, lc); /* * In case when this is a cagg with joins, the Var from the normal table * already has resorigtbl populated and we need to use that to resolve @@ -255,50 +187,18 @@ finalizequery_get_select_query(FinalizeQueryInfo *inp, List *matcollist, if (IsA(tle->expr, Var) && !OidIsValid(tle->resorigtbl)) { tle->resorigtbl = rte->relid; - tle->resorigcol = ((Var *) tle->expr)->varattno; + tle->resorigcol = castNode(Var, tle->expr)->varattno; } } - if (list_length(inp->final_userquery->jointree->fromlist) >= - CONTINUOUS_AGG_MAX_JOIN_RELATIONS || - !IsA(linitial(inp->final_userquery->jointree->fromlist), RangeTblRef)) - { - RangeTblRef *rtr; - final_selquery->rtable = list_make1(rte); -#if PG16_GE - /* perminfo has been set already in the previous if/else */ - Assert(list_length(final_selquery->rteperminfos) == 1); -#endif - rtr = makeNode(RangeTblRef); - rtr->rtindex = 1; - fromexpr = makeFromExpr(list_make1(rtr), NULL); - } - else - { - final_selquery->rtable = inp->final_userquery->rtable; -#if PG16_GE - final_selquery->rteperminfos = inp->final_userquery->rteperminfos; -#endif - fromexpr = inp->final_userquery->jointree; - fromexpr->quals = NULL; - } - - /* - * Fixup from list. No quals on original table should be - * present here - they should be on the query that populates - * the mattable (partial_selquery). For the Cagg with join, - * we can not copy the fromlist from inp->final_userquery as - * it has two tables in this case. - */ - Assert(list_length(inp->final_userquery->jointree->fromlist) <= - CONTINUOUS_AGG_MAX_JOIN_RELATIONS); + RangeTblRef *rtr = makeNode(RangeTblRef); + rtr->rtindex = 1; - final_selquery->jointree = fromexpr; + final_selquery->rtable = list_make1(rte); + final_selquery->jointree = makeFromExpr(list_make1(rtr), NULL); final_selquery->targetList = inp->final_seltlist; final_selquery->sortClause = inp->final_userquery->sortClause; - /* Already finalized query no need to copy group by or having clause. */ - return final_selquery; } diff --git a/tsl/test/expected/cagg_joins.out b/tsl/test/expected/cagg_joins.out index 2fcc19d0f93..5280dbe4e03 100644 --- a/tsl/test/expected/cagg_joins.out +++ b/tsl/test/expected/cagg_joins.out @@ -69,7 +69,7 @@ View definition: ( SELECT _materialized_hypertable_3.bucket, _materialized_hypertable_3.avg, _materialized_hypertable_3.name - FROM _timescaledb_internal._materialized_hypertable_3 _materialized_hypertable_3 + FROM _timescaledb_internal._materialized_hypertable_3 WHERE _materialized_hypertable_3.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(3)), '-infinity'::timestamp with time zone) ORDER BY _materialized_hypertable_3.bucket) UNION ALL @@ -147,7 +147,7 @@ View definition: ( SELECT _materialized_hypertable_4.bucket, _materialized_hypertable_4.avg, _materialized_hypertable_4.name - FROM _timescaledb_internal._materialized_hypertable_4 _materialized_hypertable_4 + FROM _timescaledb_internal._materialized_hypertable_4 WHERE _materialized_hypertable_4.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(4)), '-infinity'::timestamp with time zone) ORDER BY _materialized_hypertable_4.bucket) UNION ALL @@ -226,7 +226,7 @@ View definition: ( SELECT _materialized_hypertable_5.bucket, _materialized_hypertable_5.avg, _materialized_hypertable_5.name - FROM _timescaledb_internal._materialized_hypertable_5 _materialized_hypertable_5 + FROM _timescaledb_internal._materialized_hypertable_5 WHERE _materialized_hypertable_5.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(5)), '-infinity'::timestamp with time zone) ORDER BY _materialized_hypertable_5.bucket) UNION ALL @@ -306,7 +306,7 @@ View definition: ( SELECT _materialized_hypertable_6.bucket, _materialized_hypertable_6.avg, _materialized_hypertable_6.name - FROM _timescaledb_internal._materialized_hypertable_6 _materialized_hypertable_6 + FROM _timescaledb_internal._materialized_hypertable_6 WHERE _materialized_hypertable_6.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(6)), '-infinity'::timestamp with time zone) ORDER BY _materialized_hypertable_6.bucket) UNION ALL @@ -387,7 +387,7 @@ View definition: ( SELECT _materialized_hypertable_7.bucket, _materialized_hypertable_7.avg, _materialized_hypertable_7.name - FROM _timescaledb_internal._materialized_hypertable_7 _materialized_hypertable_7 + FROM _timescaledb_internal._materialized_hypertable_7 WHERE _materialized_hypertable_7.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(7)), '-infinity'::timestamp with time zone) ORDER BY _materialized_hypertable_7.bucket) UNION ALL @@ -470,7 +470,7 @@ View definition: ( SELECT _materialized_hypertable_8.bucket, _materialized_hypertable_8.avg, _materialized_hypertable_8.name - FROM _timescaledb_internal._materialized_hypertable_8 _materialized_hypertable_8 + FROM _timescaledb_internal._materialized_hypertable_8 WHERE _materialized_hypertable_8.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(8)), '-infinity'::timestamp with time zone) ORDER BY _materialized_hypertable_8.bucket) UNION ALL @@ -1165,6 +1165,53 @@ JOIN location ON location.name = devices.location GROUP BY bucket, devices.name, location.name; NOTICE: refreshing continuous aggregate "conditions_by_day" HINT: Use WITH NO DATA if you do not want to refresh the continuous aggregate on creation. +SELECT * FROM conditions_by_day ORDER BY bucket, device, location; + bucket | avg | device | location +------------------------------+---------------------+----------+----------- + Sun Jun 13 17:00:00 2021 PDT | 26.0000000000000000 | thermo_1 | Moscow + Mon Jun 14 17:00:00 2021 PDT | 22.0000000000000000 | thermo_2 | Berlin + Tue Jun 15 17:00:00 2021 PDT | 24.0000000000000000 | thermo_3 | London + Wed Jun 16 17:00:00 2021 PDT | 24.0000000000000000 | thermo_4 | Stockholm + Thu Jun 17 17:00:00 2021 PDT | 27.0000000000000000 | thermo_4 | Stockholm + Fri Jun 18 17:00:00 2021 PDT | 28.0000000000000000 | thermo_4 | Stockholm + Sat Jun 19 17:00:00 2021 PDT | 30.0000000000000000 | thermo_1 | Moscow + Sun Jun 20 17:00:00 2021 PDT | 31.0000000000000000 | thermo_1 | Moscow + Mon Jun 21 17:00:00 2021 PDT | 34.0000000000000000 | thermo_1 | Moscow + Tue Jun 22 17:00:00 2021 PDT | 34.0000000000000000 | thermo_2 | Berlin + Wed Jun 23 17:00:00 2021 PDT | 34.0000000000000000 | thermo_2 | Berlin + Thu Jun 24 17:00:00 2021 PDT | 32.0000000000000000 | thermo_3 | London + Fri Jun 25 17:00:00 2021 PDT | 32.0000000000000000 | thermo_3 | London + Sat Jun 26 17:00:00 2021 PDT | 31.0000000000000000 | thermo_3 | London + Tue Jun 29 17:00:00 2021 PDT | 28.0000000000000000 | thermo_3 | London + Wed Jun 30 17:00:00 2021 PDT | 28.0000000000000000 | thermo_3 | London +(16 rows) + +ALTER MATERIALIZED VIEW conditions_by_day SET (timescaledb.materialized_only = FALSE); +-- Insert one more row on conditions and check the result (should have one more row) +INSERT INTO conditions (day, city, temperature, device_id) VALUES + ('2024-07-01', 'Moscow', 28, 3); +SELECT * FROM conditions_by_day ORDER BY bucket, device, location; + bucket | avg | device | location +------------------------------+---------------------+----------+----------- + Sun Jun 13 17:00:00 2021 PDT | 26.0000000000000000 | thermo_1 | Moscow + Mon Jun 14 17:00:00 2021 PDT | 22.0000000000000000 | thermo_2 | Berlin + Tue Jun 15 17:00:00 2021 PDT | 24.0000000000000000 | thermo_3 | London + Wed Jun 16 17:00:00 2021 PDT | 24.0000000000000000 | thermo_4 | Stockholm + Thu Jun 17 17:00:00 2021 PDT | 27.0000000000000000 | thermo_4 | Stockholm + Fri Jun 18 17:00:00 2021 PDT | 28.0000000000000000 | thermo_4 | Stockholm + Sat Jun 19 17:00:00 2021 PDT | 30.0000000000000000 | thermo_1 | Moscow + Sun Jun 20 17:00:00 2021 PDT | 31.0000000000000000 | thermo_1 | Moscow + Mon Jun 21 17:00:00 2021 PDT | 34.0000000000000000 | thermo_1 | Moscow + Tue Jun 22 17:00:00 2021 PDT | 34.0000000000000000 | thermo_2 | Berlin + Wed Jun 23 17:00:00 2021 PDT | 34.0000000000000000 | thermo_2 | Berlin + Thu Jun 24 17:00:00 2021 PDT | 32.0000000000000000 | thermo_3 | London + Fri Jun 25 17:00:00 2021 PDT | 32.0000000000000000 | thermo_3 | London + Sat Jun 26 17:00:00 2021 PDT | 31.0000000000000000 | thermo_3 | London + Tue Jun 29 17:00:00 2021 PDT | 28.0000000000000000 | thermo_3 | London + Wed Jun 30 17:00:00 2021 PDT | 28.0000000000000000 | thermo_3 | London + Sun Jun 30 17:00:00 2024 PDT | 28.0000000000000000 | thermo_3 | London +(17 rows) + -- JOIN with a foreign table \c :TEST_DBNAME :ROLE_SUPERUSER SELECT current_setting('port') AS "PGPORT", current_database() AS "PGDATABASE" \gset diff --git a/tsl/test/expected/cagg_repair-14.out b/tsl/test/expected/cagg_repair-14.out index ad731110b5a..f265c35e1de 100644 --- a/tsl/test/expected/cagg_repair-14.out +++ b/tsl/test/expected/cagg_repair-14.out @@ -76,7 +76,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2; + FROM _timescaledb_internal._materialized_hypertable_2; CALL refresh_continuous_aggregate('conditions_summary', NULL, '2021-06-22 00:00:00-00'); SELECT * FROM conditions_summary ORDER BY bucket, device_name; @@ -106,7 +106,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2; + FROM _timescaledb_internal._materialized_hypertable_2; SELECT * FROM conditions_summary ORDER BY bucket, device_name; bucket | device_name | min | max | sum @@ -134,7 +134,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2; + FROM _timescaledb_internal._materialized_hypertable_2; SELECT * FROM conditions_summary ORDER BY bucket, device_name; bucket | device_name | min | max | sum @@ -162,7 +162,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2 + FROM _timescaledb_internal._materialized_hypertable_2 WHERE _materialized_hypertable_2.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(2)), '-infinity'::timestamp with time zone) UNION ALL SELECT time_bucket('@ 7 days'::interval, conditions."time") AS bucket, @@ -205,7 +205,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2 + FROM _timescaledb_internal._materialized_hypertable_2 WHERE _materialized_hypertable_2.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(2)), '-infinity'::timestamp with time zone) UNION ALL SELECT time_bucket('@ 7 days'::interval, conditions."time") AS bucket, @@ -247,7 +247,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2 + FROM _timescaledb_internal._materialized_hypertable_2 WHERE _materialized_hypertable_2.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(2)), '-infinity'::timestamp with time zone) UNION ALL SELECT time_bucket('@ 7 days'::interval, conditions."time") AS bucket, diff --git a/tsl/test/expected/cagg_repair-15.out b/tsl/test/expected/cagg_repair-15.out index ad731110b5a..f265c35e1de 100644 --- a/tsl/test/expected/cagg_repair-15.out +++ b/tsl/test/expected/cagg_repair-15.out @@ -76,7 +76,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2; + FROM _timescaledb_internal._materialized_hypertable_2; CALL refresh_continuous_aggregate('conditions_summary', NULL, '2021-06-22 00:00:00-00'); SELECT * FROM conditions_summary ORDER BY bucket, device_name; @@ -106,7 +106,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2; + FROM _timescaledb_internal._materialized_hypertable_2; SELECT * FROM conditions_summary ORDER BY bucket, device_name; bucket | device_name | min | max | sum @@ -134,7 +134,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2; + FROM _timescaledb_internal._materialized_hypertable_2; SELECT * FROM conditions_summary ORDER BY bucket, device_name; bucket | device_name | min | max | sum @@ -162,7 +162,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2 + FROM _timescaledb_internal._materialized_hypertable_2 WHERE _materialized_hypertable_2.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(2)), '-infinity'::timestamp with time zone) UNION ALL SELECT time_bucket('@ 7 days'::interval, conditions."time") AS bucket, @@ -205,7 +205,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2 + FROM _timescaledb_internal._materialized_hypertable_2 WHERE _materialized_hypertable_2.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(2)), '-infinity'::timestamp with time zone) UNION ALL SELECT time_bucket('@ 7 days'::interval, conditions."time") AS bucket, @@ -247,7 +247,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2 + FROM _timescaledb_internal._materialized_hypertable_2 WHERE _materialized_hypertable_2.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(2)), '-infinity'::timestamp with time zone) UNION ALL SELECT time_bucket('@ 7 days'::interval, conditions."time") AS bucket, diff --git a/tsl/test/expected/cagg_repair-16.out b/tsl/test/expected/cagg_repair-16.out index ffb4db7beb1..164a0fc8201 100644 --- a/tsl/test/expected/cagg_repair-16.out +++ b/tsl/test/expected/cagg_repair-16.out @@ -76,7 +76,7 @@ View definition: min, max, sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2; + FROM _timescaledb_internal._materialized_hypertable_2; CALL refresh_continuous_aggregate('conditions_summary', NULL, '2021-06-22 00:00:00-00'); SELECT * FROM conditions_summary ORDER BY bucket, device_name; @@ -106,7 +106,7 @@ View definition: min, max, sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2; + FROM _timescaledb_internal._materialized_hypertable_2; SELECT * FROM conditions_summary ORDER BY bucket, device_name; bucket | device_name | min | max | sum @@ -134,7 +134,7 @@ View definition: min, max, sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2; + FROM _timescaledb_internal._materialized_hypertable_2; SELECT * FROM conditions_summary ORDER BY bucket, device_name; bucket | device_name | min | max | sum @@ -162,7 +162,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2 + FROM _timescaledb_internal._materialized_hypertable_2 WHERE _materialized_hypertable_2.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(2)), '-infinity'::timestamp with time zone) UNION ALL SELECT time_bucket('@ 7 days'::interval, conditions."time") AS bucket, @@ -205,7 +205,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2 + FROM _timescaledb_internal._materialized_hypertable_2 WHERE _materialized_hypertable_2.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(2)), '-infinity'::timestamp with time zone) UNION ALL SELECT time_bucket('@ 7 days'::interval, conditions."time") AS bucket, @@ -247,7 +247,7 @@ View definition: _materialized_hypertable_2.min, _materialized_hypertable_2.max, _materialized_hypertable_2.sum - FROM _timescaledb_internal._materialized_hypertable_2 _materialized_hypertable_2 + FROM _timescaledb_internal._materialized_hypertable_2 WHERE _materialized_hypertable_2.bucket < COALESCE(_timescaledb_functions.to_timestamp(_timescaledb_functions.cagg_watermark(2)), '-infinity'::timestamp with time zone) UNION ALL SELECT time_bucket('@ 7 days'::interval, conditions."time") AS bucket, diff --git a/tsl/test/sql/cagg_joins.sql b/tsl/test/sql/cagg_joins.sql index 4d0e2ffc8f4..908014ec31b 100644 --- a/tsl/test/sql/cagg_joins.sql +++ b/tsl/test/sql/cagg_joins.sql @@ -564,6 +564,16 @@ JOIN devices ON conditions.device_id = devices.device_id JOIN location ON location.name = devices.location GROUP BY bucket, devices.name, location.name; +SELECT * FROM conditions_by_day ORDER BY bucket, device, location; + +ALTER MATERIALIZED VIEW conditions_by_day SET (timescaledb.materialized_only = FALSE); + +-- Insert one more row on conditions and check the result (should have one more row) +INSERT INTO conditions (day, city, temperature, device_id) VALUES + ('2024-07-01', 'Moscow', 28, 3); + +SELECT * FROM conditions_by_day ORDER BY bucket, device, location; + -- JOIN with a foreign table \c :TEST_DBNAME :ROLE_SUPERUSER SELECT current_setting('port') AS "PGPORT", current_database() AS "PGDATABASE" \gset