From bfd92ab822c17e4e0f19cb0a6a72a03ac775424a Mon Sep 17 00:00:00 2001 From: davidkohn88 Date: Tue, 8 Jun 2021 18:05:17 -0400 Subject: [PATCH] Use CREATE OR REPLACE AGGREGATE From PG12 on, CREATE OR REPLACE is supported for aggregates, therefore, since we have dropped support for PG11, we can avoid going through the rigamarole of having our aggregates in a separate file from the functions we define to support them. Nor do we need to handle aggregates separately from other functions as their creation is now idempotent. --- sql/CMakeLists.txt | 4 +-- sql/aggregates.sql | 59 ------------------------------------- sql/bookend.sql | 34 +++++++++++++++++++++ sql/histogram.sql | 20 +++++++++++++ sql/partialize_finalize.sql | 6 ++++ 5 files changed, 61 insertions(+), 62 deletions(-) delete mode 100644 sql/aggregates.sql diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 8174cf609..f753e8f8b 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -93,8 +93,6 @@ endfunction() version_files("${PRE_UPDATE_FILES}" PRE_UPDATE_FILES_VERSIONED) version_files("${POST_UPDATE_FILES}" POST_UPDATE_FILES_VERSIONED) version_files("${PRE_INSTALL_SOURCE_FILES}" PRE_INSTALL_SOURCE_FILES_VERSIONED) -version_files("${IMMUTABLE_API_SOURCE_FILES}" - IMMUTABLE_API_SOURCE_FILES_VERSIONED) version_files("${SOURCE_FILES}" SOURCE_FILES_VERSIONED) version_files("${MOD_FILES}" MOD_FILES_VERSIONED) version_files("updates/latest-dev.sql" LASTEST_MOD_VERSIONED) @@ -122,7 +120,7 @@ endfunction() # Generate the extension file used with CREATE EXTENSION cat_files( - "${PRE_INSTALL_SOURCE_FILES_VERSIONED};${SOURCE_FILES_VERSIONED};${IMMUTABLE_API_SOURCE_FILES_VERSIONED};${NOTICE_FILE}" + "${PRE_INSTALL_SOURCE_FILES_VERSIONED};${SOURCE_FILES_VERSIONED};${NOTICE_FILE}" ${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_FILE}) add_custom_target(sqlfile ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${INSTALL_FILE}) diff --git a/sql/aggregates.sql b/sql/aggregates.sql deleted file mode 100644 index a716512ec..000000000 --- a/sql/aggregates.sql +++ /dev/null @@ -1,59 +0,0 @@ --- This file and its contents are licensed under the Apache License 2.0. --- Please see the included NOTICE for copyright information and --- LICENSE-APACHE for a copy of the license. - --- This file is meant to contain aggregate functions that need to be created only --- once and not recreated during updates. --- There is no CREATE OR REPLACE AGGREGATE which means that the only way to replace --- an aggregate is to DROP then CREATE which is problematic as it will fail --- if the previous version of the aggregate has dependencies. --- NOTE that WHEN CREATING NEW FUNCTIONS HERE you should also make sure they are --- created in an update script so that both new users and people updating from a --- previous version get the new function - - ---This aggregate returns the "first" element of the first argument when ordered by the second argument. ---Ex. first(temp, time) returns the temp value for the row with the lowest time -CREATE AGGREGATE first(anyelement, "any") ( - SFUNC = _timescaledb_internal.first_sfunc, - STYPE = internal, - COMBINEFUNC = _timescaledb_internal.first_combinefunc, - SERIALFUNC = _timescaledb_internal.bookend_serializefunc, - DESERIALFUNC = _timescaledb_internal.bookend_deserializefunc, - PARALLEL = SAFE, - FINALFUNC = _timescaledb_internal.bookend_finalfunc, - FINALFUNC_EXTRA -); - ---This aggregate returns the "last" element of the first argument when ordered by the second argument. ---Ex. last(temp, time) returns the temp value for the row with highest time -CREATE AGGREGATE last(anyelement, "any") ( - SFUNC = _timescaledb_internal.last_sfunc, - STYPE = internal, - COMBINEFUNC = _timescaledb_internal.last_combinefunc, - SERIALFUNC = _timescaledb_internal.bookend_serializefunc, - DESERIALFUNC = _timescaledb_internal.bookend_deserializefunc, - PARALLEL = SAFE, - FINALFUNC = _timescaledb_internal.bookend_finalfunc, - FINALFUNC_EXTRA -); - --- This aggregate partitions the dataset into a specified number of buckets (nbuckets) ranging --- from the inputted min to max values. -CREATE AGGREGATE histogram (DOUBLE PRECISION, DOUBLE PRECISION, DOUBLE PRECISION, INTEGER) ( - SFUNC = _timescaledb_internal.hist_sfunc, - STYPE = INTERNAL, - COMBINEFUNC = _timescaledb_internal.hist_combinefunc, - SERIALFUNC = _timescaledb_internal.hist_serializefunc, - DESERIALFUNC = _timescaledb_internal.hist_deserializefunc, - PARALLEL = SAFE, - FINALFUNC = _timescaledb_internal.hist_finalfunc, - FINALFUNC_EXTRA -); - -CREATE AGGREGATE _timescaledb_internal.finalize_agg(agg_name TEXT, inner_agg_collation_schema NAME, inner_agg_collation_name NAME, inner_agg_input_types NAME[][], inner_agg_serialized_state BYTEA, return_type_dummy_val anyelement) ( - SFUNC = _timescaledb_internal.finalize_agg_sfunc, - STYPE = internal, - FINALFUNC = _timescaledb_internal.finalize_agg_ffunc, - FINALFUNC_EXTRA -); diff --git a/sql/bookend.sql b/sql/bookend.sql index 0ab77fa88..a30415f52 100644 --- a/sql/bookend.sql +++ b/sql/bookend.sql @@ -36,3 +36,37 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, RETURNS internal AS '@MODULE_PATHNAME@', 'ts_bookend_deserializefunc' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + + +-- We started using CREATE OR REPLACE AGGREGATE for aggregate creation once the syntax was fully supported +-- as it is easier to support idempotent changes this way. This will allow for changes to functions supporting +-- the aggregate, and, for instance, the definition and inclusion of inverse functions for window function +-- support. However, it should still be noted that changes to the data structures used for the internal +-- state of the aggregate must be backwards compatible and the old format must be accepted by any new functions +-- in order for them to continue working with Continuous Aggregates, where old states may have been materialized. + +--This aggregate returns the "first" value of the first argument when ordered by the second argument. +--Ex. first(temp, time) returns the temp value for the row with the lowest time +CREATE OR REPLACE AGGREGATE first(anyelement, "any") ( + SFUNC = _timescaledb_internal.first_sfunc, + STYPE = internal, + COMBINEFUNC = _timescaledb_internal.first_combinefunc, + SERIALFUNC = _timescaledb_internal.bookend_serializefunc, + DESERIALFUNC = _timescaledb_internal.bookend_deserializefunc, + PARALLEL = SAFE, + FINALFUNC = _timescaledb_internal.bookend_finalfunc, + FINALFUNC_EXTRA +); + +--This aggregate returns the "last" value of the first argument when ordered by the second argument. +--Ex. last(temp, time) returns the temp value for the row with highest time +CREATE OR REPLACE AGGREGATE last(anyelement, "any") ( + SFUNC = _timescaledb_internal.last_sfunc, + STYPE = internal, + COMBINEFUNC = _timescaledb_internal.last_combinefunc, + SERIALFUNC = _timescaledb_internal.bookend_serializefunc, + DESERIALFUNC = _timescaledb_internal.bookend_deserializefunc, + PARALLEL = SAFE, + FINALFUNC = _timescaledb_internal.bookend_finalfunc, + FINALFUNC_EXTRA +); diff --git a/sql/histogram.sql b/sql/histogram.sql index bebc84968..414713080 100644 --- a/sql/histogram.sql +++ b/sql/histogram.sql @@ -26,3 +26,23 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_finalfunc(state INTERNAL, RETURNS INTEGER[] AS '@MODULE_PATHNAME@', 'ts_hist_finalfunc' LANGUAGE C IMMUTABLE PARALLEL SAFE; + +-- We started using CREATE OR REPLACE AGGREGATE for aggregate creation once the syntax was fully supported +-- as it is easier to support idempotent changes this way. This will allow for changes to functions supporting +-- the aggregate, and, for instance, the definition and inclusion of inverse functions for window function +-- support. However, it should still be noted that changes to the data structures used for the internal +-- state of the aggregate must be backwards compatible and the old format must be accepted by any new functions +-- in order for them to continue working with Continuous Aggregates, where old states may have been materialized. + +-- This aggregate partitions the dataset into a specified number of buckets (nbuckets) ranging +-- from the inputted min to max values. +CREATE OR REPLACE AGGREGATE histogram (DOUBLE PRECISION, DOUBLE PRECISION, DOUBLE PRECISION, INTEGER) ( + SFUNC = _timescaledb_internal.hist_sfunc, + STYPE = INTERNAL, + COMBINEFUNC = _timescaledb_internal.hist_combinefunc, + SERIALFUNC = _timescaledb_internal.hist_serializefunc, + DESERIALFUNC = _timescaledb_internal.hist_deserializefunc, + PARALLEL = SAFE, + FINALFUNC = _timescaledb_internal.hist_finalfunc, + FINALFUNC_EXTRA +); diff --git a/sql/partialize_finalize.sql b/sql/partialize_finalize.sql index 34a22785b..e3a97c074 100644 --- a/sql/partialize_finalize.sql +++ b/sql/partialize_finalize.sql @@ -17,3 +17,9 @@ RETURNS anyelement AS '@MODULE_PATHNAME@', 'ts_finalize_agg_ffunc' LANGUAGE C IMMUTABLE ; +CREATE OR REPLACE AGGREGATE _timescaledb_internal.finalize_agg(agg_name TEXT, inner_agg_collation_schema NAME, inner_agg_collation_name NAME, inner_agg_input_types NAME[][], inner_agg_serialized_state BYTEA, return_type_dummy_val anyelement) ( + SFUNC = _timescaledb_internal.finalize_agg_sfunc, + STYPE = internal, + FINALFUNC = _timescaledb_internal.finalize_agg_ffunc, + FINALFUNC_EXTRA +);