diff --git a/sql/pre_install/tables.sql b/sql/pre_install/tables.sql index 9389d315a9a..aa9b58e04fb 100644 --- a/sql/pre_install/tables.sql +++ b/sql/pre_install/tables.sql @@ -387,29 +387,6 @@ CREATE INDEX continuous_agg_raw_hypertable_id_idx ON _timescaledb_catalog.contin SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.continuous_agg', ''); --- See the comments for ContinuousAggsBucketFunction structure. -CREATE TABLE _timescaledb_catalog.continuous_aggs_bucket_function ( - mat_hypertable_id integer NOT NULL, - -- The bucket function - bucket_func text NOT NULL, - -- `bucket_width` argument of the function, e.g. "1 month" - bucket_width text NOT NULL, - -- optional `origin` argument of the function provided by the user - bucket_origin text, - -- optional `offset` argument of the function provided by the user - bucket_offset text, - -- optional `timezone` argument of the function provided by the user - bucket_timezone text, - -- fixed or variable sized bucket - bucket_fixed_width bool NOT NULL, - -- table constraints - CONSTRAINT continuous_aggs_bucket_function_pkey PRIMARY KEY (mat_hypertable_id), - CONSTRAINT continuous_aggs_bucket_function_mat_hypertable_id_fkey FOREIGN KEY (mat_hypertable_id) REFERENCES _timescaledb_catalog.hypertable (id) ON DELETE CASCADE, - CONSTRAINT continuous_aggs_bucket_function_func_check CHECK (pg_catalog.to_regprocedure(bucket_func) IS DISTINCT FROM 0) -); - -SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.continuous_aggs_bucket_function', ''); - CREATE TABLE _timescaledb_catalog.continuous_aggs_invalidation_threshold ( hypertable_id integer NOT NULL, watermark bigint NOT NULL, diff --git a/sql/updates/latest-dev.sql b/sql/updates/latest-dev.sql index d233b0ae5f8..5533c3c058b 100644 --- a/sql/updates/latest-dev.sql +++ b/sql/updates/latest-dev.sql @@ -114,3 +114,9 @@ CREATE FUNCTION @extschema@.hypertable_columnstore_stats (hypertable REGCLASS) STABLE STRICT AS 'SELECT * FROM @extschema@.hypertable_compression_stats($1)' SET search_path TO pg_catalog, pg_temp; + +-- Remove useless catalog metadata +ALTER EXTENSION timescaledb + DROP TABLE _timescaledb_catalog.continuous_aggs_bucket_function; + +DROP TABLE _timescaledb_catalog.continuous_aggs_bucket_function; diff --git a/sql/updates/reverse-dev.sql b/sql/updates/reverse-dev.sql index 6b75bc1c851..0837e77697b 100644 --- a/sql/updates/reverse-dev.sql +++ b/sql/updates/reverse-dev.sql @@ -57,3 +57,35 @@ ALTER EXTENSION timescaledb DROP VIEW timescaledb_information.chunk_columnstore_ DROP VIEW timescaledb_information.hypertable_columnstore_settings; DROP VIEW timescaledb_information.chunk_columnstore_settings; +-- Restore the removed metadata table +CREATE TABLE _timescaledb_catalog.continuous_aggs_bucket_function ( + mat_hypertable_id integer NOT NULL, + -- The bucket function + bucket_func text NOT NULL, + -- `bucket_width` argument of the function, e.g. "1 month" + bucket_width text NOT NULL, + -- optional `origin` argument of the function provided by the user + bucket_origin text, + -- optional `offset` argument of the function provided by the user + bucket_offset text, + -- optional `timezone` argument of the function provided by the user + bucket_timezone text, + -- fixed or variable sized bucket + bucket_fixed_width bool NOT NULL, + -- table constraints + CONSTRAINT continuous_aggs_bucket_function_pkey PRIMARY KEY (mat_hypertable_id), + CONSTRAINT continuous_aggs_bucket_function_mat_hypertable_id_fkey FOREIGN KEY (mat_hypertable_id) REFERENCES _timescaledb_catalog.hypertable (id) ON DELETE CASCADE, + CONSTRAINT continuous_aggs_bucket_function_func_check CHECK (pg_catalog.to_regprocedure(bucket_func) IS DISTINCT FROM 0) +); + +INSERT INTO _timescaledb_catalog.continuous_aggs_bucket_function + (mat_hypertable_id, bucket_func, bucket_width, bucket_origin, bucket_offset, bucket_timezone, bucket_fixed_width) +SELECT mat_hypertable_id, bf.bucket_func::text, bf.bucket_width, bf.bucket_origin, bf.bucket_offset, bf.bucket_timezone, bf.bucket_fixed_width +FROM _timescaledb_catalog.continuous_agg, LATERAL _timescaledb_functions.cagg_get_bucket_function_info(mat_hypertable_id) AS bf; + +SELECT pg_catalog.pg_extension_config_dump('_timescaledb_catalog.continuous_aggs_bucket_function', ''); + +GRANT SELECT ON _timescaledb_catalog.continuous_aggs_bucket_function TO PUBLIC; + +DROP FUNCTION IF EXISTS _timescaledb_functions.cagg_get_bucket_function_info(INTEGER); + diff --git a/src/cross_module_fn.c b/src/cross_module_fn.c index 5f1b5a0290e..1814ac94bf9 100644 --- a/src/cross_module_fn.c +++ b/src/cross_module_fn.c @@ -284,6 +284,13 @@ continuous_agg_call_invalidation_trigger_default(int32 hypertable_id, Relation c pg_unreachable(); } +static ContinuousAggsBucketFunction * +continuous_agg_get_bucket_function_info_internal_default(Oid view_oid) +{ + error_no_default_fn_community(); + pg_unreachable(); +} + TS_FUNCTION_INFO_V1(ts_tsl_loaded); PGDLLEXPORT Datum @@ -373,6 +380,8 @@ TSDLLEXPORT CrossModuleFunctions ts_cm_functions_default = { .continuous_agg_validate_query = error_no_default_fn_pg_community, .continuous_agg_get_bucket_function = error_no_default_fn_pg_community, .continuous_agg_get_bucket_function_info = error_no_default_fn_pg_community, + .continuous_agg_get_bucket_function_info_internal = + continuous_agg_get_bucket_function_info_internal_default, .continuous_agg_migrate_to_time_bucket = error_no_default_fn_pg_community, .cagg_try_repair = process_cagg_try_repair, diff --git a/src/cross_module_fn.h b/src/cross_module_fn.h index e471a867b25..c8bf2085928 100644 --- a/src/cross_module_fn.h +++ b/src/cross_module_fn.h @@ -117,6 +117,7 @@ typedef struct CrossModuleFunctions PGFunction continuous_agg_get_bucket_function_info; PGFunction continuous_agg_migrate_to_time_bucket; PGFunction cagg_try_repair; + ContinuousAggsBucketFunction *(*continuous_agg_get_bucket_function_info_internal)(Oid view_oid); PGFunction compressed_data_send; PGFunction compressed_data_recv; diff --git a/src/ts_catalog/catalog.c b/src/ts_catalog/catalog.c index 4278ac763c0..4645e3b77ea 100644 --- a/src/ts_catalog/catalog.c +++ b/src/ts_catalog/catalog.c @@ -97,10 +97,6 @@ static const TableInfoDef catalog_table_names[_MAX_CATALOG_TABLES + 1] = { .schema_name = CATALOG_SCHEMA_NAME, .table_name = COMPRESSION_CHUNK_SIZE_TABLE_NAME, }, - [CONTINUOUS_AGGS_BUCKET_FUNCTION] = { - .schema_name = CATALOG_SCHEMA_NAME, - .table_name = CONTINUOUS_AGGS_BUCKET_FUNCTION_TABLE_NAME, - }, [CONTINUOUS_AGGS_WATERMARK] = { .schema_name = CATALOG_SCHEMA_NAME, .table_name = CONTINUOUS_AGGS_WATERMARK_TABLE_NAME, @@ -255,12 +251,6 @@ static const TableIndexDef catalog_table_index_definitions[_MAX_CATALOG_TABLES] .names = (char *[]) { [COMPRESSION_CHUNK_SIZE_PKEY] = "compression_chunk_size_pkey", }, - }, - [CONTINUOUS_AGGS_BUCKET_FUNCTION] = { - .length = _MAX_CONTINUOUS_AGGS_BUCKET_FUNCTION_INDEX, - .names = (char *[]) { - [CONTINUOUS_AGGS_BUCKET_FUNCTION_PKEY_IDX] = "continuous_aggs_bucket_function_pkey", - }, } }; diff --git a/src/ts_catalog/catalog.h b/src/ts_catalog/catalog.h index 36d925acef4..7be84f27dd2 100644 --- a/src/ts_catalog/catalog.h +++ b/src/ts_catalog/catalog.h @@ -50,7 +50,6 @@ typedef enum CatalogTable CONTINUOUS_AGGS_MATERIALIZATION_INVALIDATION_LOG, COMPRESSION_SETTINGS, COMPRESSION_CHUNK_SIZE, - CONTINUOUS_AGGS_BUCKET_FUNCTION, CONTINUOUS_AGGS_WATERMARK, TELEMETRY_EVENT, CHUNK_COLUMN_STATS, @@ -972,38 +971,6 @@ typedef enum Anum_continuous_agg_raw_hypertable_id_idx #define Natts_continuous_agg_raw_hypertable_id_idx \ (_Anum_continuous_agg_raw_hypertable_id_idx_max - 1) -/*** continuous_aggs_bucket_function table definitions ***/ - -#define CONTINUOUS_AGGS_BUCKET_FUNCTION_TABLE_NAME "continuous_aggs_bucket_function" -typedef enum Anum_continuous_aggs_bucket_function -{ - Anum_continuous_aggs_bucket_function_mat_hypertable_id = 1, - Anum_continuous_aggs_bucket_function_function, - Anum_continuous_aggs_bucket_function_bucket_width, - Anum_continuous_aggs_bucket_function_bucket_origin, - Anum_continuous_aggs_bucket_function_bucket_offset, - Anum_continuous_aggs_bucket_function_bucket_timezone, - Anum_continuous_aggs_bucket_function_bucket_fixed_width, - _Anum_continuous_aggs_bucket_function_max, -} Anum_continuous_aggs_bucket_function; - -#define Natts_continuous_aggs_bucket_function (_Anum_continuous_aggs_bucket_function_max - 1) - -enum -{ - CONTINUOUS_AGGS_BUCKET_FUNCTION_PKEY_IDX = 0, - _MAX_CONTINUOUS_AGGS_BUCKET_FUNCTION_INDEX, -}; - -typedef enum Anum_continuous_aggs_bucket_function_pkey -{ - Anum_continuous_aggs_bucket_function_pkey_mat_hypertable_id = 1, - _Anum_continuous_aggs_bucket_function_pkey_max, -} Anum_continuous_aggs_bucket_function_pkey; - -#define Natts_continuous_aggs_bucket_function_pkey \ - (_Anum_continuous_aggs_bucket_function_pkey_max - 1) - /****** CONTINUOUS_AGGS_HYPERTABLE_INVALIDATION_LOG_TABLE definitions*/ #define CONTINUOUS_AGGS_HYPERTABLE_INVALIDATION_LOG_TABLE_NAME \ "continuous_aggs_hypertable_invalidation_log" diff --git a/src/ts_catalog/continuous_agg.c b/src/ts_catalog/continuous_agg.c index a786b4bf44a..f2e1a345df6 100644 --- a/src/ts_catalog/continuous_agg.c +++ b/src/ts_catalog/continuous_agg.c @@ -46,6 +46,8 @@ #define BUCKET_FUNCTION_SERIALIZE_VERSION 1 #define CHECK_NAME_MATCH(name1, name2) (namestrcmp(name1, name2) == 0) +static ObjectAddress get_and_lock_rel_by_name(const Name schema, const Name name, LOCKMODE mode); + static const WithClauseDefinition continuous_aggregate_with_clause_def[] = { [ContinuousEnabled] = { .arg_names = {"continuous", NULL}, @@ -149,21 +151,6 @@ init_scan_by_mat_hypertable_id(ScanIterator *iterator, const int32 mat_hypertabl Int32GetDatum(mat_hypertable_id)); } -static void -init_scan_cagg_bucket_function_by_mat_hypertable_id(ScanIterator *iterator, - const int32 mat_hypertable_id) -{ - iterator->ctx.index = catalog_get_index(ts_catalog_get(), - CONTINUOUS_AGGS_BUCKET_FUNCTION, - CONTINUOUS_AGGS_BUCKET_FUNCTION_PKEY_IDX); - - ts_scan_iterator_scan_key_init(iterator, - Anum_continuous_aggs_bucket_function_pkey_mat_hypertable_id, - BTEqualStrategyNumber, - F_INT4EQ, - Int32GetDatum(mat_hypertable_id)); -} - static void init_scan_by_raw_hypertable_id(ScanIterator *iterator, const int32 raw_hypertable_id) { @@ -252,22 +239,6 @@ invalidation_threshold_delete(int32 raw_hypertable_id) } } -static void -cagg_bucket_function_delete(int32 mat_hypertable_id) -{ - ScanIterator iterator = ts_scan_iterator_create(CONTINUOUS_AGGS_BUCKET_FUNCTION, - RowExclusiveLock, - CurrentMemoryContext); - - init_scan_cagg_bucket_function_by_mat_hypertable_id(&iterator, mat_hypertable_id); - - ts_scanner_foreach(&iterator) - { - TupleInfo *ti = ts_scan_iterator_tuple_info(&iterator); - ts_catalog_delete_tid(ti->scanrel, ts_scanner_get_tuple_tid(ti)); - } -} - static void hypertable_invalidation_log_delete(int32 raw_hypertable_id) { @@ -396,156 +367,6 @@ continuous_agg_formdata_fill(FormData_continuous_agg *fd, const TupleInfo *ti) heap_freetuple(tuple); } -/* - * Fill the fields of a integer based bucketing function - */ -static void -cagg_fill_bucket_function_integer_based(ContinuousAggsBucketFunction *bf, bool *isnull, - Datum *values) -{ - /* Bucket width */ - Assert(!isnull[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_width)]); - const char *bucket_width_str = TextDatumGetCString( - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_width)]); - Assert(strlen(bucket_width_str) > 0); - bf->bucket_integer_width = pg_strtoint64(bucket_width_str); - - /* Bucket origin cannot be used with integer based buckets */ - Assert(isnull[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_origin)] == - true); - - /* Bucket offset */ - if (!isnull[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_offset)]) - { - const char *offset_str = TextDatumGetCString( - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_offset)]); - bf->bucket_integer_offset = pg_strtoint64(offset_str); - } - - /* Timezones cannot be used with integer based buckets */ - Assert(isnull[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_timezone)] == - true); -} - -/* - * Fill the fields of a time based bucketing function - */ -static void -cagg_fill_bucket_function_time_based(ContinuousAggsBucketFunction *bf, bool *isnull, Datum *values) -{ - /* - * bucket_width - * - * The value is stored as TEXT since we have to store the interval value of time - * buckets and also the number value of integer based buckets. - */ - Assert(!isnull[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_width)]); - const char *bucket_width_str = TextDatumGetCString( - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_width)]); - Assert(strlen(bucket_width_str) > 0); - bf->bucket_time_width = DatumGetIntervalP( - DirectFunctionCall3(interval_in, CStringGetDatum(bucket_width_str), InvalidOid, -1)); - - /* Bucket origin */ - if (!isnull[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_origin)]) - { - const char *origin_str = TextDatumGetCString( - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_origin)]); - bf->bucket_time_origin = DatumGetTimestamp(DirectFunctionCall3(timestamptz_in, - CStringGetDatum(origin_str), - ObjectIdGetDatum(InvalidOid), - Int32GetDatum(-1))); - } - else - { - TIMESTAMP_NOBEGIN(bf->bucket_time_origin); - } - - /* Bucket offset */ - if (!isnull[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_offset)]) - { - const char *offset_str = TextDatumGetCString( - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_offset)]); - bf->bucket_time_offset = DatumGetIntervalP( - DirectFunctionCall3(interval_in, CStringGetDatum(offset_str), InvalidOid, -1)); - } - - /* Bucket timezone */ - if (!isnull[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_timezone)]) - { - bf->bucket_time_timezone = TextDatumGetCString( - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_timezone)]); - } -} - -static void -continuous_agg_fill_bucket_function(int32 mat_hypertable_id, ContinuousAggsBucketFunction *bf) -{ - ScanIterator iterator; - int count = 0; - - iterator = ts_scan_iterator_create(CONTINUOUS_AGGS_BUCKET_FUNCTION, - AccessShareLock, - CurrentMemoryContext); - init_scan_cagg_bucket_function_by_mat_hypertable_id(&iterator, mat_hypertable_id); - ts_scanner_foreach(&iterator) - { - Datum values[Natts_continuous_aggs_bucket_function]; - bool isnull[Natts_continuous_aggs_bucket_function]; - bool should_free; - - HeapTuple tuple = ts_scan_iterator_fetch_heap_tuple(&iterator, false, &should_free); - - /* - * Our usual GETSTRUCT() approach doesn't work when TEXT fields are involved, - * thus a more robust approach with heap_deform_tuple() is used here. - */ - heap_deform_tuple(tuple, ts_scan_iterator_tupledesc(&iterator), values, isnull); - - /* Bucket function */ - Assert(!isnull[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_function)]); - const char *bucket_function_str = TextDatumGetCString( - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_function)]); - bf->bucket_function = DatumGetObjectId( - DirectFunctionCall1(regprocedurein, CStringGetDatum(bucket_function_str))); - - bf->bucket_time_based = ts_continuous_agg_bucket_on_interval(bf->bucket_function); - - if (bf->bucket_time_based) - { - cagg_fill_bucket_function_time_based(bf, isnull, values); - } - else - { - cagg_fill_bucket_function_integer_based(bf, isnull, values); - } - - /* Bucket fixed width */ - Assert(!isnull[AttrNumberGetAttrOffset( - Anum_continuous_aggs_bucket_function_bucket_fixed_width)]); - bf->bucket_fixed_interval = DatumGetBool(values[AttrNumberGetAttrOffset( - Anum_continuous_aggs_bucket_function_bucket_fixed_width)]); - - count++; - - if (should_free) - heap_freetuple(tuple); - } - - /* - * This function should never be called unless we know that the corresponding - * cagg exists and uses a variable-sized bucket. There should be exactly one - * entry in .continuous_aggs_bucket_function catalog table for such a cagg. - */ - if (count != 1) - { - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("invalid or missing information about the bucketing function for cagg"), - errdetail("%d", mat_hypertable_id))); - } -} - static void continuous_agg_init(ContinuousAgg *cagg, const Form_continuous_agg fd) { @@ -563,8 +384,12 @@ continuous_agg_init(ContinuousAgg *cagg, const Form_continuous_agg fd) Assert(OidIsValid(cagg->relid)); Assert(OidIsValid(cagg->partition_type)); - cagg->bucket_function = palloc0(sizeof(ContinuousAggsBucketFunction)); - continuous_agg_fill_bucket_function(cagg->data.mat_hypertable_id, cagg->bucket_function); + ObjectAddress direct_view = + get_and_lock_rel_by_name(&fd->direct_view_schema, &fd->direct_view_name, AccessShareLock); + Assert(OidIsValid(direct_view.objectId)); + + cagg->bucket_function = + ts_cm_functions->continuous_agg_get_bucket_function_info_internal(direct_view.objectId); } TSDLLEXPORT CaggsInfo @@ -1004,8 +829,6 @@ drop_continuous_agg(FormData_continuous_agg *cadata, bool drop_user_view) ts_cagg_watermark_delete_by_mat_hypertable_id(form.mat_hypertable_id); } - cagg_bucket_function_delete(cadata->mat_hypertable_id); - /* Perform actual deletions now */ if (OidIsValid(user_view.objectId)) performDeletion(&user_view, DROP_RESTRICT, 0); diff --git a/src/ts_catalog/continuous_agg.h b/src/ts_catalog/continuous_agg.h index 268c42488d3..a55a2780ae9 100644 --- a/src/ts_catalog/continuous_agg.h +++ b/src/ts_catalog/continuous_agg.h @@ -77,14 +77,7 @@ ts_continuous_agg_get_compression_defelems(const WithClauseResult *with_clauses) */ typedef struct ContinuousAggsBucketFunction { - /* Oid of the bucketing function. In the catalog table, the regprocedure is used. This ensures - * that the Oid is mapped to a string when a backup is taken and the string is converted back to - * the Oid when the backup is restored. This way, we can use an Oid in the catalog table even - * when a backup is restored and the Oid may have changed. However, the dependency management in - * PostgreSQL does not track the Oid. If the function is dropped and a new one is created, the - * Oid changes and this value points to a non-existing Oid. This can not happen in real-world - * situations since PostgreSQL protects the bucket_function from deletion until the CAgg is - * defined. */ + /* Oid of the bucketing function */ Oid bucket_function; Oid bucket_width_type; /* type of bucket_width */ @@ -98,6 +91,7 @@ typedef struct ContinuousAggsBucketFunction * Fields that are used for time based buckets */ Interval *bucket_time_width; + /* * Custom origin value stored as UTC timestamp. * If not specified, stores infinity. diff --git a/tsl/src/continuous_aggs/common.c b/tsl/src/continuous_aggs/common.c index 50b1b849164..b285ad7952b 100644 --- a/tsl/src/continuous_aggs/common.c +++ b/tsl/src/continuous_aggs/common.c @@ -1502,16 +1502,17 @@ cagg_get_by_relid_or_fail(const Oid cagg_relid) /* Get time bucket function info based on the view definition */ ContinuousAggsBucketFunction * -ts_cagg_get_bucket_function_info(Oid view_oid) +tsl_cagg_get_bucket_function_info(Oid view_oid) { - Relation view_rel = relation_open(view_oid, AccessShareLock); + Relation view_rel = table_open(view_oid, AccessShareLock); Query *query = copyObject(get_view_query(view_rel)); - relation_close(view_rel, NoLock); + table_close(view_rel, NoLock); Assert(query != NULL); Assert(query->commandType == CMD_SELECT); ContinuousAggsBucketFunction *bf = palloc0(sizeof(ContinuousAggsBucketFunction)); + TIMESTAMP_NOBEGIN(bf->bucket_time_origin); ListCell *l; foreach (l, query->groupClause) diff --git a/tsl/src/continuous_aggs/common.h b/tsl/src/continuous_aggs/common.h index 6051e0de7d4..94f7570155e 100644 --- a/tsl/src/continuous_aggs/common.h +++ b/tsl/src/continuous_aggs/common.h @@ -140,4 +140,4 @@ cagg_get_time_min(const ContinuousAgg *cagg) return ts_time_get_min(cagg->partition_type); } -ContinuousAggsBucketFunction *ts_cagg_get_bucket_function_info(Oid view_oid); +extern ContinuousAggsBucketFunction *tsl_cagg_get_bucket_function_info(Oid view_oid); diff --git a/tsl/src/continuous_aggs/create.c b/tsl/src/continuous_aggs/create.c index f290cd38956..587065007ea 100644 --- a/tsl/src/continuous_aggs/create.c +++ b/tsl/src/continuous_aggs/create.c @@ -81,10 +81,6 @@ static void create_cagg_catalog_entry(int32 matht_id, int32 rawht_id, const char const char *partial_view, bool materialized_only, const char *direct_schema, const char *direct_view, const bool finalized, const int32 parent_mat_hypertable_id); -static void create_bucket_function_catalog_entry(int32 matht_id, Oid bucket_function, - const char *bucket_width, const char *origin, - const char *offset, const char *timezone, - const bool bucket_fixed_width); static void cagg_create_hypertable(int32 hypertable_id, Oid mat_tbloid, const char *matpartcolname, int64 mat_tbltimecol_interval); static void cagg_add_trigger_hypertable(Oid relid, int32 hypertable_id); @@ -177,86 +173,6 @@ create_cagg_catalog_entry(int32 matht_id, int32 rawht_id, const char *user_schem table_close(rel, RowExclusiveLock); } -/* - * Create a entry for the materialization table in table - * CONTINUOUS_AGGS_BUCKET_FUNCTION. - */ -static void -create_bucket_function_catalog_entry(int32 matht_id, Oid bucket_function, const char *bucket_width, - const char *bucket_origin, const char *bucket_offset, - const char *bucket_timezone, const bool bucket_fixed_width) -{ - Catalog *catalog = ts_catalog_get(); - Relation rel; - TupleDesc desc; - Datum values[Natts_continuous_aggs_bucket_function]; - bool nulls[Natts_continuous_aggs_bucket_function] = { false }; - CatalogSecurityContext sec_ctx; - - Assert(OidIsValid(bucket_function)); - Assert(bucket_width != NULL); - - rel = table_open(catalog_get_table_id(catalog, CONTINUOUS_AGGS_BUCKET_FUNCTION), - RowExclusiveLock); - desc = RelationGetDescr(rel); - - memset(values, 0, sizeof(values)); - - /* Hypertable ID */ - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_mat_hypertable_id)] = - matht_id; - - /* Bucket function */ - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_function)] = - CStringGetTextDatum(format_procedure_qualified(bucket_function)); - - /* Bucket width */ - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_width)] = - CStringGetTextDatum(bucket_width); - - /* Bucket origin */ - if (bucket_origin != NULL) - { - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_origin)] = - CStringGetTextDatum(bucket_origin); - } - else - { - nulls[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_origin)] = true; - } - - /* Bucket offset */ - if (bucket_offset != NULL) - { - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_offset)] = - CStringGetTextDatum(bucket_offset); - } - else - { - nulls[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_offset)] = true; - } - - /* Bucket timezone */ - if (bucket_timezone != NULL) - { - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_timezone)] = - CStringGetTextDatum(bucket_timezone); - } - else - { - nulls[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_timezone)] = true; - } - - /* Bucket fixed width */ - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_fixed_width)] = - BoolGetDatum(bucket_fixed_width); - - ts_catalog_database_info_become_owner(ts_catalog_database_info_get(), &sec_ctx); - ts_catalog_insert_values(rel, desc, values, nulls); - ts_catalog_restore_user(&sec_ctx); - table_close(rel, RowExclusiveLock); -} - /* * Create hypertable for the table referred by mat_tbloid * matpartcolname - partition column for hypertable @@ -815,14 +731,6 @@ cagg_create(const CreateTableAsStmt *create_stmt, ViewStmt *stmt, Query *panquer } } - create_bucket_function_catalog_entry(materialize_hypertable_id, - bucket_info->bf->bucket_function, - bucket_width, - bucket_origin, - bucket_offset, - bucket_info->bf->bucket_time_timezone, - bucket_info->bf->bucket_fixed_interval); - /* Step 5: Create trigger on raw hypertable -specified in the user view query. */ cagg_add_trigger_hypertable(bucket_info->htoid, bucket_info->htid); } diff --git a/tsl/src/continuous_aggs/utils.c b/tsl/src/continuous_aggs/utils.c index 6b9771c3162..fb9353ce0c1 100644 --- a/tsl/src/continuous_aggs/utils.c +++ b/tsl/src/continuous_aggs/utils.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include @@ -292,88 +291,6 @@ get_replacement_timebucket_function(const ContinuousAgg *cagg, bool *need_parame return funcid; } -/* - * Update the cagg bucket function catalog table. During the migration, we set a new bucket - * function and a origin if the bucket function is time based. - */ -static ScanTupleResult -cagg_time_bucket_update(TupleInfo *ti, void *data) -{ - bool should_free; - HeapTuple tuple = ts_scanner_fetch_heap_tuple(ti, false, &should_free); - TupleDesc tupleDesc = ts_scanner_get_tupledesc(ti); - const ContinuousAgg *cagg = (ContinuousAgg *) data; - - Datum values[Natts_continuous_aggs_bucket_function] = { 0 }; - bool isnull[Natts_continuous_aggs_bucket_function] = { 0 }; - bool doReplace[Natts_continuous_aggs_bucket_function] = { 0 }; - - /* Update the bucket function */ - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_function)] = - CStringGetTextDatum(format_procedure_qualified(cagg->bucket_function->bucket_function)); - doReplace[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_function)] = true; - - /* Set new origin if not already present. Time_bucket and time_bucket_ng use different - * origin values for time based values. - */ - if (cagg->bucket_function->bucket_time_based) - { - char *origin_value = DatumGetCString( - DirectFunctionCall1(timestamptz_out, - TimestampTzGetDatum(cagg->bucket_function->bucket_time_origin))); - - values[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_origin)] = - CStringGetTextDatum(origin_value); - - doReplace[AttrNumberGetAttrOffset(Anum_continuous_aggs_bucket_function_bucket_origin)] = - true; - } - - HeapTuple new_tuple = heap_modify_tuple(tuple, tupleDesc, values, isnull, doReplace); - - ts_catalog_update(ti->scanrel, new_tuple); - - heap_freetuple(new_tuple); - - if (should_free) - heap_freetuple(tuple); - - return SCAN_DONE; -} - -/* - * Search for the bucket function entry in the catalog and update the values. - */ -static int -replace_time_bucket_function_in_catalog(ContinuousAgg *cagg) -{ - ScanKeyData scankey[1]; - - ScanKeyInit(&scankey[0], - Anum_continuous_aggs_bucket_function_pkey_mat_hypertable_id, - BTEqualStrategyNumber, - F_INT4EQ, - Int32GetDatum(cagg->data.mat_hypertable_id)); - - Catalog *catalog = ts_catalog_get(); - - ScannerCtx scanctx = { - .table = catalog_get_table_id(catalog, CONTINUOUS_AGGS_BUCKET_FUNCTION), - .index = catalog_get_index(catalog, - CONTINUOUS_AGGS_BUCKET_FUNCTION, - CONTINUOUS_AGGS_BUCKET_FUNCTION_PKEY_IDX), - .nkeys = 1, - .scankey = scankey, - .data = cagg, - .limit = 1, - .tuple_found = cagg_time_bucket_update, - .lockmode = AccessShareLock, - .scandirection = ForwardScanDirection, - }; - - return ts_scanner_scan(&scanctx); -} - typedef struct TimeBucketInfoContext { /* The updated cagg definition */ @@ -578,12 +495,12 @@ continuous_agg_replace_function(const ContinuousAgg *cagg, Oid function_to_repla * Get the default origin value for time_bucket to be compatible with * the default origin of time_bucket_ng. */ -static TimestampTz -continuous_agg_get_default_origin(Oid new_bucket_function) +TimestampTz +continuous_agg_get_default_origin(Oid bucket_function) { - Assert(OidIsValid(new_bucket_function)); + Assert(OidIsValid(bucket_function)); - Oid bucket_function_rettype = get_func_rettype(new_bucket_function); + Oid bucket_function_rettype = get_func_rettype(bucket_function); Assert(OidIsValid(bucket_function_rettype)); Datum origin; @@ -689,22 +606,19 @@ continuous_agg_migrate_to_time_bucket(PG_FUNCTION_ARGS) origin_added_during_migration = true; } - /* Update the catalog */ - replace_time_bucket_function_in_catalog(cagg); + /* Modify the CAgg view definition */ + continuous_agg_replace_function(cagg, + old_bucket_function, + origin_added_during_migration, + need_parameter_order_change); /* Fetch new CAgg definition from catalog */ ContinuousAgg PG_USED_FOR_ASSERTS_ONLY *new_cagg_definition = cagg_get_by_relid_or_fail(cagg_relid); - Assert(new_cagg_definition->bucket_function->bucket_function == new_bucket_function); + Assert(new_cagg_definition->bucket_function->bucket_function == old_bucket_function); Assert(cagg->bucket_function->bucket_time_origin == new_cagg_definition->bucket_function->bucket_time_origin); - /* Modify the CAgg view definition */ - continuous_agg_replace_function(cagg, - old_bucket_function, - origin_added_during_migration, - need_parameter_order_change); - /* The migration is a procedure, no return value is expected */ PG_RETURN_VOID(); } @@ -892,7 +806,7 @@ cagg_get_bucket_function_datum(int32 mat_hypertable_id, FunctionCallInfo fcinfo) if (fcinfo != NULL && get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "function returning record called in context that cannot accept type record"); - ContinuousAggsBucketFunction *bf = ts_cagg_get_bucket_function_info(direct_view_oid); + ContinuousAggsBucketFunction *bf = tsl_cagg_get_bucket_function_info(direct_view_oid); if (!OidIsValid(bf->bucket_function)) { diff --git a/tsl/src/continuous_aggs/utils.h b/tsl/src/continuous_aggs/utils.h index 99292f4dba5..a0ed1e34b9a 100644 --- a/tsl/src/continuous_aggs/utils.h +++ b/tsl/src/continuous_aggs/utils.h @@ -19,3 +19,4 @@ extern Datum continuous_agg_validate_query(PG_FUNCTION_ARGS); extern Datum continuous_agg_migrate_to_time_bucket(PG_FUNCTION_ARGS); extern Datum continuous_agg_get_bucket_function(PG_FUNCTION_ARGS); extern Datum continuous_agg_get_bucket_function_info(PG_FUNCTION_ARGS); +extern TimestampTz continuous_agg_get_default_origin(Oid new_bucket_function); diff --git a/tsl/src/init.c b/tsl/src/init.c index 24f5c917515..3ef73d2897b 100644 --- a/tsl/src/init.c +++ b/tsl/src/init.c @@ -147,6 +147,7 @@ CrossModuleFunctions tsl_cm_functions = { .continuous_agg_validate_query = continuous_agg_validate_query, .continuous_agg_get_bucket_function = continuous_agg_get_bucket_function, .continuous_agg_get_bucket_function_info = continuous_agg_get_bucket_function_info, + .continuous_agg_get_bucket_function_info_internal = tsl_cagg_get_bucket_function_info, .continuous_agg_migrate_to_time_bucket = continuous_agg_migrate_to_time_bucket, .cagg_try_repair = tsl_cagg_try_repair, diff --git a/tsl/test/expected/cagg_bgw-16.out b/tsl/test/expected/cagg_bgw-16.out index 15abb5ea074..10a9839fca3 100644 --- a/tsl/test/expected/cagg_bgw-16.out +++ b/tsl/test/expected/cagg_bgw-16.out @@ -109,7 +109,7 @@ SELECT mat_hypertable_id, user_view_schema, user_view_name FROM _timescaledb_cat 2 | public | test_continuous_agg_view (1 row) -SELECT mat_hypertable_id, bucket_width FROM _timescaledb_catalog.continuous_aggs_bucket_function; +SELECT mat_hypertable_id, bucket_width FROM _timescaledb_catalog.continuous_agg, LATERAL _timescaledb_functions.cagg_get_bucket_function_info(mat_hypertable_id); mat_hypertable_id | bucket_width -------------------+-------------- 2 | 2 diff --git a/tsl/test/expected/cagg_migrate.out b/tsl/test/expected/cagg_migrate.out index 492303e1ff2..92c0c0dd197 100644 --- a/tsl/test/expected/cagg_migrate.out +++ b/tsl/test/expected/cagg_migrate.out @@ -159,7 +159,6 @@ UNION ALL COPY _timescaledb_catalog.hypertable (id, schema_name, table_name, associated_schema_name, associated_table_prefix, num_dimensions, chunk_sizing_func_schema, chunk_sizing_func_name, chunk_target_size, compression_state, compressed_hypertable_id, status) FROM stdin; COPY _timescaledb_catalog.dimension (id, hypertable_id, column_name, column_type, aligned, num_slices, partitioning_func_schema, partitioning_func, interval_length, compress_interval_length, integer_now_func_schema, integer_now_func) FROM stdin; COPY _timescaledb_catalog.continuous_agg (mat_hypertable_id, raw_hypertable_id, parent_mat_hypertable_id, user_view_schema, user_view_name, partial_view_schema, partial_view_name, direct_view_schema, direct_view_name, materialized_only, finalized) FROM stdin; -COPY _timescaledb_catalog.continuous_aggs_bucket_function (mat_hypertable_id, bucket_func, bucket_width, bucket_fixed_width) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_invalidation_threshold (hypertable_id, watermark) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_materialization_invalidation_log (materialization_id, lowest_modified_value, greatest_modified_value) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_watermark (mat_hypertable_id, watermark) FROM stdin; @@ -1028,7 +1027,6 @@ UNION ALL COPY _timescaledb_catalog.hypertable (id, schema_name, table_name, associated_schema_name, associated_table_prefix, num_dimensions, chunk_sizing_func_schema, chunk_sizing_func_name, chunk_target_size, compression_state, compressed_hypertable_id, status) FROM stdin; COPY _timescaledb_catalog.dimension (id, hypertable_id, column_name, column_type, aligned, num_slices, partitioning_func_schema, partitioning_func, interval_length, compress_interval_length, integer_now_func_schema, integer_now_func) FROM stdin; COPY _timescaledb_catalog.continuous_agg (mat_hypertable_id, raw_hypertable_id, parent_mat_hypertable_id, user_view_schema, user_view_name, partial_view_schema, partial_view_name, direct_view_schema, direct_view_name, materialized_only, finalized) FROM stdin; -COPY _timescaledb_catalog.continuous_aggs_bucket_function (mat_hypertable_id, bucket_func, bucket_width, bucket_fixed_width) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_invalidation_threshold (hypertable_id, watermark) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_materialization_invalidation_log (materialization_id, lowest_modified_value, greatest_modified_value) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_watermark (mat_hypertable_id, watermark) FROM stdin; @@ -1874,7 +1872,6 @@ UNION ALL COPY _timescaledb_catalog.hypertable (id, schema_name, table_name, associated_schema_name, associated_table_prefix, num_dimensions, chunk_sizing_func_schema, chunk_sizing_func_name, chunk_target_size, compression_state, compressed_hypertable_id, status) FROM stdin; COPY _timescaledb_catalog.dimension (id, hypertable_id, column_name, column_type, aligned, num_slices, partitioning_func_schema, partitioning_func, interval_length, compress_interval_length, integer_now_func_schema, integer_now_func) FROM stdin; COPY _timescaledb_catalog.continuous_agg (mat_hypertable_id, raw_hypertable_id, parent_mat_hypertable_id, user_view_schema, user_view_name, partial_view_schema, partial_view_name, direct_view_schema, direct_view_name, materialized_only, finalized) FROM stdin; -COPY _timescaledb_catalog.continuous_aggs_bucket_function (mat_hypertable_id, bucket_func, bucket_width, bucket_fixed_width) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_invalidation_threshold (hypertable_id, watermark) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_materialization_invalidation_log (materialization_id, lowest_modified_value, greatest_modified_value) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_watermark (mat_hypertable_id, watermark) FROM stdin; @@ -2710,7 +2707,6 @@ UNION ALL COPY _timescaledb_catalog.hypertable (id, schema_name, table_name, associated_schema_name, associated_table_prefix, num_dimensions, chunk_sizing_func_schema, chunk_sizing_func_name, chunk_target_size, compression_state, compressed_hypertable_id, status) FROM stdin; COPY _timescaledb_catalog.dimension (id, hypertable_id, column_name, column_type, aligned, num_slices, partitioning_func_schema, partitioning_func, interval_length, compress_interval_length, integer_now_func_schema, integer_now_func) FROM stdin; COPY _timescaledb_catalog.continuous_agg (mat_hypertable_id, raw_hypertable_id, parent_mat_hypertable_id, user_view_schema, user_view_name, partial_view_schema, partial_view_name, direct_view_schema, direct_view_name, materialized_only, finalized) FROM stdin; -COPY _timescaledb_catalog.continuous_aggs_bucket_function (mat_hypertable_id, bucket_func, bucket_width, bucket_fixed_width) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_invalidation_threshold (hypertable_id, watermark) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_materialization_invalidation_log (materialization_id, lowest_modified_value, greatest_modified_value) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_watermark (mat_hypertable_id, watermark) FROM stdin; @@ -2910,7 +2906,6 @@ UNION ALL COPY _timescaledb_catalog.hypertable (id, schema_name, table_name, associated_schema_name, associated_table_prefix, num_dimensions, chunk_sizing_func_schema, chunk_sizing_func_name, chunk_target_size, compression_state, compressed_hypertable_id, status) FROM stdin; COPY _timescaledb_catalog.dimension (id, hypertable_id, column_name, column_type, aligned, num_slices, partitioning_func_schema, partitioning_func, interval_length, compress_interval_length, integer_now_func_schema, integer_now_func) FROM stdin; COPY _timescaledb_catalog.continuous_agg (mat_hypertable_id, raw_hypertable_id, parent_mat_hypertable_id, user_view_schema, user_view_name, partial_view_schema, partial_view_name, direct_view_schema, direct_view_name, materialized_only, finalized) FROM stdin; -COPY _timescaledb_catalog.continuous_aggs_bucket_function (mat_hypertable_id, bucket_func, bucket_width, bucket_fixed_width) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_invalidation_threshold (hypertable_id, watermark) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_materialization_invalidation_log (materialization_id, lowest_modified_value, greatest_modified_value) FROM stdin; COPY _timescaledb_catalog.continuous_aggs_watermark (mat_hypertable_id, watermark) FROM stdin; diff --git a/tsl/test/expected/cagg_utils.out b/tsl/test/expected/cagg_utils.out index 8ac4bf55243..9eee9ca0bf7 100644 --- a/tsl/test/expected/cagg_utils.out +++ b/tsl/test/expected/cagg_utils.out @@ -378,10 +378,10 @@ ORDER BY user_view_name; -----------------------------+---------------------------------------------------------------------------------------+--------------+------------------------------+---------------+-----------------+-------------------- integer_ht_cagg | time_bucket(integer,integer) | 1 | | | | t integer_ht_cagg_offset | time_bucket(integer,integer,integer) | 1 | | 10 | | t - temperature_4h | time_bucket(interval,timestamp without time zone) | @ 4 hours | Fri Dec 31 16:00:00 1999 PST | | | t - temperature_tz_4h | time_bucket(interval,timestamp with time zone) | @ 4 hours | Fri Dec 31 16:00:00 1999 PST | | | t - temperature_tz_4h_ts | time_bucket(interval,timestamp with time zone,text,timestamp with time zone,interval) | @ 4 hours | Fri Dec 31 16:00:00 1999 PST | | Europe/Berlin | f - temperature_tz_4h_ts_offset | time_bucket(interval,timestamp with time zone,text,timestamp with time zone,interval) | @ 4 hours | Fri Dec 31 16:00:00 1999 PST | @ 1 hour | Europe/Berlin | f + temperature_4h | time_bucket(interval,timestamp without time zone) | @ 4 hours | | | | t + temperature_tz_4h | time_bucket(interval,timestamp with time zone) | @ 4 hours | | | | t + temperature_tz_4h_ts | time_bucket(interval,timestamp with time zone,text,timestamp with time zone,interval) | @ 4 hours | | | Europe/Berlin | f + temperature_tz_4h_ts_offset | time_bucket(interval,timestamp with time zone,text,timestamp with time zone,interval) | @ 4 hours | | @ 1 hour | Europe/Berlin | f temperature_tz_4h_ts_origin | time_bucket(interval,timestamp with time zone,text,timestamp with time zone,interval) | @ 4 hours | Mon Jan 01 00:00:00 2001 PST | | Europe/Berlin | f (7 rows) diff --git a/tsl/test/sql/cagg_bgw.sql.in b/tsl/test/sql/cagg_bgw.sql.in index 4d1a0a34b74..4391eb2b3e0 100644 --- a/tsl/test/sql/cagg_bgw.sql.in +++ b/tsl/test/sql/cagg_bgw.sql.in @@ -95,7 +95,7 @@ SELECT id as raw_table_id FROM _timescaledb_catalog.hypertable WHERE table_name= -- min distance from end should be 1 SELECT mat_hypertable_id, user_view_schema, user_view_name FROM _timescaledb_catalog.continuous_agg; -SELECT mat_hypertable_id, bucket_width FROM _timescaledb_catalog.continuous_aggs_bucket_function; +SELECT mat_hypertable_id, bucket_width FROM _timescaledb_catalog.continuous_agg, LATERAL _timescaledb_functions.cagg_get_bucket_function_info(mat_hypertable_id); SELECT mat_hypertable_id FROM _timescaledb_catalog.continuous_agg \gset SELECT id AS job_id FROM _timescaledb_config.bgw_job where hypertable_id=:mat_hypertable_id \gset diff --git a/tsl/test/sql/exp_cagg_monthly.sql b/tsl/test/sql/exp_cagg_monthly.sql index ddfcb25d325..13774955fe7 100644 --- a/tsl/test/sql/exp_cagg_monthly.sql +++ b/tsl/test/sql/exp_cagg_monthly.sql @@ -76,8 +76,8 @@ WHERE user_view_name = 'conditions_summary' \gset \pset null -SELECT * -FROM _timescaledb_catalog.continuous_aggs_bucket_function +SELECT mat_hypertable_id, bf.* +FROM _timescaledb_catalog.continuous_agg, LATERAL _timescaledb_functions.cagg_get_bucket_function_info(mat_hypertable_id) AS bf WHERE mat_hypertable_id = :cagg_id; \pset null "" @@ -103,20 +103,6 @@ SELECT city, to_char(bucket, 'YYYY-MM-DD') AS month, min, max FROM conditions_summary ORDER by month, city; --- Special check for "invalid or missing information about the bucketing --- function" code path -\c :TEST_DBNAME :ROLE_CLUSTER_SUPERUSER -CREATE TEMPORARY TABLE restore_table ( LIKE _timescaledb_catalog.continuous_aggs_bucket_function ); -INSERT INTO restore_table SELECT * FROM _timescaledb_catalog.continuous_aggs_bucket_function; -DELETE FROM _timescaledb_catalog.continuous_aggs_bucket_function; -\set ON_ERROR_STOP 0 --- should fail with "invalid or missing information..." -CALL refresh_continuous_aggregate('conditions_summary', '2021-06-01', '2021-07-01'); -\set ON_ERROR_STOP 1 -INSERT INTO _timescaledb_catalog.continuous_aggs_bucket_function SELECT * FROM restore_table; -DROP TABLE restore_table; --- should execute successfully -CALL refresh_continuous_aggregate('conditions_summary', '2021-06-01', '2021-07-01'); SET ROLE :ROLE_DEFAULT_PERM_USER; -- Check the invalidation threshold @@ -166,7 +152,8 @@ DROP MATERIALIZED VIEW conditions_summary; SELECT * FROM _timescaledb_catalog.continuous_agg WHERE mat_hypertable_id = :cagg_id; -SELECT * FROM _timescaledb_catalog.continuous_aggs_bucket_function +SELECT mat_hypertable_id, bf.* +FROM _timescaledb_catalog.continuous_agg, LATERAL _timescaledb_functions.cagg_get_bucket_function_info(mat_hypertable_id) AS bf WHERE mat_hypertable_id = :cagg_id; -- Re-create cagg, this time WITH DATA diff --git a/tsl/test/sql/exp_cagg_next_gen.sql b/tsl/test/sql/exp_cagg_next_gen.sql index 6aec2b6c784..d0cb03a770f 100644 --- a/tsl/test/sql/exp_cagg_next_gen.sql +++ b/tsl/test/sql/exp_cagg_next_gen.sql @@ -160,8 +160,9 @@ FROM conditions GROUP BY city, bucket WITH NO DATA; -SELECT bucket_func, bucket_width, bucket_origin, bucket_timezone, bucket_fixed_width -FROM _timescaledb_catalog.continuous_aggs_bucket_function ORDER BY 1; +SELECT bf.* +FROM _timescaledb_catalog.continuous_agg, LATERAL _timescaledb_functions.cagg_get_bucket_function_info(mat_hypertable_id) AS bf +ORDER BY 1; -- Try to toggle realtime feature on existing CAgg using timescaledb_experimental.time_bucket_ng ALTER MATERIALIZED VIEW conditions_summary_monthly SET (timescaledb.materialized_only=false); diff --git a/tsl/test/sql/exp_cagg_origin.sql b/tsl/test/sql/exp_cagg_origin.sql index 7641da0d8af..f66377ba5e2 100644 --- a/tsl/test/sql/exp_cagg_origin.sql +++ b/tsl/test/sql/exp_cagg_origin.sql @@ -526,9 +526,9 @@ SELECT mat_hypertable_id AS cagg_id WHERE user_view_name = 'conditions_summary_timestamptz' \gset -SELECT bucket_func, bucket_width, bucket_origin, bucket_timezone, bucket_fixed_width - FROM _timescaledb_catalog.continuous_aggs_bucket_function - WHERE mat_hypertable_id = :cagg_id; +SELECT bf.* +FROM _timescaledb_catalog.continuous_agg, LATERAL _timescaledb_functions.cagg_get_bucket_function_info(mat_hypertable_id) AS bf +WHERE mat_hypertable_id = :cagg_id; SELECT city, to_char(bucket at time zone 'MSK', 'YYYY-MM-DD HH24:MI:SS') AS b, min, max FROM conditions_summary_timestamptz diff --git a/tsl/test/sql/exp_cagg_timezone.sql b/tsl/test/sql/exp_cagg_timezone.sql index 9a93182562f..8c03e6c8949 100644 --- a/tsl/test/sql/exp_cagg_timezone.sql +++ b/tsl/test/sql/exp_cagg_timezone.sql @@ -126,8 +126,8 @@ WHERE user_view_name = 'conditions_summary_tz' \gset -- Make sure the timezone is saved in the catalog table -SELECT bucket_func, bucket_width, bucket_origin, bucket_timezone, bucket_fixed_width -FROM _timescaledb_catalog.continuous_aggs_bucket_function +SELECT bf.* +FROM _timescaledb_catalog.continuous_agg, LATERAL _timescaledb_functions.cagg_get_bucket_function_info(mat_hypertable_id) AS bf WHERE mat_hypertable_id = :cagg_id_tz; -- Make sure that buckets with specified timezone are always treated as @@ -153,8 +153,8 @@ WHERE user_view_name = 'conditions_summary_1w' \gset -- Make sure the timezone is saved in the catalog table -SELECT bucket_func, bucket_width, bucket_origin, bucket_timezone, bucket_fixed_width -FROM _timescaledb_catalog.continuous_aggs_bucket_function +SELECT bf.* +FROM _timescaledb_catalog.continuous_agg, LATERAL _timescaledb_functions.cagg_get_bucket_function_info(mat_hypertable_id) AS bf WHERE mat_hypertable_id = :cagg_id_1w; -- Check the invalidation threshold is -infinity diff --git a/tsl/test/sql/include/cagg_query_common.sql b/tsl/test/sql/include/cagg_query_common.sql index c1bcb3b9da4..e16da6ffec2 100644 --- a/tsl/test/sql/include/cagg_query_common.sql +++ b/tsl/test/sql/include/cagg_query_common.sql @@ -2,6 +2,7 @@ -- Please see the included NOTICE for copyright information and -- LICENSE-TIMESCALE for a copy of the license. +\set TEST_BASE_NAME cagg_query SELECT format('%s/results/%s_results_view.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_VIEW", format('%s/results/%s_results_view_hashagg.out', :'TEST_OUTPUT_DIR', :'TEST_BASE_NAME') as "TEST_RESULTS_VIEW_HASHAGG", @@ -360,7 +361,7 @@ INSERT INTO table_bigint VALUES(1,2); CREATE VIEW caggs_info AS SELECT user_view_schema, user_view_name, bucket_func, bucket_width, bucket_origin, bucket_offset, bucket_timezone, bucket_fixed_width -FROM _timescaledb_catalog.continuous_aggs_bucket_function NATURAL JOIN _timescaledb_catalog.continuous_agg; +FROM _timescaledb_catalog.continuous_agg, LATERAL _timescaledb_functions.cagg_get_bucket_function_info(mat_hypertable_id); --- -- Tests with CAgg creation @@ -557,17 +558,6 @@ CREATE MATERIALIZED VIEW cagg_bigint_offset2 GROUP BY 1 WITH NO DATA; SELECT * FROM caggs_info WHERE user_view_name = 'cagg_bigint_offset2'; --- mess with the bucket_func signature to make sure it will raise an exception -SET ROLE :ROLE_CLUSTER_SUPERUSER; -\set ON_ERROR_STOP 0 -BEGIN; -UPDATE _timescaledb_catalog.continuous_aggs_bucket_function SET bucket_func = 'func_does_not_exist()'; --- should error because function does not exist -CALL refresh_continuous_aggregate('cagg_bigint_offset2', NULL, NULL); -ROLLBACK; -\set ON_ERROR_STOP 1 -SET ROLE :ROLE_DEFAULT_PERM_USER; - DROP MATERIALIZED VIEW cagg_bigint_offset2; -- Test invalid bucket definitions diff --git a/tsl/test/sql/include/cagg_run_timebucket_migration.sql b/tsl/test/sql/include/cagg_run_timebucket_migration.sql index 8d166adf8d4..fcab342deda 100644 --- a/tsl/test/sql/include/cagg_run_timebucket_migration.sql +++ b/tsl/test/sql/include/cagg_run_timebucket_migration.sql @@ -8,14 +8,20 @@ SELECT mat_hypertable_id, FROM _timescaledb_catalog.continuous_agg where user_view_name = :'CAGG_NAME' \gset -SELECT * FROM _timescaledb_catalog.continuous_aggs_bucket_function WHERE mat_hypertable_id = :mat_hypertable_id; +SELECT mat_hypertable_id, bf.* +FROM _timescaledb_catalog.continuous_agg, LATERAL _timescaledb_functions.cagg_get_bucket_function_info(mat_hypertable_id) AS bf +WHERE mat_hypertable_id = :mat_hypertable_id; + SELECT pg_get_viewdef(:'partial_view', true); SELECT pg_get_viewdef(:'direct_view', true); SELECT pg_get_viewdef(:'CAGG_NAME', true); CALL _timescaledb_functions.cagg_migrate_to_time_bucket(:'CAGG_NAME'); -SELECT * FROM _timescaledb_catalog.continuous_aggs_bucket_function WHERE mat_hypertable_id = :mat_hypertable_id; +SELECT mat_hypertable_id, bf.* +FROM _timescaledb_catalog.continuous_agg, LATERAL _timescaledb_functions.cagg_get_bucket_function_info(mat_hypertable_id) AS bf +WHERE mat_hypertable_id = :mat_hypertable_id; + SELECT pg_get_viewdef(:'partial_view', true); SELECT pg_get_viewdef(:'direct_view', true); SELECT pg_get_viewdef(:'CAGG_NAME', true); diff --git a/tsl/test/sql/include/data/cagg_migrate_integer.sql.gz b/tsl/test/sql/include/data/cagg_migrate_integer.sql.gz index 4a67fae9f5d..3a04dba4a6e 100644 Binary files a/tsl/test/sql/include/data/cagg_migrate_integer.sql.gz and b/tsl/test/sql/include/data/cagg_migrate_integer.sql.gz differ diff --git a/tsl/test/sql/include/data/cagg_migrate_timestamp.sql.gz b/tsl/test/sql/include/data/cagg_migrate_timestamp.sql.gz index bb3cf45b41c..227d3405382 100644 Binary files a/tsl/test/sql/include/data/cagg_migrate_timestamp.sql.gz and b/tsl/test/sql/include/data/cagg_migrate_timestamp.sql.gz differ diff --git a/tsl/test/sql/include/data/cagg_migrate_timestamptz.sql.gz b/tsl/test/sql/include/data/cagg_migrate_timestamptz.sql.gz index 32744f15b4f..986ae0384bb 100644 Binary files a/tsl/test/sql/include/data/cagg_migrate_timestamptz.sql.gz and b/tsl/test/sql/include/data/cagg_migrate_timestamptz.sql.gz differ