Skip to content

Commit

Permalink
Fix accessor function cagg_get_bucket_function
Browse files Browse the repository at this point in the history
In timescale#6624 we refactored time_bucket catalog table to be more generic and
introduced the `cagg_get_bucket_function` to inspect the query tree of a
given Continuous Aggregate and return the time_bucket function oid.

The problem with the implementation is we traverse the whole query tree
looking for FuncExpr and in certain cases we can have two different
time_bucket function definition but what matters is the correct and
valid time_bucket function that is part of the groupClause.

Fixed it by inspecting only the Query->groupClause items to look for a
valid time_bucket FuncExpr and return it Oid.
  • Loading branch information
fabriziomello committed May 15, 2024
1 parent 2a4f02b commit 9d5d97b
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 12 deletions.
42 changes: 36 additions & 6 deletions tsl/test/expected/cagg_utils.out
Original file line number Diff line number Diff line change
Expand Up @@ -332,11 +332,10 @@ CREATE MATERIALIZED VIEW integer_ht_cagg
GROUP BY time_bucket(1, a), a;
NOTICE: continuous aggregate "integer_ht_cagg" is already up-to-date
--- Get the bucket Oids
SELECT user_view_name,
cagg_get_bucket_function(mat_hypertable_id)
FROM _timescaledb_catalog.continuous_agg
WHERE user_view_name in('temperature_4h', 'temperature_tz_4h', 'temperature_tz_4h_ts', 'integer_ht_cagg')
ORDER BY user_view_name;
SELECT user_view_name, cagg_get_bucket_function(mat_hypertable_id)
FROM _timescaledb_catalog.continuous_agg
WHERE user_view_name IN ('temperature_4h', 'temperature_tz_4h', 'temperature_tz_4h_ts', 'integer_ht_cagg')
ORDER BY user_view_name;
user_view_name | cagg_get_bucket_function
----------------------+---------------------------------------------------------------------------------------
integer_ht_cagg | time_bucket(integer,integer)
Expand All @@ -345,7 +344,38 @@ SELECT user_view_name,
temperature_tz_4h_ts | time_bucket(interval,timestamp with time zone,text,timestamp with time zone,interval)
(4 rows)

--- Cleanup
-- Valid multiple time_bucket usage on view definition
CREATE MATERIALIZED VIEW temperature_tz_4h_2
WITH (timescaledb.continuous) AS
SELECT (time_bucket('4 hour', time) at time zone 'utc')::date, avg(value)
FROM timestamptz_ht
GROUP BY time_bucket('4 hour', time)
ORDER BY 1
WITH NO DATA;
SELECT user_view_name, cagg_get_bucket_function(mat_hypertable_id)
FROM _timescaledb_catalog.continuous_agg
WHERE user_view_name = 'temperature_tz_4h_2'
ORDER BY user_view_name;
user_view_name | cagg_get_bucket_function
---------------------+------------------------------------------------
temperature_tz_4h_2 | time_bucket(interval,timestamp with time zone)
(1 row)

-- Corrupt the direct view definition
\c :TEST_DBNAME :ROLE_SUPERUSER
SELECT direct_view_schema, direct_view_name
FROM _timescaledb_catalog.continuous_agg
WHERE user_view_name = 'temperature_tz_4h_2' \gset
CREATE OR REPLACE VIEW :direct_view_schema.:direct_view_name AS
SELECT NULL::date AS timezone, NULL::FLOAT8 AS avg;
\set ON_ERROR_STOP 0
-- Should error because there's no time_bucket function on the view definition
SELECT user_view_name, cagg_get_bucket_function(mat_hypertable_id)
FROM _timescaledb_catalog.continuous_agg
WHERE user_view_name = 'temperature_tz_4h_2'
ORDER BY user_view_name;
ERROR: time_bucket function not found in CAgg definition for mat_ht_id: 11
\set ON_ERROR_STOP 1
--- Cleanup
DROP FUNCTION IF EXISTS cagg_get_bucket_function(INTEGER);
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
42 changes: 36 additions & 6 deletions tsl/test/sql/cagg_utils.sql
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,43 @@ CREATE MATERIALIZED VIEW integer_ht_cagg
GROUP BY time_bucket(1, a), a;

--- Get the bucket Oids
SELECT user_view_name,
cagg_get_bucket_function(mat_hypertable_id)
FROM _timescaledb_catalog.continuous_agg
WHERE user_view_name in('temperature_4h', 'temperature_tz_4h', 'temperature_tz_4h_ts', 'integer_ht_cagg')
ORDER BY user_view_name;
SELECT user_view_name, cagg_get_bucket_function(mat_hypertable_id)
FROM _timescaledb_catalog.continuous_agg
WHERE user_view_name IN ('temperature_4h', 'temperature_tz_4h', 'temperature_tz_4h_ts', 'integer_ht_cagg')
ORDER BY user_view_name;

-- Valid multiple time_bucket usage on view definition
CREATE MATERIALIZED VIEW temperature_tz_4h_2
WITH (timescaledb.continuous) AS
SELECT (time_bucket('4 hour', time) at time zone 'utc')::date, avg(value)
FROM timestamptz_ht
GROUP BY time_bucket('4 hour', time)
ORDER BY 1
WITH NO DATA;

--- Cleanup
SELECT user_view_name, cagg_get_bucket_function(mat_hypertable_id)
FROM _timescaledb_catalog.continuous_agg
WHERE user_view_name = 'temperature_tz_4h_2'
ORDER BY user_view_name;

-- Corrupt the direct view definition
\c :TEST_DBNAME :ROLE_SUPERUSER

SELECT direct_view_schema, direct_view_name
FROM _timescaledb_catalog.continuous_agg
WHERE user_view_name = 'temperature_tz_4h_2' \gset

CREATE OR REPLACE VIEW :direct_view_schema.:direct_view_name AS
SELECT NULL::date AS timezone, NULL::FLOAT8 AS avg;

\set ON_ERROR_STOP 0
-- Should error because there's no time_bucket function on the view definition
SELECT user_view_name, cagg_get_bucket_function(mat_hypertable_id)
FROM _timescaledb_catalog.continuous_agg
WHERE user_view_name = 'temperature_tz_4h_2'
ORDER BY user_view_name;
\set ON_ERROR_STOP 1

--- Cleanup
DROP FUNCTION IF EXISTS cagg_get_bucket_function(INTEGER);
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER

0 comments on commit 9d5d97b

Please sign in to comment.