mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-16 10:33:27 +08:00
Add support for multiple extension version in one pg instance
This PR adds the ability to have multiple different versions of the timescaledb extension be used by different databases in the same PostgreSQL instance (server). This is accomplished by splitting this extension into two .so files. 1) timescaledb.so -- stuff under loader/. Really not a lot of code. This code MUST be backwards compatible in the future. 2) timescaledb-version.so (most of our code). Need not be backwards compatible. Timescaledb.so becomes a small stub which is preloaded and whose main reason for existing is to dynamically load the right timescaledb-version.so when the time comes. This change allows either of the above .so to be loaded in shared_preload_libraries. But timescaledb.so allows for multiple versions used on different databases in the same instance along with smoother upgrades. Using timescaledb-version.so allows for finer-grained control and lock-in and is appropriate in only a few production environments. This PR also adds version checking so that a clear failure message will be displayed if the .so version does not match the SQL extension version. To support multi-version functionality we changed the way SQL update scripts are generated. Previously, the system used a bunch of intermediate upgrade scripts. So with 3 versions, you would have an update script of 1--2, 2--3. But, this PR changes things so that we produce direct "shortcut" update files: 1--3, 2--3. This is done for 2 reasons: 1) Each of the update files should point to $libdir/timescaledb-current_version. Since you cannot guarantee that Previous .so for each intermediate version has been installed. 2) You don't want intermediate version updates installed without the .so. For example, if you have versions 1,2,3 and you are installing version 3, you want the upgrade files 1--3, 2--3 but not 1--2 because if you have 1--2 then a user could do ALTER EXTENSION timescaledb UPDATE TO 2. But the .so for version 2 may not be installed. In order to test this functionality, we add a mock extension version .so that we can test extension loading inside the regression framework.
This commit is contained in:
parent
e8eabf4278
commit
da8cc797a4
CMakeLists.txttimescaledb.control.in
sql
CMakeLists.txtbookend.sqlcache_functions.sqlchunk.sqlddl_internal.sqlddl_triggers.sqlhistogram.sqlpartitioning.sqltime_bucket.sqltimescaledb--0.1.0--0.2.0.sqltimescaledb--0.2.0--0.3.0.sqltimescaledb--0.3.0--0.4.0.sqltimescaledb--0.4.0--0.4.1.sqltimescaledb--0.4.1--0.4.2.sqltimescaledb--0.4.2--0.5.0.sqltimescaledb--0.5.0--0.6.0.sqltimescaledb--0.6.0--0.6.1.sqltimescaledb--0.6.1--0.7.0.sqltimescaledb--0.6.1--0.7.1.sqltimescaledb--0.7.0--0.7.1.sqltimescaledb--0.7.1--0.8.0.sql
updates
util_internal_table_ddl.sqlutil_time.sqlversion.sqlsrc
test
expected
loader-mock
CMakeLists.txt
runner.shsql
CMakeLists.txttimescaledb--mock-1--mock-2.sqltimescaledb--mock-1.sqltimescaledb--mock-2--mock-3.sqltimescaledb--mock-2.sqltimescaledb--mock-3--mock-4.sqltimescaledb--mock-3.sqltimescaledb--mock-4.sqltimescaledb--mock-5--mock-6.sqltimescaledb--mock-5.sqltimescaledb--mock-6.sqltimescaledb--mock-broken--mock-5.sqltimescaledb--mock-broken.sql
src
sql
@ -1,5 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
|
||||
configure_file("version.config" "version.config" COPYONLY)
|
||||
file(READ version.config VERSION_CONFIG)
|
||||
set(VERSION_REGEX "version[\t ]*=[\t ]*([0-9]+\\.[0-9]+\\.*[0-9]*)([-]([a-z]+))*\r?\nupdate_from_version[\t ]*=[\t ]*([0-9]+\\.[0-9]+\\.*[0-9]*)(\r?\n)*$")
|
||||
|
||||
|
@ -22,7 +22,8 @@ set(SQL_FILES
|
||||
cache_functions.sql
|
||||
size_utils.sql
|
||||
histogram.sql
|
||||
cache.sql)
|
||||
cache.sql
|
||||
)
|
||||
|
||||
set(EXT_SQL_EXTRA_FILES
|
||||
timescaledb--0.1.0--0.2.0.sql
|
||||
@ -33,48 +34,116 @@ set(EXT_SQL_EXTRA_FILES
|
||||
timescaledb--0.4.2--0.5.0.sql
|
||||
timescaledb--0.5.0--0.6.0.sql
|
||||
timescaledb--0.6.0--0.6.1.sql
|
||||
timescaledb--0.6.1--0.7.0.sql
|
||||
timescaledb--0.6.1--0.7.1.sql
|
||||
timescaledb--0.7.0--0.7.1.sql
|
||||
timescaledb--0.7.1--0.8.0.sql)
|
||||
timescaledb--0.7.1--0.8.0.sql
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
# Make list of files into string of files separated by "+"
|
||||
# to make Windows copy concatenate them
|
||||
string(REPLACE ";" ";+" SQL_FILES_JOINED "${SQL_FILES}")
|
||||
# Windows copy command requires backslashes for relative paths
|
||||
string(REPLACE "/" "\\" EXT_SQL_UPDATE_PRE_FILE "${EXT_SQL_UPDATE_PRE_FILE}")
|
||||
string(REPLACE "/" "\\" EXT_SQL_UPDATE_POST_FILE "${EXT_SQL_UPDATE_POST_FILE}")
|
||||
#TODO handle these manually.
|
||||
set(EXT_SQL_SPECIAL_FILES
|
||||
timescaledb--0.6.1--0.7.0.sql
|
||||
timescaledb--0.7.0--0.7.1.sql
|
||||
)
|
||||
|
||||
set(CAT_SQL_FILE_CMD copy /B /y ${SQL_FILES_JOINED} "\"${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_FILE}\"" >NUL)
|
||||
set(CAT_SQL_UPDATE_FILE_CMD copy /B /y ${EXT_SQL_UPDATE_PRE_FILE} + ${SQL_FILES_JOINED} + ${EXT_SQL_UPDATE_POST_FILE} "\"${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_UPDATE_FILE}\"" >NUL)
|
||||
else ()
|
||||
set(CAT_SQL_FILE_CMD cat ${SQL_FILES} > ${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_FILE})
|
||||
set(CAT_SQL_UPDATE_FILE_CMD cat ${EXT_SQL_UPDATE_PRE_FILE} ${SQL_FILES} ${EXT_SQL_UPDATE_POST_FILE} > ${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_UPDATE_FILE})
|
||||
endif ()
|
||||
set(EXT_SQL_UPDATE_PRE_GLOBAL_FILE updates/pre-global.sql)
|
||||
set(EXT_SQL_UPDATE_POST_GLOBAL_FILE updates/post-global.sql)
|
||||
set(UPDATE_FILE_LIST ${EXT_SQL_UPDATE_PRE_GLOBAL_FILE} ${EXT_SQL_UPDATE_PRE_FILE} ${SQL_FILES} ${EXT_SQL_UPDATE_POST_FILE} ${EXT_SQL_UPDATE_POST_GLOBAL_FILE})
|
||||
|
||||
# Command and target for the SQL file
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_FILE}
|
||||
DEPENDS ${SQL_FILES}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMAND ${CAT_SQL_FILE_CMD}
|
||||
COMMENT "Generating ${EXT_SQL_FILE}")
|
||||
#replace MODULE PATHNAME for files making up EXT_SQL_FILE (timescaledb--version.sql) and EXT_SQL_UPDATE_FILE (timescaledb--previous_version--version.sql)
|
||||
set(MODULE_PATHNAME "$libdir/timescaledb-${PROJECT_VERSION_MOD}")
|
||||
set(UPDATE_FILE_LIST_VERSIONED "")
|
||||
set(SQL_FILES_VERSIONED "")
|
||||
foreach(update_file ${UPDATE_FILE_LIST})
|
||||
set(update_file_versioned ${update_file}.${PROJECT_VERSION_MOD})
|
||||
configure_file(${update_file} ${update_file_versioned} @ONLY)
|
||||
list(APPEND UPDATE_FILE_LIST_VERSIONED ${CMAKE_CURRENT_BINARY_DIR}/${update_file_versioned})
|
||||
if (${update_file} IN_LIST SQL_FILES)
|
||||
list(APPEND SQL_FILES_VERSIONED ${CMAKE_CURRENT_BINARY_DIR}/${update_file_versioned})
|
||||
endif()
|
||||
endforeach(update_file)
|
||||
|
||||
#function to concatenate all files in SRC_FILE_LIST into file OUTPUT_FILE
|
||||
function(cat_files SRC_FILE_LIST OUTPUT_FILE)
|
||||
if (WIN32)
|
||||
# Make list of files into string of files separated by "+"
|
||||
# to make Windows copy concatenate them
|
||||
|
||||
file(TO_NATIVE_PATH "${SRC_FILE_LIST}" SRC_FILE_LIST_NATIVE)
|
||||
string(REPLACE ";" ";+" SQL_LIST_JOINED "${SRC_FILE_LIST_NATIVE}")
|
||||
|
||||
file(TO_NATIVE_PATH "${OUTPUT_FILE}" OUTPUT_FILE_NATIVE)
|
||||
|
||||
set(CAT_CMD copy /B /y ${SQL_LIST_JOINED} "\"${OUTPUT_FILE_NATIVE}\"" >NUL)
|
||||
else ()
|
||||
set(CAT_CMD cat ${SRC_FILE_LIST} > ${OUTPUT_FILE})
|
||||
endif ()
|
||||
add_custom_command(
|
||||
OUTPUT ${OUTPUT_FILE}
|
||||
DEPENDS ${SRC_FILE_LIST}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMAND ${CAT_CMD}
|
||||
COMMENT "Generating ${OUTPUT_FILE}"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
cat_files("${SQL_FILES_VERSIONED}" ${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_FILE})
|
||||
add_custom_target(sqlfile ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_FILE})
|
||||
|
||||
# Command and target for the update SQL file
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_UPDATE_FILE}
|
||||
DEPENDS ${SQL_FILES} ${EXT_SQL_UPDATE_PRE_FILE} ${EXT_SQL_UPDATE_POST_FILE}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMAND ${CAT_SQL_UPDATE_FILE_CMD}
|
||||
COMMENT "Generating ${EXT_SQL_UPDATE_FILE}")
|
||||
cat_files("${UPDATE_FILE_LIST_VERSIONED}" ${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_UPDATE_FILE})
|
||||
add_custom_target(sqlupdatefile ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_UPDATE_FILE})
|
||||
|
||||
add_custom_target(sqlupdatefile ALL DEPENDS ${EXT_SQL_UPDATE_FILE})
|
||||
#This generates the update file without MODULE_PATHNAME replaced. This file should be copied for the release.
|
||||
cat_files("${UPDATE_FILE_LIST}" ${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_UPDATE_FILE}.release)
|
||||
add_custom_target(sqlreleaseupdate ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_UPDATE_FILE}.release)
|
||||
|
||||
#You want to create timescaledb-old_version--current_version for all possible old_versions.
|
||||
#This is done for 2 reasons:
|
||||
# 1) Each of the update files should point to $libdir/timescaledb-current_version. Since you cannot guarantee that
|
||||
# Previous .so for each intermediate version has been installed.
|
||||
# 2) You don't want intermediate version updates installed without the .so. For example, if you have versions 1,2,3
|
||||
# and you are installing version 3, you want the upgrade files 1--3, 2--3 but not 1--2 because if you have 1--2
|
||||
# then a user could do ALTER EXTENSION timescaledb UPDATE TO 2. But the .so for version 2 may not be installed.
|
||||
#
|
||||
# Note that we build these update files by concatenating intermediate files. So we should have the intermediate update
|
||||
# files of 1--2, 2--3. From these we build the actual update scripts 1--3, 2--3.
|
||||
|
||||
#replace MODULE_PATHNAME in all the intermediate update files to point to $libdir/timescaledb-current_version
|
||||
#note that intermediate update files are never installed/packaged. Rather, they are only used to build the
|
||||
#update scripts below.
|
||||
set(INTERMEDIATE_UPDATE_VERSIONED "")
|
||||
foreach(intermediate_update_file ${EXT_SQL_EXTRA_FILES})
|
||||
set(intermediate_update_file_versioned ${intermediate_update_file}.${PROJECT_VERSION_MOD})
|
||||
configure_file(${intermediate_update_file} ${intermediate_update_file_versioned} @ONLY)
|
||||
list(APPEND INTERMEDIATE_UPDATE_VERSIONED ${CMAKE_CURRENT_BINARY_DIR}/${intermediate_update_file_versioned})
|
||||
endforeach(intermediate_update_file)
|
||||
|
||||
#we expect INTERMEDIATE_UPDATE_VERSIONED to be in order. For example, it should be 1--2, 2--3.
|
||||
set(INTERMEDIATE_FILE_REGEX "${CMAKE_CURRENT_BINARY_DIR}/timescaledb--([0-9]+\\.[0-9]+\\.*[0-9]*)--([0-9]+\\.[0-9]+\\.*[0-9]*).sql.${PROJECT_VERSION_MOD}")
|
||||
#build the actual update scripts for historic versions.
|
||||
set(PREVIOUS_UPDATE_SCRIPTS "")
|
||||
while(INTERMEDIATE_UPDATE_VERSIONED) #while list not empty
|
||||
#start with the first (oldest) file in the list and create an update for that version to current version
|
||||
list(GET INTERMEDIATE_UPDATE_VERSIONED 0 FIRST_INTERMEDIATE_FILE)
|
||||
if (NOT (${FIRST_INTERMEDIATE_FILE} MATCHES ${INTERMEDIATE_FILE_REGEX}))
|
||||
message(FATAL_ERROR "Cannot parse update file name ${FIRST_INTERMEDIATE_FILE}")
|
||||
endif ()
|
||||
|
||||
set(START_VERSION ${CMAKE_MATCH_1})
|
||||
set(PREV_UPDATE_FILE "${PROJECT_NAME}--${START_VERSION}--${PROJECT_VERSION_MOD}.sql")
|
||||
|
||||
#the files that go into this update are all the intermediate files + latest update
|
||||
set(UPDATE_FILES ${INTERMEDIATE_UPDATE_VERSIONED} ${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_UPDATE_FILE})
|
||||
|
||||
cat_files("${UPDATE_FILES}" ${CMAKE_CURRENT_BINARY_DIR}/${PREV_UPDATE_FILE})
|
||||
list(APPEND PREVIOUS_UPDATE_SCRIPTS ${CMAKE_CURRENT_BINARY_DIR}/${PREV_UPDATE_FILE})
|
||||
|
||||
#drop the head and start again
|
||||
list(REMOVE_AT INTERMEDIATE_UPDATE_VERSIONED 0)
|
||||
endwhile(INTERMEDIATE_UPDATE_VERSIONED)
|
||||
|
||||
add_custom_target(sqlprevupdatescripts ALL DEPENDS ${PREVIOUS_UPDATE_SCRIPTS})
|
||||
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_FILE}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${EXT_SQL_UPDATE_FILE}
|
||||
${EXT_SQL_EXTRA_FILES}
|
||||
${PREVIOUS_UPDATE_SCRIPTS}
|
||||
DESTINATION "${PG_SHAREDIR}/extension")
|
||||
|
@ -1,36 +1,36 @@
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_finalfunc(internal, anyelement, "any")
|
||||
RETURNS anyelement
|
||||
AS '$libdir/timescaledb', 'bookend_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_finalfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_serializefunc(internal)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'bookend_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_serializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'bookend_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
|
||||
|
@ -1,8 +1,9 @@
|
||||
-- this trigger function causes an invalidation event on the table whose name is
|
||||
-- passed in as the first element.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache_trigger()
|
||||
RETURNS TRIGGER AS '$libdir/timescaledb', 'invalidate_relcache_trigger' LANGUAGE C STRICT;
|
||||
RETURNS TRIGGER AS '@MODULE_PATHNAME@', 'invalidate_relcache_trigger' LANGUAGE C STRICT;
|
||||
|
||||
-- This function is only used for debugging
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache(catalog_table REGCLASS)
|
||||
RETURNS BOOLEAN AS '$libdir/timescaledb', 'invalidate_relcache' LANGUAGE C STRICT;
|
||||
RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'invalidate_relcache' LANGUAGE C STRICT;
|
||||
|
||||
|
@ -3,11 +3,11 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_ran
|
||||
interval_length BIGINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_range_closed(
|
||||
dimension_value BIGINT,
|
||||
num_slices SMALLINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
|
@ -23,7 +23,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.check_associated_schema_permissions(schema_name NAME, userid OID)
|
||||
RETURNS VOID AS '$libdir/timescaledb', 'hypertable_check_associated_schema_permissions' LANGUAGE C;
|
||||
RETURNS VOID AS '@MODULE_PATHNAME@', 'hypertable_check_associated_schema_permissions' LANGUAGE C;
|
||||
|
||||
-- Creates a hypertable row.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.create_hypertable(
|
||||
@ -543,7 +543,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.verify_hypertable_indexes(hypertable REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'indexing_verify_hypertable_indexes' LANGUAGE C STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'indexing_verify_hypertable_indexes' LANGUAGE C STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_change_owner(main_table OID, new_table_owner NAME)
|
||||
RETURNS void LANGUAGE plpgsql
|
||||
@ -572,20 +572,20 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.attach_tablespace(tablespace NAME, hypertable REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'tablespace_attach' LANGUAGE C VOLATILE;
|
||||
AS '@MODULE_PATHNAME@', 'tablespace_attach' LANGUAGE C VOLATILE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.detach_tablespace(tablespace NAME, hypertable REGCLASS) RETURNS INTEGER
|
||||
AS '$libdir/timescaledb', 'tablespace_detach' LANGUAGE C VOLATILE;
|
||||
AS '@MODULE_PATHNAME@', 'tablespace_detach' LANGUAGE C VOLATILE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.detach_tablespaces(hypertable REGCLASS) RETURNS INTEGER
|
||||
AS '$libdir/timescaledb', 'tablespace_detach_all_from_hypertable' LANGUAGE C VOLATILE;
|
||||
AS '@MODULE_PATHNAME@', 'tablespace_detach_all_from_hypertable' LANGUAGE C VOLATILE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.show_tablespaces(hypertable REGCLASS) RETURNS SETOF NAME
|
||||
AS '$libdir/timescaledb', 'tablespace_show' LANGUAGE C VOLATILE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'tablespace_show' LANGUAGE C VOLATILE STRICT;
|
||||
|
||||
--documentation of these function located in chunk_index.h
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_index_clone(chunk_index_oid OID) RETURNS OID
|
||||
AS '$libdir/timescaledb', 'chunk_index_clone' LANGUAGE C VOLATILE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'chunk_index_clone' LANGUAGE C VOLATILE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_index_replace(chunk_index_oid_old OID, chunk_index_oid_new OID) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'chunk_index_replace' LANGUAGE C VOLATILE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'chunk_index_replace' LANGUAGE C VOLATILE STRICT;
|
||||
|
@ -1,6 +1,8 @@
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_command_end() RETURNS event_trigger
|
||||
AS '$libdir/timescaledb', 'timescaledb_ddl_command_end' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@', 'timescaledb_ddl_command_end' LANGUAGE C;
|
||||
|
||||
DROP EVENT TRIGGER IF EXISTS timescaledb_ddl_command_end;
|
||||
--EVENT TRIGGER MUST exclude the ALTER EXTENSION tag.
|
||||
CREATE EVENT TRIGGER timescaledb_ddl_command_end ON ddl_command_end
|
||||
WHEN TAG IN ('ALTER TABLE','CREATE TRIGGER','CREATE TABLE','CREATE INDEX','ALTER INDEX')
|
||||
EXECUTE PROCEDURE _timescaledb_internal.ddl_command_end();
|
||||
|
@ -1,26 +1,26 @@
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_sfunc (state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_combinefunc(state1 INTERNAL, state2 INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_serializefunc(INTERNAL)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'hist_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_serializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_deserializefunc(bytea, INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_finalfunc(state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTEGER[]
|
||||
AS '$libdir/timescaledb', 'hist_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_finalfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- Tell Postgres how to use the new function
|
||||
|
@ -1,8 +1,9 @@
|
||||
-- Deprecated partition hash function
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val anyelement)
|
||||
RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_hash(val anyelement)
|
||||
RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_hash' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_hash' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
-- time_bucket returns the left edge of the bucket where ts falls into.
|
||||
-- Buckets span an interval of time equal to the bucket_width and are aligned with the epoch.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP) RETURNS TIMESTAMP
|
||||
AS '$libdir/timescaledb', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- bucketing of timestamptz happens at UTC time
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMPTZ) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
--bucketing on date should not do any timezone conversion
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts DATE) RETURNS DATE
|
||||
AS '$libdir/timescaledb', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- If an interval is given as the third argument, the bucket alignment is offset by the interval.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP, "offset" INTERVAL)
|
||||
|
@ -523,16 +523,16 @@ $BODY$
|
||||
$BODY$;
|
||||
-- This file contains utilities for time conversion.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_unix_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp(unixtime_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp_pg(postgres_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
|
||||
@ -1160,10 +1160,10 @@ $BODY$;
|
||||
|
||||
-- These trigger functions intercept regular inserts and implement our smart insert fastpath
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.main_table_insert_trigger() RETURNS TRIGGER
|
||||
AS '$libdir/timescaledb', 'insert_main_table_trigger' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@', 'insert_main_table_trigger' LANGUAGE C;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.main_table_after_insert_trigger() RETURNS TRIGGER
|
||||
AS '$libdir/timescaledb', 'insert_main_table_trigger_after' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@', 'insert_main_table_trigger_after' LANGUAGE C;
|
||||
|
||||
-- Adds the above triggers to the main table when a hypertable is created.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.on_change_hypertable()
|
||||
@ -1269,7 +1269,7 @@ $BODY$;
|
||||
-- our default partitioning function.
|
||||
-- returns a hash of val modulous the mod_factor
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val text) RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- This file contains functions related to getting information about the
|
||||
-- schema of a hypertable, including columns, their types, etc.
|
||||
|
||||
@ -1801,11 +1801,11 @@ $BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_is_change_owner(pg_ddl_command)
|
||||
RETURNS bool IMMUTABLE STRICT
|
||||
AS '$libdir/timescaledb' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@' LANGUAGE C;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_change_owner_to(pg_ddl_command)
|
||||
RETURNS name IMMUTABLE STRICT
|
||||
AS '$libdir/timescaledb' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@' LANGUAGE C;
|
||||
|
||||
-- Handles ddl create index commands on hypertables
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_process_create_index()
|
||||
@ -2118,37 +2118,37 @@ END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_finalfunc(internal, anyelement, "any")
|
||||
RETURNS anyelement
|
||||
AS '$libdir/timescaledb', 'bookend_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_finalfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_serializefunc(internal)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'bookend_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_serializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'bookend_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
|
||||
@ -2183,11 +2183,11 @@ CREATE AGGREGATE last(anyelement, "any") (
|
||||
-- time_bucket returns the left edge of the bucket where ts falls into.
|
||||
-- Buckets span an interval of time equal to the bucket_width and are aligned with the epoch.
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMP) RETURNS TIMESTAMP
|
||||
AS '$libdir/timescaledb', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- bucketing of timestamptz happens at UTC time
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMPTZ) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- If an interval is given as the third argument, the bucket alignment is offset by the interval.
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMP, "offset" INTERVAL)
|
||||
@ -2240,15 +2240,15 @@ $BODY$;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_git_commit() RETURNS TEXT
|
||||
AS '$libdir/timescaledb', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- this trigger function causes an invalidation event on the table whose name is
|
||||
-- passed in as the first element.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache_trigger()
|
||||
RETURNS TRIGGER AS '$libdir/timescaledb', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
RETURNS TRIGGER AS '@MODULE_PATHNAME@', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
|
||||
-- This function is only used for debugging
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache(proxy_oid OID)
|
||||
RETURNS BOOLEAN AS '$libdir/timescaledb', 'invalidate_relcache' LANGUAGE C;
|
||||
RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'invalidate_relcache' LANGUAGE C;
|
||||
|
||||
|
||||
|
||||
|
@ -510,16 +510,16 @@ END
|
||||
$BODY$;
|
||||
-- This file contains utilities for time conversion.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_unix_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp(unixtime_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp_pg(postgres_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
|
||||
@ -1232,7 +1232,7 @@ $BODY$;
|
||||
-- our default partitioning function.
|
||||
-- returns a hash of val modulous the mod_factor
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val text) RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- This file contains functions related to getting information about the
|
||||
-- schema of a hypertable, including columns, their types, etc.
|
||||
|
||||
@ -1764,11 +1764,11 @@ $BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_is_change_owner(pg_ddl_command)
|
||||
RETURNS bool IMMUTABLE STRICT
|
||||
AS '$libdir/timescaledb' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@' LANGUAGE C;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_change_owner_to(pg_ddl_command)
|
||||
RETURNS name IMMUTABLE STRICT
|
||||
AS '$libdir/timescaledb' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@' LANGUAGE C;
|
||||
|
||||
-- Handles ddl create index commands on hypertables
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_process_create_index()
|
||||
@ -2079,37 +2079,37 @@ END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_finalfunc(internal, anyelement, "any")
|
||||
RETURNS anyelement
|
||||
AS '$libdir/timescaledb', 'bookend_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_finalfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_serializefunc(internal)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'bookend_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_serializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'bookend_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
|
||||
@ -2144,11 +2144,11 @@ CREATE AGGREGATE last(anyelement, "any") (
|
||||
-- time_bucket returns the left edge of the bucket where ts falls into.
|
||||
-- Buckets span an interval of time equal to the bucket_width and are aligned with the epoch.
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMP) RETURNS TIMESTAMP
|
||||
AS '$libdir/timescaledb', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- bucketing of timestamptz happens at UTC time
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMPTZ) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- If an interval is given as the third argument, the bucket alignment is offset by the interval.
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMP, "offset" INTERVAL)
|
||||
@ -2201,15 +2201,15 @@ $BODY$;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_git_commit() RETURNS TEXT
|
||||
AS '$libdir/timescaledb', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- this trigger function causes an invalidation event on the table whose name is
|
||||
-- passed in as the first element.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache_trigger()
|
||||
RETURNS TRIGGER AS '$libdir/timescaledb', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
RETURNS TRIGGER AS '@MODULE_PATHNAME@', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
|
||||
-- This function is only used for debugging
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache(proxy_oid OID)
|
||||
RETURNS BOOLEAN AS '$libdir/timescaledb', 'invalidate_relcache' LANGUAGE C;
|
||||
RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'invalidate_relcache' LANGUAGE C;
|
||||
|
||||
|
||||
|
||||
|
@ -514,16 +514,16 @@ END
|
||||
$BODY$;
|
||||
-- This file contains utilities for time conversion.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_unix_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp(unixtime_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp_pg(postgres_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
|
||||
@ -1245,7 +1245,7 @@ $BODY$;
|
||||
-- our default partitioning function.
|
||||
-- returns a hash of val modulous the mod_factor
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val text) RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- This file contains functions related to getting information about the
|
||||
-- schema of a hypertable, including columns, their types, etc.
|
||||
|
||||
@ -1805,11 +1805,11 @@ $BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_is_change_owner(pg_ddl_command)
|
||||
RETURNS bool IMMUTABLE STRICT
|
||||
AS '$libdir/timescaledb' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@' LANGUAGE C;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_change_owner_to(pg_ddl_command)
|
||||
RETURNS name IMMUTABLE STRICT
|
||||
AS '$libdir/timescaledb' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@' LANGUAGE C;
|
||||
|
||||
-- Handles ddl create index commands on hypertables
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_process_create_index()
|
||||
@ -2120,37 +2120,37 @@ END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_finalfunc(internal, anyelement, "any")
|
||||
RETURNS anyelement
|
||||
AS '$libdir/timescaledb', 'bookend_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_finalfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_serializefunc(internal)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'bookend_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_serializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'bookend_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
|
||||
@ -2185,11 +2185,11 @@ CREATE AGGREGATE last(anyelement, "any") (
|
||||
-- time_bucket returns the left edge of the bucket where ts falls into.
|
||||
-- Buckets span an interval of time equal to the bucket_width and are aligned with the epoch.
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMP) RETURNS TIMESTAMP
|
||||
AS '$libdir/timescaledb', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- bucketing of timestamptz happens at UTC time
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMPTZ) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- If an interval is given as the third argument, the bucket alignment is offset by the interval.
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMP, "offset" INTERVAL)
|
||||
@ -2242,15 +2242,15 @@ $BODY$;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_git_commit() RETURNS TEXT
|
||||
AS '$libdir/timescaledb', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- this trigger function causes an invalidation event on the table whose name is
|
||||
-- passed in as the first element.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache_trigger()
|
||||
RETURNS TRIGGER AS '$libdir/timescaledb', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
RETURNS TRIGGER AS '@MODULE_PATHNAME@', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
|
||||
-- This function is only used for debugging
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache(proxy_oid OID)
|
||||
RETURNS BOOLEAN AS '$libdir/timescaledb', 'invalidate_relcache' LANGUAGE C;
|
||||
RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'invalidate_relcache' LANGUAGE C;
|
||||
|
||||
|
||||
|
||||
|
@ -511,16 +511,16 @@ END
|
||||
$BODY$;
|
||||
-- This file contains utilities for time conversion.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_unix_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp(unixtime_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp_pg(postgres_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
|
||||
@ -1278,7 +1278,7 @@ $BODY$;
|
||||
-- our default partitioning function.
|
||||
-- returns a hash of val modulous the mod_factor
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val text) RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- This file contains functions related to getting information about the
|
||||
-- schema of a hypertable, including columns, their types, etc.
|
||||
|
||||
@ -1838,11 +1838,11 @@ $BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_is_change_owner(pg_ddl_command)
|
||||
RETURNS bool IMMUTABLE STRICT
|
||||
AS '$libdir/timescaledb' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@' LANGUAGE C;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_change_owner_to(pg_ddl_command)
|
||||
RETURNS name IMMUTABLE STRICT
|
||||
AS '$libdir/timescaledb' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@' LANGUAGE C;
|
||||
|
||||
-- Handles ddl create index commands on hypertables
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_process_create_index()
|
||||
@ -2153,37 +2153,37 @@ END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_finalfunc(internal, anyelement, "any")
|
||||
RETURNS anyelement
|
||||
AS '$libdir/timescaledb', 'bookend_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_finalfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_serializefunc(internal)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'bookend_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_serializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'bookend_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
|
||||
@ -2218,15 +2218,15 @@ CREATE AGGREGATE last(anyelement, "any") (
|
||||
-- time_bucket returns the left edge of the bucket where ts falls into.
|
||||
-- Buckets span an interval of time equal to the bucket_width and are aligned with the epoch.
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMP) RETURNS TIMESTAMP
|
||||
AS '$libdir/timescaledb', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- bucketing of timestamptz happens at UTC time
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMPTZ) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
--bucketing on date should not do any timezone conversion
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts DATE) RETURNS DATE
|
||||
AS '$libdir/timescaledb', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- If an interval is given as the third argument, the bucket alignment is offset by the interval.
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMP, "offset" INTERVAL)
|
||||
@ -2286,15 +2286,15 @@ $BODY$;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_git_commit() RETURNS TEXT
|
||||
AS '$libdir/timescaledb', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- this trigger function causes an invalidation event on the table whose name is
|
||||
-- passed in as the first element.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache_trigger()
|
||||
RETURNS TRIGGER AS '$libdir/timescaledb', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
RETURNS TRIGGER AS '@MODULE_PATHNAME@', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
|
||||
-- This function is only used for debugging
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache(proxy_oid OID)
|
||||
RETURNS BOOLEAN AS '$libdir/timescaledb', 'invalidate_relcache' LANGUAGE C;
|
||||
RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'invalidate_relcache' LANGUAGE C;
|
||||
|
||||
|
||||
|
||||
|
@ -511,16 +511,16 @@ END
|
||||
$BODY$;
|
||||
-- This file contains utilities for time conversion.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_unix_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp(unixtime_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp_pg(postgres_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
|
||||
@ -1344,7 +1344,7 @@ $BODY$;
|
||||
-- our default partitioning function.
|
||||
-- returns a hash of val modulous the mod_factor
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val text) RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- This file contains functions related to getting information about the
|
||||
-- schema of a hypertable, including columns, their types, etc.
|
||||
|
||||
@ -1904,11 +1904,11 @@ $BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_is_change_owner(pg_ddl_command)
|
||||
RETURNS bool IMMUTABLE STRICT
|
||||
AS '$libdir/timescaledb' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@' LANGUAGE C;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_change_owner_to(pg_ddl_command)
|
||||
RETURNS name IMMUTABLE STRICT
|
||||
AS '$libdir/timescaledb' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@' LANGUAGE C;
|
||||
|
||||
-- Handles ddl create index commands on hypertables
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_process_create_index()
|
||||
@ -2219,37 +2219,37 @@ END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_finalfunc(internal, anyelement, "any")
|
||||
RETURNS anyelement
|
||||
AS '$libdir/timescaledb', 'bookend_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_finalfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_serializefunc(internal)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'bookend_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_serializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'bookend_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
|
||||
@ -2284,15 +2284,15 @@ CREATE AGGREGATE last(anyelement, "any") (
|
||||
-- time_bucket returns the left edge of the bucket where ts falls into.
|
||||
-- Buckets span an interval of time equal to the bucket_width and are aligned with the epoch.
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMP) RETURNS TIMESTAMP
|
||||
AS '$libdir/timescaledb', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- bucketing of timestamptz happens at UTC time
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMPTZ) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
--bucketing on date should not do any timezone conversion
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts DATE) RETURNS DATE
|
||||
AS '$libdir/timescaledb', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- If an interval is given as the third argument, the bucket alignment is offset by the interval.
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMP, "offset" INTERVAL)
|
||||
@ -2352,15 +2352,15 @@ $BODY$;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_git_commit() RETURNS TEXT
|
||||
AS '$libdir/timescaledb', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- this trigger function causes an invalidation event on the table whose name is
|
||||
-- passed in as the first element.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache_trigger()
|
||||
RETURNS TRIGGER AS '$libdir/timescaledb', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
RETURNS TRIGGER AS '@MODULE_PATHNAME@', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
|
||||
-- This function is only used for debugging
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache(proxy_oid OID)
|
||||
RETURNS BOOLEAN AS '$libdir/timescaledb', 'invalidate_relcache' LANGUAGE C;
|
||||
RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'invalidate_relcache' LANGUAGE C;
|
||||
|
||||
|
||||
|
||||
|
@ -72,14 +72,14 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_ran
|
||||
interval_length BIGINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_range_closed(
|
||||
dimension_value BIGINT,
|
||||
num_slices SMALLINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.drop_chunk(
|
||||
chunk_id int,
|
||||
@ -693,16 +693,16 @@ END
|
||||
$BODY$;
|
||||
-- This file contains utilities for time conversion.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_unix_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp(unixtime_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp_pg(postgres_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
|
||||
@ -1264,7 +1264,7 @@ $BODY$;
|
||||
-- our default partitioning function.
|
||||
-- returns a hash of val modulous the mod_factor
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val text) RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- This file contains functions related to getting information about the
|
||||
-- schema of a hypertable, including columns, their types, etc.
|
||||
|
||||
@ -2029,37 +2029,37 @@ END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_finalfunc(internal, anyelement, "any")
|
||||
RETURNS anyelement
|
||||
AS '$libdir/timescaledb', 'bookend_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_finalfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_serializefunc(internal)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'bookend_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_serializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'bookend_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
|
||||
@ -2094,15 +2094,15 @@ CREATE AGGREGATE last(anyelement, "any") (
|
||||
-- time_bucket returns the left edge of the bucket where ts falls into.
|
||||
-- Buckets span an interval of time equal to the bucket_width and are aligned with the epoch.
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMP) RETURNS TIMESTAMP
|
||||
AS '$libdir/timescaledb', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- bucketing of timestamptz happens at UTC time
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMPTZ) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
--bucketing on date should not do any timezone conversion
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts DATE) RETURNS DATE
|
||||
AS '$libdir/timescaledb', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- If an interval is given as the third argument, the bucket alignment is offset by the interval.
|
||||
CREATE OR REPLACE FUNCTION public.time_bucket(bucket_width INTERVAL, ts TIMESTAMP, "offset" INTERVAL)
|
||||
@ -2162,15 +2162,15 @@ $BODY$;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_git_commit() RETURNS TEXT
|
||||
AS '$libdir/timescaledb', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- this trigger function causes an invalidation event on the table whose name is
|
||||
-- passed in as the first element.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache_trigger()
|
||||
RETURNS TRIGGER AS '$libdir/timescaledb', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
RETURNS TRIGGER AS '@MODULE_PATHNAME@', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
|
||||
-- This function is only used for debugging
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache(proxy_oid OID)
|
||||
RETURNS BOOLEAN AS '$libdir/timescaledb', 'invalidate_relcache' LANGUAGE C;
|
||||
RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'invalidate_relcache' LANGUAGE C;
|
||||
|
||||
|
||||
|
||||
@ -2590,27 +2590,27 @@ END;
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_sfunc (state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_combinefunc(state1 INTERNAL, state2 INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_serializefunc(INTERNAL)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'hist_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_serializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_deserializefunc(bytea, INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_finalfunc(state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTEGER[]
|
||||
AS '$libdir/timescaledb', 'hist_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_finalfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
-- Tell Postgres how to use the new function
|
||||
|
@ -222,14 +222,14 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_ran
|
||||
interval_length BIGINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_range_closed(
|
||||
dimension_value BIGINT,
|
||||
num_slices SMALLINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.drop_chunk_metadata(
|
||||
chunk_id int
|
||||
@ -775,7 +775,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.verify_hypertable_indexes(hypertable REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'indexing_verify_hypertable_indexes' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'indexing_verify_hypertable_indexes' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_change_owner(main_table OID, new_table_owner NAME)
|
||||
RETURNS void LANGUAGE plpgsql
|
||||
@ -804,16 +804,16 @@ END
|
||||
$BODY$;
|
||||
-- This file contains utilities for time conversion.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_unix_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp(unixtime_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp_pg(postgres_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
|
||||
@ -1277,7 +1277,7 @@ $BODY$;
|
||||
-- our default partitioning function.
|
||||
-- returns a hash of val modulous the mod_factor
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val text) RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- This file contains functions related to getting information about the
|
||||
-- schema of a hypertable, including columns, their types, etc.
|
||||
|
||||
@ -1678,7 +1678,7 @@ BEGIN
|
||||
END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_command_end() RETURNS event_trigger
|
||||
AS '$libdir/timescaledb', 'timescaledb_ddl_command_end' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'timescaledb_ddl_command_end' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE EVENT TRIGGER timescaledb_ddl_command_end ON ddl_command_end
|
||||
EXECUTE PROCEDURE _timescaledb_internal.ddl_command_end();
|
||||
@ -1805,37 +1805,37 @@ END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_finalfunc(internal, anyelement, "any")
|
||||
RETURNS anyelement
|
||||
AS '$libdir/timescaledb', 'bookend_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_finalfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_serializefunc(internal)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'bookend_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_serializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'bookend_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
|
||||
@ -1870,15 +1870,15 @@ CREATE AGGREGATE last(anyelement, "any") (
|
||||
-- time_bucket returns the left edge of the bucket where ts falls into.
|
||||
-- Buckets span an interval of time equal to the bucket_width and are aligned with the epoch.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP) RETURNS TIMESTAMP
|
||||
AS '$libdir/timescaledb', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- bucketing of timestamptz happens at UTC time
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMPTZ) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
--bucketing on date should not do any timezone conversion
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts DATE) RETURNS DATE
|
||||
AS '$libdir/timescaledb', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- If an interval is given as the third argument, the bucket alignment is offset by the interval.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP, "offset" INTERVAL)
|
||||
@ -1936,15 +1936,15 @@ $BODY$
|
||||
SELECT (((ts-"offset") / bucket_width)*bucket_width)+"offset";
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_git_commit() RETURNS TEXT
|
||||
AS '$libdir/timescaledb', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- this trigger function causes an invalidation event on the table whose name is
|
||||
-- passed in as the first element.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache_trigger()
|
||||
RETURNS TRIGGER AS '$libdir/timescaledb', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
RETURNS TRIGGER AS '@MODULE_PATHNAME@', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
|
||||
-- This function is only used for debugging
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache(proxy_oid OID)
|
||||
RETURNS BOOLEAN AS '$libdir/timescaledb', 'invalidate_relcache' LANGUAGE C;
|
||||
RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'invalidate_relcache' LANGUAGE C;
|
||||
|
||||
|
||||
-- This file contains utility functions to get the relation size
|
||||
@ -2364,27 +2364,27 @@ END;
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_sfunc (state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_combinefunc(state1 INTERNAL, state2 INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_serializefunc(INTERNAL)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'hist_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_serializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_deserializefunc(bytea, INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_finalfunc(state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTEGER[]
|
||||
AS '$libdir/timescaledb', 'hist_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_finalfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
-- Tell Postgres how to use the new function
|
||||
|
@ -164,14 +164,14 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_ran
|
||||
interval_length BIGINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_range_closed(
|
||||
dimension_value BIGINT,
|
||||
num_slices SMALLINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.drop_chunk_metadata(
|
||||
chunk_id int
|
||||
@ -717,7 +717,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.verify_hypertable_indexes(hypertable REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'indexing_verify_hypertable_indexes' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'indexing_verify_hypertable_indexes' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_change_owner(main_table OID, new_table_owner NAME)
|
||||
RETURNS void LANGUAGE plpgsql
|
||||
@ -746,16 +746,16 @@ END
|
||||
$BODY$;
|
||||
-- This file contains utilities for time conversion.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_unix_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp(unixtime_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp_pg(postgres_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
|
||||
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
|
||||
@ -1219,7 +1219,7 @@ $BODY$;
|
||||
-- our default partitioning function.
|
||||
-- returns a hash of val modulous the mod_factor
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val text) RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- This file contains functions related to getting information about the
|
||||
-- schema of a hypertable, including columns, their types, etc.
|
||||
|
||||
@ -1620,7 +1620,7 @@ BEGIN
|
||||
END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_command_end() RETURNS event_trigger
|
||||
AS '$libdir/timescaledb', 'timescaledb_ddl_command_end' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'timescaledb_ddl_command_end' LANGUAGE C IMMUTABLE STRICT;
|
||||
|
||||
DROP EVENT TRIGGER IF EXISTS timescaledb_ddl_command_end;
|
||||
CREATE EVENT TRIGGER timescaledb_ddl_command_end ON ddl_command_end
|
||||
@ -1748,37 +1748,37 @@ END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_finalfunc(internal, anyelement, "any")
|
||||
RETURNS anyelement
|
||||
AS '$libdir/timescaledb', 'bookend_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_finalfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_serializefunc(internal)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'bookend_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_serializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'bookend_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
|
||||
@ -1813,15 +1813,15 @@ CREATE AGGREGATE last(anyelement, "any") (
|
||||
-- time_bucket returns the left edge of the bucket where ts falls into.
|
||||
-- Buckets span an interval of time equal to the bucket_width and are aligned with the epoch.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP) RETURNS TIMESTAMP
|
||||
AS '$libdir/timescaledb', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- bucketing of timestamptz happens at UTC time
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMPTZ) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
--bucketing on date should not do any timezone conversion
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts DATE) RETURNS DATE
|
||||
AS '$libdir/timescaledb', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- If an interval is given as the third argument, the bucket alignment is offset by the interval.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP, "offset" INTERVAL)
|
||||
@ -1879,15 +1879,15 @@ $BODY$
|
||||
SELECT (((ts-"offset") / bucket_width)*bucket_width)+"offset";
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_git_commit() RETURNS TEXT
|
||||
AS '$libdir/timescaledb', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT;
|
||||
-- this trigger function causes an invalidation event on the table whose name is
|
||||
-- passed in as the first element.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache_trigger()
|
||||
RETURNS TRIGGER AS '$libdir/timescaledb', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
RETURNS TRIGGER AS '@MODULE_PATHNAME@', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
|
||||
-- This function is only used for debugging
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache(proxy_oid OID)
|
||||
RETURNS BOOLEAN AS '$libdir/timescaledb', 'invalidate_relcache' LANGUAGE C;
|
||||
RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'invalidate_relcache' LANGUAGE C;
|
||||
|
||||
|
||||
-- This file contains utility functions to get the relation size
|
||||
@ -2307,27 +2307,27 @@ END;
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_sfunc (state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_sfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_combinefunc(state1 INTERNAL, state2 INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_combinefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_serializefunc(INTERNAL)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'hist_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_serializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_deserializefunc(bytea, INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_finalfunc(state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTEGER[]
|
||||
AS '$libdir/timescaledb', 'hist_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_finalfunc'
|
||||
LANGUAGE C IMMUTABLE;
|
||||
|
||||
-- Tell Postgres how to use the new function
|
||||
|
@ -201,14 +201,14 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_ran
|
||||
interval_length BIGINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_range_closed(
|
||||
dimension_value BIGINT,
|
||||
num_slices SMALLINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.drop_chunk_metadata(
|
||||
chunk_id int
|
||||
@ -812,7 +812,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.verify_hypertable_indexes(hypertable REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'indexing_verify_hypertable_indexes' LANGUAGE C STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'indexing_verify_hypertable_indexes' LANGUAGE C STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_change_owner(main_table OID, new_table_owner NAME)
|
||||
RETURNS void LANGUAGE plpgsql
|
||||
@ -841,16 +841,16 @@ END
|
||||
$BODY$;
|
||||
-- This file contains utilities for time conversion.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_unix_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp(unixtime_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp_pg(postgres_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
|
||||
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
|
||||
@ -1193,7 +1193,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.validate_triggers(main_table REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'hypertable_validate_triggers' LANGUAGE C STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'hypertable_validate_triggers' LANGUAGE C STRICT;
|
||||
-- Creates a constraint on a chunk.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_constraint_add_table_constraint(
|
||||
chunk_constraint_row _timescaledb_catalog.chunk_constraint
|
||||
@ -1340,11 +1340,11 @@ $BODY$;
|
||||
-- Deprecated partition hash function
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val anyelement)
|
||||
RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_hash(val anyelement)
|
||||
RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_hash' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_hash' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
-- This file contains functions related to getting information about the
|
||||
-- schema of a hypertable, including columns, their types, etc.
|
||||
|
||||
@ -1752,7 +1752,7 @@ BEGIN
|
||||
END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_command_end() RETURNS event_trigger
|
||||
AS '$libdir/timescaledb', 'timescaledb_ddl_command_end' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@', 'timescaledb_ddl_command_end' LANGUAGE C;
|
||||
|
||||
DROP EVENT TRIGGER IF EXISTS timescaledb_ddl_command_end;
|
||||
CREATE EVENT TRIGGER timescaledb_ddl_command_end ON ddl_command_end
|
||||
@ -1880,37 +1880,37 @@ END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_finalfunc(internal, anyelement, "any")
|
||||
RETURNS anyelement
|
||||
AS '$libdir/timescaledb', 'bookend_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_finalfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_serializefunc(internal)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'bookend_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_serializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'bookend_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
|
||||
@ -1943,15 +1943,15 @@ CREATE AGGREGATE last(anyelement, "any") (
|
||||
-- time_bucket returns the left edge of the bucket where ts falls into.
|
||||
-- Buckets span an interval of time equal to the bucket_width and are aligned with the epoch.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP) RETURNS TIMESTAMP
|
||||
AS '$libdir/timescaledb', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- bucketing of timestamptz happens at UTC time
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMPTZ) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
--bucketing on date should not do any timezone conversion
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts DATE) RETURNS DATE
|
||||
AS '$libdir/timescaledb', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- If an interval is given as the third argument, the bucket alignment is offset by the interval.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP, "offset" INTERVAL)
|
||||
@ -2009,15 +2009,15 @@ $BODY$
|
||||
SELECT (((ts-"offset") / bucket_width)*bucket_width)+"offset";
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_git_commit() RETURNS TEXT
|
||||
AS '$libdir/timescaledb', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
-- this trigger function causes an invalidation event on the table whose name is
|
||||
-- passed in as the first element.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache_trigger()
|
||||
RETURNS TRIGGER AS '$libdir/timescaledb', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
RETURNS TRIGGER AS '@MODULE_PATHNAME@', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
|
||||
-- This function is only used for debugging
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache(proxy_oid OID)
|
||||
RETURNS BOOLEAN AS '$libdir/timescaledb', 'invalidate_relcache' LANGUAGE C;
|
||||
RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'invalidate_relcache' LANGUAGE C;
|
||||
|
||||
|
||||
-- This file contains utility functions to get the relation size
|
||||
@ -2440,27 +2440,27 @@ END;
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_sfunc (state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_combinefunc(state1 INTERNAL, state2 INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_serializefunc(INTERNAL)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'hist_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_serializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_deserializefunc(bytea, INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_finalfunc(state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTEGER[]
|
||||
AS '$libdir/timescaledb', 'hist_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_finalfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- Tell Postgres how to use the new function
|
||||
|
@ -210,14 +210,14 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_ran
|
||||
interval_length BIGINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_range_closed(
|
||||
dimension_value BIGINT,
|
||||
num_slices SMALLINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.drop_chunk_metadata(
|
||||
chunk_id int
|
||||
@ -821,7 +821,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.verify_hypertable_indexes(hypertable REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'indexing_verify_hypertable_indexes' LANGUAGE C STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'indexing_verify_hypertable_indexes' LANGUAGE C STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_change_owner(main_table OID, new_table_owner NAME)
|
||||
RETURNS void LANGUAGE plpgsql
|
||||
@ -850,16 +850,16 @@ END
|
||||
$BODY$;
|
||||
-- This file contains utilities for time conversion.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_unix_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp(unixtime_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp_pg(postgres_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
|
||||
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
|
||||
@ -1202,7 +1202,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.validate_triggers(main_table REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'hypertable_validate_triggers' LANGUAGE C STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'hypertable_validate_triggers' LANGUAGE C STRICT;
|
||||
-- Creates a constraint on a chunk.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_constraint_add_table_constraint(
|
||||
chunk_constraint_row _timescaledb_catalog.chunk_constraint
|
||||
@ -1349,11 +1349,11 @@ $BODY$;
|
||||
-- Deprecated partition hash function
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val anyelement)
|
||||
RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_hash(val anyelement)
|
||||
RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_hash' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_hash' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
-- This file contains functions related to getting information about the
|
||||
-- schema of a hypertable, including columns, their types, etc.
|
||||
|
||||
@ -1761,7 +1761,7 @@ BEGIN
|
||||
END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_command_end() RETURNS event_trigger
|
||||
AS '$libdir/timescaledb', 'timescaledb_ddl_command_end' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@', 'timescaledb_ddl_command_end' LANGUAGE C;
|
||||
|
||||
DROP EVENT TRIGGER IF EXISTS timescaledb_ddl_command_end;
|
||||
CREATE EVENT TRIGGER timescaledb_ddl_command_end ON ddl_command_end
|
||||
@ -1889,37 +1889,37 @@ END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_finalfunc(internal, anyelement, "any")
|
||||
RETURNS anyelement
|
||||
AS '$libdir/timescaledb', 'bookend_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_finalfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_serializefunc(internal)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'bookend_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_serializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'bookend_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
|
||||
@ -1952,15 +1952,15 @@ CREATE AGGREGATE last(anyelement, "any") (
|
||||
-- time_bucket returns the left edge of the bucket where ts falls into.
|
||||
-- Buckets span an interval of time equal to the bucket_width and are aligned with the epoch.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP) RETURNS TIMESTAMP
|
||||
AS '$libdir/timescaledb', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- bucketing of timestamptz happens at UTC time
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMPTZ) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
--bucketing on date should not do any timezone conversion
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts DATE) RETURNS DATE
|
||||
AS '$libdir/timescaledb', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- If an interval is given as the third argument, the bucket alignment is offset by the interval.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP, "offset" INTERVAL)
|
||||
@ -2018,15 +2018,15 @@ $BODY$
|
||||
SELECT (((ts-"offset") / bucket_width)*bucket_width)+"offset";
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_git_commit() RETURNS TEXT
|
||||
AS '$libdir/timescaledb', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
-- this trigger function causes an invalidation event on the table whose name is
|
||||
-- passed in as the first element.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache_trigger()
|
||||
RETURNS TRIGGER AS '$libdir/timescaledb', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
RETURNS TRIGGER AS '@MODULE_PATHNAME@', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
|
||||
-- This function is only used for debugging
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache(proxy_oid OID)
|
||||
RETURNS BOOLEAN AS '$libdir/timescaledb', 'invalidate_relcache' LANGUAGE C;
|
||||
RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'invalidate_relcache' LANGUAGE C;
|
||||
|
||||
|
||||
-- This file contains utility functions to get the relation size
|
||||
@ -2449,27 +2449,27 @@ END;
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_sfunc (state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_combinefunc(state1 INTERNAL, state2 INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_serializefunc(INTERNAL)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'hist_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_serializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_deserializefunc(bytea, INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_finalfunc(state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTEGER[]
|
||||
AS '$libdir/timescaledb', 'hist_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_finalfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- Tell Postgres how to use the new function
|
||||
@ -2752,14 +2752,14 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_ran
|
||||
interval_length BIGINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_range_closed(
|
||||
dimension_value BIGINT,
|
||||
num_slices SMALLINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.drop_chunk_metadata(
|
||||
chunk_id int
|
||||
@ -3406,7 +3406,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.verify_hypertable_indexes(hypertable REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'indexing_verify_hypertable_indexes' LANGUAGE C STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'indexing_verify_hypertable_indexes' LANGUAGE C STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_change_owner(main_table OID, new_table_owner NAME)
|
||||
RETURNS void LANGUAGE plpgsql
|
||||
@ -3437,22 +3437,22 @@ $BODY$;
|
||||
|
||||
--documentation of these function located in chunk_index.h
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_index_clone(chunk_index_oid OID) RETURNS OID
|
||||
AS '$libdir/timescaledb', 'chunk_index_clone' LANGUAGE C VOLATILE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'chunk_index_clone' LANGUAGE C VOLATILE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_index_replace(chunk_index_oid_old OID, chunk_index_oid_new OID) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'chunk_index_replace' LANGUAGE C VOLATILE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'chunk_index_replace' LANGUAGE C VOLATILE STRICT;
|
||||
-- This file contains utilities for time conversion.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_unix_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp(unixtime_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp_pg(postgres_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
|
||||
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
|
||||
@ -3546,7 +3546,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.time_to_internal(time_element anyelement, time_type REGTYPE) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'time_to_internal' LANGUAGE C IMMUTABLE PARALLEL SAFE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'time_to_internal' LANGUAGE C IMMUTABLE PARALLEL SAFE STRICT;
|
||||
-- This file contains functions associated with creating new
|
||||
-- hypertables.
|
||||
|
||||
@ -3798,7 +3798,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.validate_triggers(main_table REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'hypertable_validate_triggers' LANGUAGE C STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'hypertable_validate_triggers' LANGUAGE C STRICT;
|
||||
-- Creates a constraint on a chunk.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_constraint_add_table_constraint(
|
||||
chunk_constraint_row _timescaledb_catalog.chunk_constraint
|
||||
@ -3945,11 +3945,11 @@ $BODY$;
|
||||
-- Deprecated partition hash function
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val anyelement)
|
||||
RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_hash(val anyelement)
|
||||
RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_hash' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_hash' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
-- This file contains functions related to getting information about the
|
||||
-- schema of a hypertable, including columns, their types, etc.
|
||||
|
||||
@ -4345,7 +4345,7 @@ BEGIN
|
||||
END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_command_end() RETURNS event_trigger
|
||||
AS '$libdir/timescaledb', 'timescaledb_ddl_command_end' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@', 'timescaledb_ddl_command_end' LANGUAGE C;
|
||||
|
||||
DROP EVENT TRIGGER IF EXISTS timescaledb_ddl_command_end;
|
||||
CREATE EVENT TRIGGER timescaledb_ddl_command_end ON ddl_command_end
|
||||
@ -4473,37 +4473,37 @@ END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_finalfunc(internal, anyelement, "any")
|
||||
RETURNS anyelement
|
||||
AS '$libdir/timescaledb', 'bookend_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_finalfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_serializefunc(internal)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'bookend_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_serializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'bookend_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
|
||||
@ -4536,15 +4536,15 @@ CREATE AGGREGATE last(anyelement, "any") (
|
||||
-- time_bucket returns the left edge of the bucket where ts falls into.
|
||||
-- Buckets span an interval of time equal to the bucket_width and are aligned with the epoch.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP) RETURNS TIMESTAMP
|
||||
AS '$libdir/timescaledb', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- bucketing of timestamptz happens at UTC time
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMPTZ) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
--bucketing on date should not do any timezone conversion
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts DATE) RETURNS DATE
|
||||
AS '$libdir/timescaledb', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- If an interval is given as the third argument, the bucket alignment is offset by the interval.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP, "offset" INTERVAL)
|
||||
@ -4602,15 +4602,15 @@ $BODY$
|
||||
SELECT (((ts-"offset") / bucket_width)*bucket_width)+"offset";
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_git_commit() RETURNS TEXT
|
||||
AS '$libdir/timescaledb', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
-- this trigger function causes an invalidation event on the table whose name is
|
||||
-- passed in as the first element.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache_trigger()
|
||||
RETURNS TRIGGER AS '$libdir/timescaledb', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
RETURNS TRIGGER AS '@MODULE_PATHNAME@', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
|
||||
-- This function is only used for debugging
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache(proxy_oid OID)
|
||||
RETURNS BOOLEAN AS '$libdir/timescaledb', 'invalidate_relcache' LANGUAGE C;
|
||||
RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'invalidate_relcache' LANGUAGE C;
|
||||
|
||||
|
||||
-- This file contains utility functions to get the relation size
|
||||
@ -5033,27 +5033,27 @@ END;
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_sfunc (state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_combinefunc(state1 INTERNAL, state2 INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_serializefunc(INTERNAL)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'hist_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_serializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_deserializefunc(bytea, INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_finalfunc(state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTEGER[]
|
||||
AS '$libdir/timescaledb', 'hist_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_finalfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- Tell Postgres how to use the new function
|
||||
|
@ -188,14 +188,14 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_ran
|
||||
interval_length BIGINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_range_closed(
|
||||
dimension_value BIGINT,
|
||||
num_slices SMALLINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.drop_chunk_metadata(
|
||||
chunk_id int
|
||||
@ -842,7 +842,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.verify_hypertable_indexes(hypertable REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'indexing_verify_hypertable_indexes' LANGUAGE C STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'indexing_verify_hypertable_indexes' LANGUAGE C STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_change_owner(main_table OID, new_table_owner NAME)
|
||||
RETURNS void LANGUAGE plpgsql
|
||||
@ -873,22 +873,22 @@ $BODY$;
|
||||
|
||||
--documentation of these function located in chunk_index.h
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_index_clone(chunk_index_oid OID) RETURNS OID
|
||||
AS '$libdir/timescaledb', 'chunk_index_clone' LANGUAGE C VOLATILE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'chunk_index_clone' LANGUAGE C VOLATILE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_index_replace(chunk_index_oid_old OID, chunk_index_oid_new OID) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'chunk_index_replace' LANGUAGE C VOLATILE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'chunk_index_replace' LANGUAGE C VOLATILE STRICT;
|
||||
-- This file contains utilities for time conversion.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_unix_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp(unixtime_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp_pg(postgres_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
|
||||
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
|
||||
@ -982,7 +982,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.time_to_internal(time_element anyelement, time_type REGTYPE) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'time_to_internal' LANGUAGE C IMMUTABLE PARALLEL SAFE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'time_to_internal' LANGUAGE C IMMUTABLE PARALLEL SAFE STRICT;
|
||||
-- This file contains functions associated with creating new
|
||||
-- hypertables.
|
||||
|
||||
@ -1234,7 +1234,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.validate_triggers(main_table REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'hypertable_validate_triggers' LANGUAGE C STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'hypertable_validate_triggers' LANGUAGE C STRICT;
|
||||
-- Creates a constraint on a chunk.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_constraint_add_table_constraint(
|
||||
chunk_constraint_row _timescaledb_catalog.chunk_constraint
|
||||
@ -1381,11 +1381,11 @@ $BODY$;
|
||||
-- Deprecated partition hash function
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val anyelement)
|
||||
RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_hash(val anyelement)
|
||||
RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_hash' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_hash' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
-- This file contains functions related to getting information about the
|
||||
-- schema of a hypertable, including columns, their types, etc.
|
||||
|
||||
@ -1781,7 +1781,7 @@ BEGIN
|
||||
END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_command_end() RETURNS event_trigger
|
||||
AS '$libdir/timescaledb', 'timescaledb_ddl_command_end' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@', 'timescaledb_ddl_command_end' LANGUAGE C;
|
||||
|
||||
DROP EVENT TRIGGER IF EXISTS timescaledb_ddl_command_end;
|
||||
CREATE EVENT TRIGGER timescaledb_ddl_command_end ON ddl_command_end
|
||||
@ -1909,37 +1909,37 @@ END
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_finalfunc(internal, anyelement, "any")
|
||||
RETURNS anyelement
|
||||
AS '$libdir/timescaledb', 'bookend_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_finalfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_serializefunc(internal)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'bookend_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_serializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'bookend_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
|
||||
@ -1972,15 +1972,15 @@ CREATE AGGREGATE last(anyelement, "any") (
|
||||
-- time_bucket returns the left edge of the bucket where ts falls into.
|
||||
-- Buckets span an interval of time equal to the bucket_width and are aligned with the epoch.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP) RETURNS TIMESTAMP
|
||||
AS '$libdir/timescaledb', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- bucketing of timestamptz happens at UTC time
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMPTZ) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
--bucketing on date should not do any timezone conversion
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts DATE) RETURNS DATE
|
||||
AS '$libdir/timescaledb', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- If an interval is given as the third argument, the bucket alignment is offset by the interval.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP, "offset" INTERVAL)
|
||||
@ -2038,15 +2038,15 @@ $BODY$
|
||||
SELECT (((ts-"offset") / bucket_width)*bucket_width)+"offset";
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_git_commit() RETURNS TEXT
|
||||
AS '$libdir/timescaledb', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
-- this trigger function causes an invalidation event on the table whose name is
|
||||
-- passed in as the first element.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache_trigger()
|
||||
RETURNS TRIGGER AS '$libdir/timescaledb', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
RETURNS TRIGGER AS '@MODULE_PATHNAME@', 'invalidate_relcache_trigger' LANGUAGE C;
|
||||
|
||||
-- This function is only used for debugging
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache(proxy_oid OID)
|
||||
RETURNS BOOLEAN AS '$libdir/timescaledb', 'invalidate_relcache' LANGUAGE C;
|
||||
RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'invalidate_relcache' LANGUAGE C;
|
||||
|
||||
|
||||
-- This file contains utility functions to get the relation size
|
||||
@ -2469,27 +2469,27 @@ END;
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_sfunc (state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_combinefunc(state1 INTERNAL, state2 INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_serializefunc(INTERNAL)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'hist_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_serializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_deserializefunc(bytea, INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_finalfunc(state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTEGER[]
|
||||
AS '$libdir/timescaledb', 'hist_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_finalfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- Tell Postgres how to use the new function
|
||||
|
@ -175,14 +175,14 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_ran
|
||||
interval_length BIGINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_open_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.dimension_calculate_default_range_closed(
|
||||
dimension_value BIGINT,
|
||||
num_slices SMALLINT,
|
||||
OUT range_start BIGINT,
|
||||
OUT range_end BIGINT)
|
||||
AS '$libdir/timescaledb', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
AS '@MODULE_PATHNAME@', 'dimension_calculate_closed_range_default' LANGUAGE C STABLE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.drop_chunk_metadata(
|
||||
chunk_id int
|
||||
@ -838,7 +838,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.verify_hypertable_indexes(hypertable REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'indexing_verify_hypertable_indexes' LANGUAGE C STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'indexing_verify_hypertable_indexes' LANGUAGE C STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_change_owner(main_table OID, new_table_owner NAME)
|
||||
RETURNS void LANGUAGE plpgsql
|
||||
@ -867,35 +867,35 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.attach_tablespace(tablespace NAME, hypertable REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'tablespace_attach' LANGUAGE C VOLATILE;
|
||||
AS '@MODULE_PATHNAME@', 'tablespace_attach' LANGUAGE C VOLATILE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.detach_tablespace(tablespace NAME, hypertable REGCLASS) RETURNS INTEGER
|
||||
AS '$libdir/timescaledb', 'tablespace_detach' LANGUAGE C VOLATILE;
|
||||
AS '@MODULE_PATHNAME@', 'tablespace_detach' LANGUAGE C VOLATILE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.detach_tablespaces(hypertable REGCLASS) RETURNS INTEGER
|
||||
AS '$libdir/timescaledb', 'tablespace_detach_all_from_hypertable' LANGUAGE C VOLATILE;
|
||||
AS '@MODULE_PATHNAME@', 'tablespace_detach_all_from_hypertable' LANGUAGE C VOLATILE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.show_tablespaces(hypertable REGCLASS) RETURNS SETOF NAME
|
||||
AS '$libdir/timescaledb', 'tablespace_show' LANGUAGE C VOLATILE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'tablespace_show' LANGUAGE C VOLATILE STRICT;
|
||||
|
||||
--documentation of these function located in chunk_index.h
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_index_clone(chunk_index_oid OID) RETURNS OID
|
||||
AS '$libdir/timescaledb', 'chunk_index_clone' LANGUAGE C VOLATILE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'chunk_index_clone' LANGUAGE C VOLATILE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_index_replace(chunk_index_oid_old OID, chunk_index_oid_new OID) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'chunk_index_replace' LANGUAGE C VOLATILE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'chunk_index_replace' LANGUAGE C VOLATILE STRICT;
|
||||
-- This file contains utilities for time conversion.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_unix_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp(unixtime_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp_pg(postgres_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
|
||||
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
|
||||
@ -1005,7 +1005,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.time_to_internal(time_element anyelement, time_type REGTYPE) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'time_to_internal' LANGUAGE C IMMUTABLE PARALLEL SAFE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'time_to_internal' LANGUAGE C IMMUTABLE PARALLEL SAFE STRICT;
|
||||
-- This file contains functions associated with creating new
|
||||
-- hypertables.
|
||||
|
||||
@ -1260,7 +1260,7 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.validate_triggers(main_table REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'hypertable_validate_triggers' LANGUAGE C STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'hypertable_validate_triggers' LANGUAGE C STRICT;
|
||||
-- Creates a constraint on a chunk.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_constraint_add_table_constraint(
|
||||
chunk_constraint_row _timescaledb_catalog.chunk_constraint
|
||||
@ -1415,11 +1415,11 @@ $BODY$;
|
||||
-- Deprecated partition hash function
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_for_key(val anyelement)
|
||||
RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_for_key' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_partition_hash(val anyelement)
|
||||
RETURNS int
|
||||
AS '$libdir/timescaledb', 'get_partition_hash' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_partition_hash' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
-- This file contains functions related to getting information about the
|
||||
-- schema of a hypertable, including columns, their types, etc.
|
||||
|
||||
@ -1842,7 +1842,7 @@ $BODY$
|
||||
SELECT * FROM _timescaledb_internal.show_tablespaces(hypertable);
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.ddl_command_end() RETURNS event_trigger
|
||||
AS '$libdir/timescaledb', 'timescaledb_ddl_command_end' LANGUAGE C;
|
||||
AS '@MODULE_PATHNAME@', 'timescaledb_ddl_command_end' LANGUAGE C;
|
||||
|
||||
DROP EVENT TRIGGER IF EXISTS timescaledb_ddl_command_end;
|
||||
CREATE EVENT TRIGGER timescaledb_ddl_command_end ON ddl_command_end
|
||||
@ -1939,37 +1939,37 @@ $BODY$
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.first_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'first_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'first_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_sfunc(internal, anyelement, "any")
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.last_combinefunc(internal, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'last_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'last_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_finalfunc(internal, anyelement, "any")
|
||||
RETURNS anyelement
|
||||
AS '$libdir/timescaledb', 'bookend_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_finalfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_serializefunc(internal)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'bookend_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_serializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.bookend_deserializefunc(bytea, internal)
|
||||
RETURNS internal
|
||||
AS '$libdir/timescaledb', 'bookend_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'bookend_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
--This aggregate returns the "first" element of the first argument when ordered by the second argument.
|
||||
@ -2002,15 +2002,15 @@ CREATE AGGREGATE last(anyelement, "any") (
|
||||
-- time_bucket returns the left edge of the bucket where ts falls into.
|
||||
-- Buckets span an interval of time equal to the bucket_width and are aligned with the epoch.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP) RETURNS TIMESTAMP
|
||||
AS '$libdir/timescaledb', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamp_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- bucketing of timestamptz happens at UTC time
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMPTZ) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'timestamptz_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
--bucketing on date should not do any timezone conversion
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts DATE) RETURNS DATE
|
||||
AS '$libdir/timescaledb', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'date_bucket' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- If an interval is given as the third argument, the bucket alignment is offset by the interval.
|
||||
CREATE OR REPLACE FUNCTION time_bucket(bucket_width INTERVAL, ts TIMESTAMP, "offset" INTERVAL)
|
||||
@ -2068,15 +2068,15 @@ $BODY$
|
||||
SELECT (((ts-"offset") / bucket_width)*bucket_width)+"offset";
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_git_commit() RETURNS TEXT
|
||||
AS '$libdir/timescaledb', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
-- this trigger function causes an invalidation event on the table whose name is
|
||||
-- passed in as the first element.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache_trigger()
|
||||
RETURNS TRIGGER AS '$libdir/timescaledb', 'invalidate_relcache_trigger' LANGUAGE C STRICT;
|
||||
RETURNS TRIGGER AS '@MODULE_PATHNAME@', 'invalidate_relcache_trigger' LANGUAGE C STRICT;
|
||||
|
||||
-- This function is only used for debugging
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_cache.invalidate_relcache(catalog_table REGCLASS)
|
||||
RETURNS BOOLEAN AS '$libdir/timescaledb', 'invalidate_relcache' LANGUAGE C STRICT;
|
||||
RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'invalidate_relcache' LANGUAGE C STRICT;
|
||||
-- This file contains utility functions to get the relation size
|
||||
-- of hypertables, chunks, and indexes on hypertables.
|
||||
|
||||
@ -2497,27 +2497,27 @@ END;
|
||||
$BODY$;
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_sfunc (state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_sfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_sfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_combinefunc(state1 INTERNAL, state2 INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_combinefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_combinefunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_serializefunc(INTERNAL)
|
||||
RETURNS bytea
|
||||
AS '$libdir/timescaledb', 'hist_serializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_serializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_deserializefunc(bytea, INTERNAL)
|
||||
RETURNS INTERNAL
|
||||
AS '$libdir/timescaledb', 'hist_deserializefunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_deserializefunc'
|
||||
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.hist_finalfunc(state INTERNAL, val DOUBLE PRECISION, MIN DOUBLE PRECISION, MAX DOUBLE PRECISION, nbuckets INTEGER)
|
||||
RETURNS INTEGER[]
|
||||
AS '$libdir/timescaledb', 'hist_finalfunc'
|
||||
AS '@MODULE_PATHNAME@', 'hist_finalfunc'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
|
||||
-- Tell Postgres how to use the new function
|
||||
|
1
sql/updates/post-global.sql
Normal file
1
sql/updates/post-global.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER EVENT TRIGGER timescaledb_ddl_command_end ENABLE;
|
4
sql/updates/pre-global.sql
Normal file
4
sql/updates/pre-global.sql
Normal file
@ -0,0 +1,4 @@
|
||||
--Disable the event trigger during updates. Two reasons:
|
||||
---1- Prevents the old extension .so being loaded during upgrade to process the event trigger.
|
||||
---2- Probably the right thing to do anyway since you don't necessarly know which version of the trigger will be fired during upgrade.
|
||||
ALTER EVENT TRIGGER timescaledb_ddl_command_end DISABLE;
|
@ -252,4 +252,4 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.validate_triggers(main_table REGCLASS) RETURNS VOID
|
||||
AS '$libdir/timescaledb', 'hypertable_validate_triggers' LANGUAGE C STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'hypertable_validate_triggers' LANGUAGE C STRICT;
|
||||
|
@ -1,15 +1,16 @@
|
||||
-- This file contains utilities for time conversion.
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_unix_microseconds(ts TIMESTAMPTZ) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_timestamp_to_unix_microseconds' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp(unixtime_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_unix_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.to_timestamp_pg(postgres_us BIGINT) RETURNS TIMESTAMPTZ
|
||||
AS '$libdir/timescaledb', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'pg_microseconds_to_timestamp' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
||||
|
||||
|
||||
-- Time can be represented in a hypertable as an int* (bigint/integer/smallint) or as a timestamp type (
|
||||
@ -119,4 +120,4 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.time_to_internal(time_element anyelement, time_type REGTYPE) RETURNS BIGINT
|
||||
AS '$libdir/timescaledb', 'time_to_internal' LANGUAGE C IMMUTABLE PARALLEL SAFE STRICT;
|
||||
AS '@MODULE_PATHNAME@', 'time_to_internal' LANGUAGE C IMMUTABLE PARALLEL SAFE STRICT;
|
||||
|
@ -1,2 +1,2 @@
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.get_git_commit() RETURNS TEXT
|
||||
AS '$libdir/timescaledb', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
AS '@MODULE_PATHNAME@', 'get_git_commit' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
|
@ -146,9 +146,11 @@ endif (OBJDUMP AND PGINDENT)
|
||||
add_library(${PROJECT_NAME} MODULE ${SOURCES} ${HEADERS} ${GITCOMMIT_H})
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
OUTPUT_NAME ${PROJECT_NAME}
|
||||
OUTPUT_NAME ${PROJECT_NAME}-${PROJECT_VERSION_MOD}
|
||||
PREFIX "")
|
||||
|
||||
install(
|
||||
TARGETS ${PROJECT_NAME}
|
||||
DESTINATION ${PG_PKGLIBDIR})
|
||||
|
||||
add_subdirectory(loader)
|
||||
|
@ -56,7 +56,6 @@ typedef enum InternalFunction
|
||||
#define CATALOG_SCHEMA_NAME "_timescaledb_catalog"
|
||||
#define CACHE_SCHEMA_NAME "_timescaledb_cache"
|
||||
#define INTERNAL_SCHEMA_NAME "_timescaledb_internal"
|
||||
#define EXTENSION_NAME "timescaledb"
|
||||
|
||||
/******************************
|
||||
*
|
||||
|
104
src/extension.c
104
src/extension.c
@ -6,14 +6,23 @@
|
||||
#include <utils/lsyscache.h>
|
||||
#include <utils/inval.h>
|
||||
|
||||
#include "compat-msvc-enter.h" /* To label externs in extension.h and miscadmin.h correctly */
|
||||
#include "compat-msvc-enter.h" /* To label externs in extension.h and
|
||||
* miscadmin.h correctly */
|
||||
#include <commands/extension.h>
|
||||
#include <miscadmin.h>
|
||||
#include "compat-msvc-exit.h"
|
||||
|
||||
#include <access/relscan.h>
|
||||
#include <catalog/indexing.h>
|
||||
#include <catalog/pg_extension.h>
|
||||
#include <utils/builtins.h>
|
||||
#include <utils/fmgroids.h>
|
||||
|
||||
#include "catalog.h"
|
||||
#include "extension.h"
|
||||
#include "guc.h"
|
||||
#include "version.h"
|
||||
#include "extension_utils.c"
|
||||
|
||||
#define EXTENSION_PROXY_TABLE "cache_inval_extension"
|
||||
|
||||
@ -33,76 +42,25 @@ static Oid extension_proxy_oid = InvalidOid;
|
||||
* * The proxy table will be created before the extension itself.
|
||||
* * The proxy table will be dropped before the extension itself.
|
||||
*/
|
||||
enum ExtensionState
|
||||
{
|
||||
/*
|
||||
* NOT_INSTALLED means that this backend knows that the extension is not
|
||||
* present. In this state we know that the proxy table is not present.
|
||||
* Thus, the only way to get out of this state is a RelCacheInvalidation
|
||||
* indicating that the proxy table was added.
|
||||
*/
|
||||
EXTENSION_STATE_NOT_INSTALLED,
|
||||
|
||||
/*
|
||||
* UNKNOWN state is used only if we cannot be sure what the state is. This
|
||||
* can happen in two cases: 1) at the start of a backend or 2) We got a
|
||||
* relcache event outside of a transaction and thus could not check the
|
||||
* cache for the presence/absence of the proxy table or extension.
|
||||
*/
|
||||
EXTENSION_STATE_UNKNOWN,
|
||||
|
||||
/*
|
||||
* TRANSITIONING only occurs when the proxy table exists but the extension
|
||||
* does not. This can only happen in the middle of a create or drop
|
||||
* extension.
|
||||
*/
|
||||
EXTENSION_STATE_TRANSITIONING,
|
||||
|
||||
/*
|
||||
* CREATED means we know the extension is loaded, metadata is up-to-date,
|
||||
* and we therefore do not need a full check until a RelCacheInvalidation
|
||||
* on the proxy table.
|
||||
*/
|
||||
EXTENSION_STATE_CREATED,
|
||||
};
|
||||
|
||||
static enum ExtensionState extstate = EXTENSION_STATE_UNKNOWN;
|
||||
|
||||
static bool
|
||||
proxy_table_exists()
|
||||
void
|
||||
extension_check_version(const char *so_version)
|
||||
{
|
||||
Oid nsid = get_namespace_oid(CACHE_SCHEMA_NAME, true);
|
||||
Oid proxy_table = get_relname_relid(EXTENSION_PROXY_TABLE, nsid);
|
||||
char *sql_version;
|
||||
|
||||
return OidIsValid(proxy_table);
|
||||
}
|
||||
|
||||
static bool
|
||||
extension_exists()
|
||||
{
|
||||
return OidIsValid(get_extension_oid(EXTENSION_NAME, true));
|
||||
}
|
||||
|
||||
/* Returns the recomputed current state */
|
||||
static enum ExtensionState
|
||||
extension_new_state()
|
||||
{
|
||||
/*
|
||||
* NormalProcessingMode necessary to avoid accessing cache before its
|
||||
* ready (which may result in an infinite loop). More concretely we need
|
||||
* RelationCacheInitializePhase3 to have been already called.
|
||||
*/
|
||||
if (!IsNormalProcessingMode() || !IsTransactionState())
|
||||
return EXTENSION_STATE_UNKNOWN;
|
||||
return;
|
||||
|
||||
if (proxy_table_exists())
|
||||
sql_version = extension_version();
|
||||
|
||||
if (strcmp(sql_version, so_version) != 0)
|
||||
{
|
||||
if (!extension_exists())
|
||||
return EXTENSION_STATE_TRANSITIONING;
|
||||
else
|
||||
return EXTENSION_STATE_CREATED;
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("Mismatched timescaledb version. Shared object file %s, SQL %s", so_version, sql_version)));
|
||||
}
|
||||
return EXTENSION_STATE_NOT_INSTALLED;
|
||||
}
|
||||
|
||||
/* Sets a new state, returning whether the state has changed */
|
||||
@ -119,6 +77,7 @@ extension_set_state(enum ExtensionState newstate)
|
||||
case EXTENSION_STATE_UNKNOWN:
|
||||
break;
|
||||
case EXTENSION_STATE_CREATED:
|
||||
extension_check_version(TIMESCALEDB_VERSION_MOD);
|
||||
extension_proxy_oid = get_relname_relid(EXTENSION_PROXY_TABLE, get_namespace_oid(CACHE_SCHEMA_NAME, false));
|
||||
catalog_reset();
|
||||
break;
|
||||
@ -135,7 +94,7 @@ extension_set_state(enum ExtensionState newstate)
|
||||
static bool
|
||||
extension_update_state()
|
||||
{
|
||||
return extension_set_state(extension_new_state());
|
||||
return extension_set_state(extension_current_state());
|
||||
}
|
||||
|
||||
/*
|
||||
@ -181,7 +140,6 @@ extension_invalidate(Oid relid)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
extension_is_loaded(void)
|
||||
{
|
||||
@ -195,18 +153,6 @@ extension_is_loaded(void)
|
||||
extension_update_state();
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn off extension during upgrade scripts. This is necessary so that,
|
||||
* for example, the catalog does not go looking for things that aren't yet
|
||||
* there.
|
||||
*/
|
||||
if (creating_extension)
|
||||
{
|
||||
Oid extension_oid = get_extension_oid(EXTENSION_NAME, true);
|
||||
if (OidIsValid(extension_oid) && extension_oid == CurrentExtensionObject)
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (extstate)
|
||||
{
|
||||
case EXTENSION_STATE_CREATED:
|
||||
@ -214,6 +160,12 @@ extension_is_loaded(void)
|
||||
case EXTENSION_STATE_NOT_INSTALLED:
|
||||
case EXTENSION_STATE_UNKNOWN:
|
||||
case EXTENSION_STATE_TRANSITIONING:
|
||||
|
||||
/*
|
||||
* Turn off extension during upgrade scripts. This is necessary so
|
||||
* that, for example, the catalog does not go looking for things
|
||||
* that aren't yet there.
|
||||
*/
|
||||
return false;
|
||||
default:
|
||||
elog(ERROR, "unknown state: %d", extstate);
|
||||
|
@ -2,7 +2,10 @@
|
||||
#define TIMESCALEDB_EXTENSION_H
|
||||
#include <postgres.h>
|
||||
|
||||
#define EXTENSION_NAME "timescaledb"
|
||||
|
||||
bool extension_invalidate(Oid relid);
|
||||
bool extension_is_loaded(void);
|
||||
void extension_check_version(const char *so_version);
|
||||
|
||||
#endif /* TIMESCALEDB_EXTENSION_H */
|
||||
|
172
src/extension_utils.c
Normal file
172
src/extension_utils.c
Normal file
@ -0,0 +1,172 @@
|
||||
/* This file will be used by the versioned timescaledb extension and the loader
|
||||
* Because we want the loader not to export symbols all files here should be static
|
||||
* and be included via #include "extension_utils.c" instead of the regular linking process
|
||||
*/
|
||||
|
||||
#include <postgres.h>
|
||||
#include <access/xact.h>
|
||||
#include <commands/extension.h>
|
||||
#include <catalog/namespace.h>
|
||||
#include <utils/lsyscache.h>
|
||||
#include <miscadmin.h>
|
||||
#include <parser/analyze.h>
|
||||
#include <commands/extension.h>
|
||||
#include <access/relscan.h>
|
||||
#include <catalog/pg_extension.h>
|
||||
#include <utils/fmgroids.h>
|
||||
#include <utils/builtins.h>
|
||||
#include <utils/rel.h>
|
||||
#include <catalog/indexing.h>
|
||||
|
||||
#define EXTENSION_PROXY_TABLE "cache_inval_extension"
|
||||
#define CACHE_SCHEMA_NAME "_timescaledb_cache"
|
||||
#define MAX_SO_NAME_LEN NAMEDATALEN+NAMEDATALEN+1+1 /* extname+"-"+version */
|
||||
|
||||
enum ExtensionState
|
||||
{
|
||||
/*
|
||||
* NOT_INSTALLED means that this backend knows that the extension is not
|
||||
* present. In this state we know that the proxy table is not present.
|
||||
* Thus, the only way to get out of this state is a RelCacheInvalidation
|
||||
* indicating that the proxy table was added. This is the state returned
|
||||
* during DROP EXTENSION.
|
||||
*/
|
||||
EXTENSION_STATE_NOT_INSTALLED,
|
||||
|
||||
/*
|
||||
* UNKNOWN state is used only if we cannot be sure what the state is. This
|
||||
* can happen in two cases: 1) at the start of a backend or 2) We got a
|
||||
* relcache event outside of a transaction and thus could not check the
|
||||
* cache for the presence/absence of the proxy table or extension.
|
||||
*/
|
||||
EXTENSION_STATE_UNKNOWN,
|
||||
|
||||
/*
|
||||
* TRANSITIONING only occurs in the middle of a CREATE EXTENSION or ALTER
|
||||
* EXTENSION UPDATE
|
||||
*/
|
||||
EXTENSION_STATE_TRANSITIONING,
|
||||
|
||||
/*
|
||||
* CREATED means we know the extension is loaded, metadata is up-to-date,
|
||||
* and we therefore do not need a full check until a RelCacheInvalidation
|
||||
* on the proxy table.
|
||||
*/
|
||||
EXTENSION_STATE_CREATED,
|
||||
};
|
||||
|
||||
static char *
|
||||
extension_version(void)
|
||||
{
|
||||
Datum result;
|
||||
Relation rel;
|
||||
SysScanDesc scandesc;
|
||||
HeapTuple tuple;
|
||||
ScanKeyData entry[1];
|
||||
bool is_null = true;
|
||||
static char *sql_version = NULL;
|
||||
|
||||
rel = heap_open(ExtensionRelationId, AccessShareLock);
|
||||
|
||||
ScanKeyInit(&entry[0],
|
||||
Anum_pg_extension_extname,
|
||||
BTEqualStrategyNumber, F_NAMEEQ,
|
||||
DirectFunctionCall1(namein, CStringGetDatum(EXTENSION_NAME))
|
||||
);
|
||||
|
||||
scandesc = systable_beginscan(rel, ExtensionNameIndexId, true,
|
||||
NULL, 1, entry);
|
||||
|
||||
tuple = systable_getnext(scandesc);
|
||||
|
||||
/* We assume that there can be at most one matching tuple */
|
||||
if (HeapTupleIsValid(tuple))
|
||||
{
|
||||
result = heap_getattr(tuple, Anum_pg_extension_extversion, RelationGetDescr(rel), &is_null);
|
||||
|
||||
if (!is_null)
|
||||
{
|
||||
sql_version = strdup(TextDatumGetCString(result));
|
||||
}
|
||||
}
|
||||
|
||||
systable_endscan(scandesc);
|
||||
heap_close(rel, AccessShareLock);
|
||||
|
||||
if (sql_version == NULL)
|
||||
{
|
||||
elog(ERROR, "Extension not found when getting version");
|
||||
}
|
||||
return sql_version;
|
||||
}
|
||||
|
||||
|
||||
static bool inline
|
||||
proxy_table_exists()
|
||||
{
|
||||
Oid nsid = get_namespace_oid(CACHE_SCHEMA_NAME, true);
|
||||
|
||||
if (!OidIsValid(nsid))
|
||||
return false;
|
||||
|
||||
return OidIsValid(get_relname_relid(EXTENSION_PROXY_TABLE, nsid));
|
||||
}
|
||||
|
||||
static bool inline
|
||||
extension_exists()
|
||||
{
|
||||
return OidIsValid(get_extension_oid(EXTENSION_NAME, true));
|
||||
}
|
||||
|
||||
static bool inline
|
||||
extension_is_transitioning()
|
||||
{
|
||||
/*
|
||||
* Determine whether the extension is being created or upgraded (as a
|
||||
* misnomer creating_extension is true during upgrades)
|
||||
*/
|
||||
if (creating_extension)
|
||||
{
|
||||
char *current_extension_name = get_extension_name(CurrentExtensionObject);
|
||||
|
||||
if (NULL == current_extension_name)
|
||||
elog(ERROR, "Unknown current extension while creating");
|
||||
|
||||
if (strcmp(EXTENSION_NAME, current_extension_name) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Returns the recomputed current state */
|
||||
static enum ExtensionState
|
||||
extension_current_state()
|
||||
{
|
||||
/*
|
||||
* NormalProcessingMode necessary to avoid accessing cache before its
|
||||
* ready (which may result in an infinite loop). More concretely we need
|
||||
* RelationCacheInitializePhase3 to have been already called.
|
||||
*/
|
||||
if (!IsNormalProcessingMode() || !IsTransactionState())
|
||||
return EXTENSION_STATE_UNKNOWN;
|
||||
|
||||
/*
|
||||
* NOTE: do not check for proxy_table_exists here. Want to be in
|
||||
* TRANSITIONING state even before the proxy table is created
|
||||
*/
|
||||
if (extension_is_transitioning())
|
||||
return EXTENSION_STATE_TRANSITIONING;
|
||||
|
||||
/*
|
||||
* proxy_table_exists uses syscache. Must come first. NOTE: during DROP
|
||||
* EXTENSION proxy_table_exists() will return false right away, while
|
||||
* extension_exists will return true until the end of the command
|
||||
*/
|
||||
if (proxy_table_exists())
|
||||
{
|
||||
Assert(extension_exists());
|
||||
return EXTENSION_STATE_CREATED;
|
||||
}
|
||||
|
||||
return EXTENSION_STATE_NOT_INSTALLED;
|
||||
}
|
33
src/init.c
33
src/init.c
@ -6,7 +6,10 @@
|
||||
#include <utils/guc.h>
|
||||
|
||||
#include "executor.h"
|
||||
#include "extension.h"
|
||||
#include "guc.h"
|
||||
#include "catalog.h"
|
||||
#include "version.h"
|
||||
|
||||
#ifdef PG_MODULE_MAGIC
|
||||
PG_MODULE_MAGIC;
|
||||
@ -43,32 +46,12 @@ extern void PGDLLEXPORT _PG_fini(void);
|
||||
void
|
||||
_PG_init(void)
|
||||
{
|
||||
if (!process_shared_preload_libraries_in_progress)
|
||||
{
|
||||
/* cannot use GUC variable here since extension not yet loaded */
|
||||
char *allow_install_without_preload = GetConfigOptionByName("timescaledb.allow_install_without_preload", NULL, true);
|
||||
/*
|
||||
* Check extension_is loaded to catch certain errors such as calls to
|
||||
* functions defined on the wrong extension version
|
||||
*/
|
||||
extension_check_version(TIMESCALEDB_VERSION_MOD);
|
||||
|
||||
if (allow_install_without_preload == NULL ||
|
||||
strlen(allow_install_without_preload) != 2 ||
|
||||
strncmp(allow_install_without_preload, "on", 2) != 0)
|
||||
{
|
||||
char *config_file = GetConfigOptionByName("config_file", NULL, false);
|
||||
|
||||
ereport(ERROR,
|
||||
(errmsg("The timescaledb library is not preloaded"),
|
||||
errhint("Please preload the timescaledb library via shared_preload_libraries.\n\n"
|
||||
"This can be done by editing the config file at: %1$s\n"
|
||||
"and adding 'timescaledb' to the list in the shared_preload_libraries config.\n"
|
||||
" # Modify postgresql.conf:\n shared_preload_libraries = 'timescaledb'\n\n"
|
||||
"Another way to do this, if not preloading other libraries, is with the command:\n"
|
||||
" echo \"shared_preload_libraries = 'timescaledb'\" >> %1$s \n\n"
|
||||
"(Will require a database restart.)\n\n"
|
||||
"If you REALLY know what you are doing and would like to load the library without preloading, you can disable this check with: \n"
|
||||
" SET timescaledb.allow_install_without_preload = 'on';", config_file)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
elog(INFO, "timescaledb loaded");
|
||||
_chunk_dispatch_info_init();
|
||||
_cache_init();
|
||||
_hypertable_cache_init();
|
||||
|
19
src/loader/CMakeLists.txt
Normal file
19
src/loader/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
set(HEADERS
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
loader.c)
|
||||
|
||||
add_library(${PROJECT_NAME}-loader MODULE ${SOURCES} ${HEADERS})
|
||||
|
||||
set_target_properties(${PROJECT_NAME}-loader PROPERTIES
|
||||
OUTPUT_NAME ${PROJECT_NAME}
|
||||
PREFIX "")
|
||||
|
||||
install(
|
||||
TARGETS ${PROJECT_NAME}-loader
|
||||
DESTINATION ${PG_PKGLIBDIR})
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
add_subdirectory(../../test/loader-mock/ "${CMAKE_CURRENT_BINARY_DIR}/mock")
|
||||
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
290
src/loader/loader.c
Normal file
290
src/loader/loader.c
Normal file
@ -0,0 +1,290 @@
|
||||
#include <postgres.h>
|
||||
#include <pg_config.h>
|
||||
#include <access/xact.h>
|
||||
#include "../compat-msvc-enter.h"
|
||||
#include <commands/extension.h>
|
||||
#include <miscadmin.h>
|
||||
#include <parser/analyze.h>
|
||||
#include "../compat-msvc-exit.h"
|
||||
#include <utils/guc.h>
|
||||
#include <utils/inval.h>
|
||||
#include <nodes/print.h>
|
||||
|
||||
#define EXTENSION_NAME "timescaledb"
|
||||
|
||||
#include "../extension_utils.c"
|
||||
|
||||
#define PG96 ((PG_VERSION_NUM >= 90600) && (PG_VERSION_NUM < 100000))
|
||||
#define PG10 ((PG_VERSION_NUM >= 100000) && (PG_VERSION_NUM < 110000))
|
||||
/*
|
||||
* Some notes on design:
|
||||
*
|
||||
* We do not check for the installation of the extension upon loading the extension and instead rely on a hook for two reasons:
|
||||
* 1) We probably can't
|
||||
* - The shared_preload_libraries is called in PostmasterMain which is way before InitPostgres is called.
|
||||
* (Note: This happens even before the fork of the backend) -- so we don't even know which database this is for.
|
||||
* -- This means we cannot query for the existance of the extension yet because the caches are initialized in InitPostgres.
|
||||
* 2) We actually don't want to load the extension in two cases:
|
||||
* a) We are upgrading the extension.
|
||||
* b) We set the guc timescaledb.disable_load.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef PG_MODULE_MAGIC
|
||||
PG_MODULE_MAGIC;
|
||||
#endif
|
||||
|
||||
#define GUC_DISABLE_LOAD_NAME "timescaledb.disable_load"
|
||||
|
||||
extern void PGDLLEXPORT _PG_init(void);
|
||||
extern void PGDLLEXPORT _PG_fini(void);
|
||||
|
||||
/* was the versioned-extension loaded*/
|
||||
static bool loaded = false;
|
||||
|
||||
/* GUC to disable the load */
|
||||
static bool guc_disable_load = false;
|
||||
|
||||
/* This is the hook that existed before the loader was installed */
|
||||
static post_parse_analyze_hook_type prev_post_parse_analyze_hook;
|
||||
|
||||
/* This is timescaleDB's versioned-extension's post_parse_analyze_hook */
|
||||
static post_parse_analyze_hook_type extension_post_parse_analyze_hook = NULL;
|
||||
|
||||
static void inline extension_check(void);
|
||||
static void call_extension_post_parse_analyze_hook(ParseState *pstate,
|
||||
Query *query);
|
||||
|
||||
|
||||
static void
|
||||
inval_cache_callback(Datum arg, Oid relid)
|
||||
{
|
||||
if (guc_disable_load)
|
||||
return;
|
||||
extension_check();
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
drop_statement_drops_extension(DropStmt *stmt)
|
||||
{
|
||||
if (stmt->removeType == OBJECT_EXTENSION)
|
||||
{
|
||||
if (list_length(stmt->objects) == 1)
|
||||
{
|
||||
char *ext_name;
|
||||
#if PG96
|
||||
List *names = linitial(stmt->objects);
|
||||
|
||||
Assert(list_length(names) == 1);
|
||||
ext_name = strVal(linitial(names));
|
||||
#elif PG10
|
||||
void *name = linitial(stmt->objects);
|
||||
ext_name = strVal(name);
|
||||
#endif
|
||||
if (strcmp(ext_name, EXTENSION_NAME) == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
load_utility_cmd(Node *utilityStmt)
|
||||
{
|
||||
switch (nodeTag(utilityStmt))
|
||||
{
|
||||
case T_VariableSetStmt:
|
||||
if (strcmp(((VariableSetStmt *) utilityStmt)->name, GUC_DISABLE_LOAD_NAME) == 0)
|
||||
/* Do not load when setting the guc */
|
||||
return false;
|
||||
return true;
|
||||
case T_AlterExtensionStmt:
|
||||
if (strcmp(((AlterExtensionStmt *) utilityStmt)->extname, EXTENSION_NAME) != 0)
|
||||
return true;
|
||||
|
||||
/* disallow loading two .so from different versions */
|
||||
if (loaded)
|
||||
ereport(ERROR,
|
||||
(errmsg("Cannot update the extension after the old version has already been loaded"),
|
||||
errhint("You should start a new session and execute ALTER EXTENSION as the first command")));
|
||||
|
||||
/* do not load the current (old) version's .so */
|
||||
return false;
|
||||
case T_CreateExtensionStmt:
|
||||
if (!loaded || strcmp(((CreateExtensionStmt *) utilityStmt)->extname, EXTENSION_NAME) != 0)
|
||||
return true;
|
||||
|
||||
/* disallow loading two .so from different versions */
|
||||
ereport(ERROR,
|
||||
(errmsg("Cannot create the extension after the another version has already been loaded"),
|
||||
errhint("You should start a new session and execute CREATE EXTENSION as the first command")));
|
||||
|
||||
case T_DropStmt:
|
||||
if (drop_statement_drops_extension((DropStmt *) utilityStmt))
|
||||
/* do not load when dropping */
|
||||
return false;
|
||||
return true;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
post_analyze_hook(ParseState *pstate, Query *query)
|
||||
{
|
||||
if (!guc_disable_load && (query->commandType != CMD_UTILITY || load_utility_cmd(query->utilityStmt)))
|
||||
extension_check();
|
||||
|
||||
/*
|
||||
* Call the extension's hook. This is necessary since the extension is
|
||||
* installed during the hook. If we did not do this the extension's hook
|
||||
* would not be called during the first command because the extension
|
||||
* would not have yet been installed. Thus the loader captures the
|
||||
* extension hook and calls it explicitly after the check for installing
|
||||
* the extension.
|
||||
*/
|
||||
call_extension_post_parse_analyze_hook(pstate, query);
|
||||
|
||||
if (prev_post_parse_analyze_hook != NULL)
|
||||
{
|
||||
prev_post_parse_analyze_hook(pstate, query);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_PG_init(void)
|
||||
{
|
||||
if (!process_shared_preload_libraries_in_progress)
|
||||
{
|
||||
/* cannot use GUC variable here since extension not yet loaded */
|
||||
char *allow_install_without_preload = GetConfigOptionByName("timescaledb.allow_install_without_preload", NULL, true);
|
||||
|
||||
if (allow_install_without_preload == NULL ||
|
||||
strcmp(allow_install_without_preload, "on") != 0)
|
||||
{
|
||||
char *config_file = GetConfigOptionByName("config_file", NULL, false);
|
||||
|
||||
ereport(ERROR,
|
||||
(errmsg("The timescaledb library is not preloaded"),
|
||||
errhint("Please preload the timescaledb library via shared_preload_libraries.\n\n"
|
||||
"This can be done by editing the config file at: %1$s\n"
|
||||
"and adding 'timescaledb' to the list in the shared_preload_libraries config.\n"
|
||||
" # Modify postgresql.conf:\n shared_preload_libraries = 'timescaledb'\n\n"
|
||||
"Another way to do this, if not preloading other libraries, is with the command:\n"
|
||||
" echo \"shared_preload_libraries = 'timescaledb'\" >> %1$s \n\n"
|
||||
"(Will require a database restart.)\n\n"
|
||||
"If you REALLY know what you are doing and would like to load the library without preloading, you can disable this check with: \n"
|
||||
" SET timescaledb.allow_install_without_preload = 'on';", config_file)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
elog(INFO, "timescaledb loaded");
|
||||
|
||||
/* This is a safety-valve variable to prevent loading the full extension */
|
||||
DefineCustomBoolVariable(GUC_DISABLE_LOAD_NAME, "Disable the loading of the actual extension",
|
||||
NULL,
|
||||
&guc_disable_load,
|
||||
false,
|
||||
PGC_USERSET,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/*
|
||||
* cannot check for extension here since not inside a transaction yet. Nor
|
||||
* do we even have an assigned database yet
|
||||
*/
|
||||
|
||||
CacheRegisterRelcacheCallback(inval_cache_callback, PointerGetDatum(NULL));
|
||||
|
||||
/*
|
||||
* using the post_parse_analyze_hook since it's the earliest available
|
||||
* hook
|
||||
*/
|
||||
prev_post_parse_analyze_hook = post_parse_analyze_hook;
|
||||
post_parse_analyze_hook = post_analyze_hook;
|
||||
}
|
||||
|
||||
void
|
||||
_PG_fini(void)
|
||||
{
|
||||
post_parse_analyze_hook = prev_post_parse_analyze_hook;
|
||||
/* No way to unregister relcache callback */
|
||||
}
|
||||
|
||||
static void inline
|
||||
do_load()
|
||||
{
|
||||
char *version = extension_version();
|
||||
char soname[MAX_SO_NAME_LEN];
|
||||
post_parse_analyze_hook_type old_hook;
|
||||
|
||||
|
||||
snprintf(soname, MAX_SO_NAME_LEN, "%s-%s", EXTENSION_NAME, version);
|
||||
|
||||
/*
|
||||
* we need to capture the loaded extension's post analyze hook, giving it
|
||||
* a NULL as previous
|
||||
*/
|
||||
old_hook = post_parse_analyze_hook;
|
||||
post_parse_analyze_hook = NULL;
|
||||
|
||||
PG_TRY();
|
||||
{
|
||||
load_file(soname, false);
|
||||
loaded = true;
|
||||
}
|
||||
PG_CATCH();
|
||||
{
|
||||
/* Assume the extension was loaded to prevent re-loading another .so */
|
||||
loaded = true;
|
||||
|
||||
extension_post_parse_analyze_hook = post_parse_analyze_hook;
|
||||
post_parse_analyze_hook = old_hook;
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
extension_post_parse_analyze_hook = post_parse_analyze_hook;
|
||||
post_parse_analyze_hook = old_hook;
|
||||
}
|
||||
|
||||
static void inline
|
||||
extension_check()
|
||||
{
|
||||
if (!loaded)
|
||||
{
|
||||
enum ExtensionState state = extension_current_state();
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case EXTENSION_STATE_TRANSITIONING:
|
||||
|
||||
/*
|
||||
* Always load as soon as the extension is transitioning. This
|
||||
* is necessary so that the extension load before any CREATE
|
||||
* FUNCTION calls. Otherwise, the CREATE FUNCTION calls will
|
||||
* load the .so without capturing the post_parse_analyze_hook.
|
||||
*/
|
||||
case EXTENSION_STATE_CREATED:
|
||||
do_load();
|
||||
return;
|
||||
case EXTENSION_STATE_UNKNOWN:
|
||||
case EXTENSION_STATE_NOT_INSTALLED:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
call_extension_post_parse_analyze_hook(ParseState *pstate,
|
||||
Query *query)
|
||||
{
|
||||
if (loaded && extension_post_parse_analyze_hook != NULL)
|
||||
{
|
||||
extension_post_parse_analyze_hook(pstate, query);
|
||||
}
|
||||
}
|
@ -1638,8 +1638,20 @@ timescaledb_ddl_command_start(
|
||||
.parsetree = parsetree,
|
||||
#endif
|
||||
};
|
||||
bool altering_timescaledb = false;
|
||||
|
||||
if (!extension_is_loaded())
|
||||
if (IsA(args.parsetree, AlterExtensionStmt))
|
||||
{
|
||||
AlterExtensionStmt *stmt = (AlterExtensionStmt *) args.parsetree;
|
||||
|
||||
altering_timescaledb = (strcmp(stmt->extname, EXTENSION_NAME) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't want to load the extension if we just got the command to alter
|
||||
* it.
|
||||
*/
|
||||
if (altering_timescaledb || !extension_is_loaded())
|
||||
{
|
||||
prev_ProcessUtility(&args);
|
||||
return;
|
||||
|
@ -36,7 +36,7 @@ CREATE EXTENSION timescaledb;
|
||||
-- Test that calling twice generates proper error
|
||||
\set ON_ERROR_STOP 0
|
||||
CREATE EXTENSION timescaledb;
|
||||
ERROR: extension "timescaledb" already exists
|
||||
ERROR: Cannot create the extension after the another version has already been loaded
|
||||
\set ON_ERROR_STOP 1
|
||||
\c single :ROLE_DEFAULT_PERM_USER
|
||||
-- Make the table a hypertable again
|
||||
|
434
test/expected/loader.out
Normal file
434
test/expected/loader.out
Normal file
@ -0,0 +1,434 @@
|
||||
\c single :ROLE_SUPERUSER
|
||||
DROP EXTENSION timescaledb;
|
||||
--no extension
|
||||
\dx
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
---------+---------+------------+------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
(1 row)
|
||||
|
||||
SELECT 1;
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-1';
|
||||
WARNING: mock init "mock-1"
|
||||
--same backend as create extension;
|
||||
SELECT 1;
|
||||
WARNING: mock post_analyze_hook "mock-1"
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
\dx
|
||||
WARNING: mock post_analyze_hook "mock-1"
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
-------------+---------+------------+-------------------------------------------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
timescaledb | mock-1 | public | Enables scalable inserts and complex queries for time-series data
|
||||
(2 rows)
|
||||
|
||||
--start new backend;
|
||||
\c single :ROLE_DEFAULT_PERM_USER
|
||||
SELECT 1;
|
||||
WARNING: mock init "mock-1"
|
||||
WARNING: mock post_analyze_hook "mock-1"
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT 1;
|
||||
WARNING: mock post_analyze_hook "mock-1"
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
--test fn call after load
|
||||
SELECT mock_function();
|
||||
WARNING: mock post_analyze_hook "mock-1"
|
||||
WARNING: mock function call "mock-1"
|
||||
mock_function
|
||||
---------------
|
||||
|
||||
(1 row)
|
||||
|
||||
\dx
|
||||
WARNING: mock post_analyze_hook "mock-1"
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
-------------+---------+------------+-------------------------------------------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
timescaledb | mock-1 | public | Enables scalable inserts and complex queries for time-series data
|
||||
(2 rows)
|
||||
|
||||
\c single :ROLE_DEFAULT_PERM_USER
|
||||
--test fn call as first command
|
||||
SELECT mock_function();
|
||||
WARNING: mock init "mock-1"
|
||||
WARNING: mock post_analyze_hook "mock-1"
|
||||
WARNING: mock function call "mock-1"
|
||||
mock_function
|
||||
---------------
|
||||
|
||||
(1 row)
|
||||
|
||||
--use guc to prevent loading
|
||||
\c single :ROLE_SUPERUSER
|
||||
SET timescaledb.disable_load = 'on';
|
||||
SELECT 1;
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT 1;
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SET timescaledb.disable_load = 'off';
|
||||
SELECT 1;
|
||||
WARNING: mock init "mock-1"
|
||||
WARNING: mock post_analyze_hook "mock-1"
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
SET timescaledb.disable_load = 'not bool';
|
||||
WARNING: mock post_analyze_hook "mock-1"
|
||||
ERROR: parameter "timescaledb.disable_load" requires a Boolean value
|
||||
\set ON_ERROR_STOP 1
|
||||
\set ON_ERROR_STOP 0
|
||||
--cannot update extension after .so of previous version already loaded
|
||||
ALTER EXTENSION timescaledb UPDATE TO 'mock-2';
|
||||
ERROR: Cannot update the extension after the old version has already been loaded
|
||||
\set ON_ERROR_STOP 1
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
\dx
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
---------+---------+------------+------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
(1 row)
|
||||
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-1';
|
||||
WARNING: mock init "mock-1"
|
||||
\dx
|
||||
WARNING: mock post_analyze_hook "mock-1"
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
-------------+---------+------------+-------------------------------------------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
timescaledb | mock-1 | public | Enables scalable inserts and complex queries for time-series data
|
||||
(2 rows)
|
||||
|
||||
--start a new backend to update
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
ALTER EXTENSION timescaledb UPDATE TO 'mock-2';
|
||||
WARNING: mock init "mock-2"
|
||||
SELECT 1;
|
||||
WARNING: mock post_analyze_hook "mock-2"
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
\dx
|
||||
WARNING: mock post_analyze_hook "mock-2"
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
-------------+---------+------------+-------------------------------------------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
timescaledb | mock-2 | public | Enables scalable inserts and complex queries for time-series data
|
||||
(2 rows)
|
||||
|
||||
--drop extension
|
||||
DROP EXTENSION timescaledb;
|
||||
WARNING: mock post_analyze_hook "mock-2"
|
||||
SELECT 1;
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
\dx
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
---------+---------+------------+------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
(1 row)
|
||||
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-2';
|
||||
WARNING: mock init "mock-2"
|
||||
SELECT 1;
|
||||
WARNING: mock post_analyze_hook "mock-2"
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
\dx
|
||||
WARNING: mock post_analyze_hook "mock-2"
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
-------------+---------+------------+-------------------------------------------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
timescaledb | mock-2 | public | Enables scalable inserts and complex queries for time-series data
|
||||
(2 rows)
|
||||
|
||||
--single still has old version
|
||||
\c single :ROLE_SUPERUSER
|
||||
SELECT 1;
|
||||
WARNING: mock init "mock-1"
|
||||
WARNING: mock post_analyze_hook "mock-1"
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
\dx
|
||||
WARNING: mock post_analyze_hook "mock-1"
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
-------------+---------+------------+-------------------------------------------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
timescaledb | mock-1 | public | Enables scalable inserts and complex queries for time-series data
|
||||
(2 rows)
|
||||
|
||||
--try a broken upgrade
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
\dx
|
||||
WARNING: mock init "mock-2"
|
||||
WARNING: mock post_analyze_hook "mock-2"
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
-------------+---------+------------+-------------------------------------------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
timescaledb | mock-2 | public | Enables scalable inserts and complex queries for time-series data
|
||||
(2 rows)
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
ALTER EXTENSION timescaledb UPDATE TO 'mock-3';
|
||||
ERROR: Cannot update the extension after the old version has already been loaded
|
||||
\set ON_ERROR_STOP 1
|
||||
--should still be on mock-2
|
||||
SELECT 1;
|
||||
WARNING: mock post_analyze_hook "mock-2"
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
\dx
|
||||
WARNING: mock post_analyze_hook "mock-2"
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
-------------+---------+------------+-------------------------------------------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
timescaledb | mock-2 | public | Enables scalable inserts and complex queries for time-series data
|
||||
(2 rows)
|
||||
|
||||
--drop extension
|
||||
DROP EXTENSION timescaledb;
|
||||
WARNING: mock post_analyze_hook "mock-2"
|
||||
SELECT 1;
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
\dx
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
---------+---------+------------+------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
(1 row)
|
||||
|
||||
--create extension anew, only upgrade was broken
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-3';
|
||||
WARNING: mock init "mock-3"
|
||||
SELECT 1;
|
||||
WARNING: mock post_analyze_hook "mock-3"
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
\dx
|
||||
WARNING: mock post_analyze_hook "mock-3"
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
-------------+---------+------------+-------------------------------------------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
timescaledb | mock-3 | public | Enables scalable inserts and complex queries for time-series data
|
||||
(2 rows)
|
||||
|
||||
DROP EXTENSION timescaledb;
|
||||
WARNING: mock post_analyze_hook "mock-3"
|
||||
SELECT 1;
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
--mismatched version errors
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
\set ON_ERROR_STOP 0
|
||||
--mock-4 has mismatched versions, so the .so load should throw an error
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-4';
|
||||
ERROR: Mismatched timescaledb version. Shared object file mock-4-mismatch, SQL mock-4
|
||||
\set ON_ERROR_STOP 1
|
||||
--mock-4 not installed.
|
||||
\dx
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
---------+---------+------------+------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
(1 row)
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
--should not allow since the errored-out mock-4 above already poisoned the well.
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-5';
|
||||
ERROR: Cannot create the extension after the another version has already been loaded
|
||||
\set ON_ERROR_STOP 1
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
--broken version and drop
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-broken';
|
||||
WARNING: mock init "mock-broken"
|
||||
\set ON_ERROR_STOP 0
|
||||
--intentional broken version
|
||||
\dx
|
||||
WARNING: mock post_analyze_hook "mock-broken"
|
||||
ERROR: mock broken "mock-broken"
|
||||
SELECT 1;
|
||||
WARNING: mock post_analyze_hook "mock-broken"
|
||||
ERROR: mock broken "mock-broken"
|
||||
SELECT 1;
|
||||
WARNING: mock post_analyze_hook "mock-broken"
|
||||
ERROR: mock broken "mock-broken"
|
||||
--cannot drop extension; already loaded broken version
|
||||
DROP EXTENSION timescaledb;
|
||||
WARNING: mock post_analyze_hook "mock-broken"
|
||||
ERROR: mock broken "mock-broken"
|
||||
\set ON_ERROR_STOP 1
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
--can drop extension now. Since drop first command.
|
||||
DROP EXTENSION timescaledb;
|
||||
\dx
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
---------+---------+------------+------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
(1 row)
|
||||
|
||||
--broken version and update to fixed
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-broken';
|
||||
WARNING: mock init "mock-broken"
|
||||
\set ON_ERROR_STOP 0
|
||||
--intentional broken version
|
||||
SELECT 1;
|
||||
WARNING: mock post_analyze_hook "mock-broken"
|
||||
ERROR: mock broken "mock-broken"
|
||||
--cannot update extension; already loaded bad version
|
||||
ALTER EXTENSION timescaledb UPDATE TO 'mock-5';
|
||||
ERROR: Cannot update the extension after the old version has already been loaded
|
||||
\set ON_ERROR_STOP 1
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
--can update extension now.
|
||||
ALTER EXTENSION timescaledb UPDATE TO 'mock-5';
|
||||
WARNING: mock init "mock-5"
|
||||
SELECT 1;
|
||||
WARNING: mock post_analyze_hook "mock-5"
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT mock_function();
|
||||
WARNING: mock post_analyze_hook "mock-5"
|
||||
WARNING: mock function call "mock-5"
|
||||
mock_function
|
||||
---------------
|
||||
|
||||
(1 row)
|
||||
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
ALTER EXTENSION timescaledb UPDATE TO 'mock-6';
|
||||
WARNING: mock init "mock-6"
|
||||
\set ON_ERROR_STOP 0
|
||||
--The mock-5->mock_6 upgrade is intentionally broken.
|
||||
--The mock_function was never changed to point to mock-6 in the update script.
|
||||
--Thus mock_function is defined incorrectly to point to the mock-5.so
|
||||
--This should be an error.
|
||||
SELECT mock_function();
|
||||
WARNING: mock post_analyze_hook "mock-6"
|
||||
ERROR: Mismatched timescaledb version. Shared object file mock-5, SQL mock-6
|
||||
\set ON_ERROR_STOP 1
|
||||
\dx
|
||||
WARNING: mock post_analyze_hook "mock-6"
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
-------------+---------+------------+-------------------------------------------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
timescaledb | mock-6 | public | Enables scalable inserts and complex queries for time-series data
|
||||
(2 rows)
|
||||
|
||||
--TEST: create extension when old .so already loaded
|
||||
\c single :ROLE_SUPERUSER
|
||||
--force load of extension with (\dx)
|
||||
\dx
|
||||
WARNING: mock init "mock-1"
|
||||
WARNING: mock post_analyze_hook "mock-1"
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
-------------+---------+------------+-------------------------------------------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
timescaledb | mock-1 | public | Enables scalable inserts and complex queries for time-series data
|
||||
(2 rows)
|
||||
|
||||
DROP EXTENSION timescaledb;
|
||||
WARNING: mock post_analyze_hook "mock-1"
|
||||
\dx
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
---------+---------+------------+------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
(1 row)
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-2';
|
||||
ERROR: Cannot create the extension after the another version has already been loaded
|
||||
\set ON_ERROR_STOP 1
|
||||
\dx
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
---------+---------+------------+------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
(1 row)
|
||||
|
||||
--can create in a new session.
|
||||
\c single :ROLE_SUPERUSER
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-2';
|
||||
WARNING: mock init "mock-2"
|
||||
\dx
|
||||
WARNING: mock post_analyze_hook "mock-2"
|
||||
List of installed extensions
|
||||
Name | Version | Schema | Description
|
||||
-------------+---------+------------+-------------------------------------------------------------------
|
||||
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
|
||||
timescaledb | mock-2 | public | Enables scalable inserts and complex queries for time-series data
|
||||
(2 rows)
|
||||
|
2
test/loader-mock/CMakeLists.txt
Normal file
2
test/loader-mock/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
||||
add_subdirectory(sql)
|
||||
add_subdirectory(src)
|
14
test/loader-mock/sql/CMakeLists.txt
Normal file
14
test/loader-mock/sql/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
install(
|
||||
FILES timescaledb--mock-1.sql
|
||||
timescaledb--mock-2.sql
|
||||
timescaledb--mock-3.sql
|
||||
timescaledb--mock-4.sql
|
||||
timescaledb--mock-5.sql
|
||||
timescaledb--mock-6.sql
|
||||
timescaledb--mock-broken.sql
|
||||
timescaledb--mock-1--mock-2.sql
|
||||
timescaledb--mock-2--mock-3.sql
|
||||
timescaledb--mock-3--mock-4.sql
|
||||
timescaledb--mock-5--mock-6.sql
|
||||
timescaledb--mock-broken--mock-5.sql
|
||||
DESTINATION "${PG_SHAREDIR}/extension")
|
7
test/loader-mock/sql/timescaledb--mock-1--mock-2.sql
Normal file
7
test/loader-mock/sql/timescaledb--mock-1--mock-2.sql
Normal file
@ -0,0 +1,7 @@
|
||||
--test that the extension is deactivated during upgrade
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
CREATE OR REPLACE FUNCTION mock_function() RETURNS VOID
|
||||
AS '$libdir/timescaledb-mock-2', 'mock_function' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
4
test/loader-mock/sql/timescaledb--mock-1.sql
Normal file
4
test/loader-mock/sql/timescaledb--mock-1.sql
Normal file
@ -0,0 +1,4 @@
|
||||
CREATE SCHEMA IF NOT EXISTS _timescaledb_cache;
|
||||
CREATE TABLE IF NOT EXISTS _timescaledb_cache.cache_inval_extension();
|
||||
CREATE OR REPLACE FUNCTION mock_function() RETURNS VOID
|
||||
AS '$libdir/timescaledb-mock-1', 'mock_function' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
3
test/loader-mock/sql/timescaledb--mock-2--mock-3.sql
Normal file
3
test/loader-mock/sql/timescaledb--mock-2--mock-3.sql
Normal file
@ -0,0 +1,3 @@
|
||||
broken sql;
|
||||
CREATE OR REPLACE FUNCTION mock_function() RETURNS VOID
|
||||
AS '$libdir/timescaledb-mock-3', 'mock_function' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
6
test/loader-mock/sql/timescaledb--mock-2.sql
Normal file
6
test/loader-mock/sql/timescaledb--mock-2.sql
Normal file
@ -0,0 +1,6 @@
|
||||
--create function before proxy table
|
||||
CREATE OR REPLACE FUNCTION mock_function() RETURNS VOID
|
||||
AS '$libdir/timescaledb-mock-2', 'mock_function' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
||||
CREATE SCHEMA IF NOT EXISTS _timescaledb_cache;
|
||||
CREATE TABLE IF NOT EXISTS _timescaledb_cache.cache_inval_extension();
|
||||
|
7
test/loader-mock/sql/timescaledb--mock-3--mock-4.sql
Normal file
7
test/loader-mock/sql/timescaledb--mock-3--mock-4.sql
Normal file
@ -0,0 +1,7 @@
|
||||
--test that the extension is deactivated during upgrade
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
CREATE OR REPLACE FUNCTION mock_function() RETURNS VOID
|
||||
AS '$libdir/timescaledb-mock-4', 'mock_function' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
4
test/loader-mock/sql/timescaledb--mock-3.sql
Normal file
4
test/loader-mock/sql/timescaledb--mock-3.sql
Normal file
@ -0,0 +1,4 @@
|
||||
CREATE SCHEMA IF NOT EXISTS _timescaledb_cache;
|
||||
CREATE TABLE IF NOT EXISTS _timescaledb_cache.cache_inval_extension();
|
||||
CREATE OR REPLACE FUNCTION mock_function() RETURNS VOID
|
||||
AS '$libdir/timescaledb-mock-3', 'mock_function' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
4
test/loader-mock/sql/timescaledb--mock-4.sql
Normal file
4
test/loader-mock/sql/timescaledb--mock-4.sql
Normal file
@ -0,0 +1,4 @@
|
||||
CREATE SCHEMA IF NOT EXISTS _timescaledb_cache;
|
||||
CREATE TABLE IF NOT EXISTS _timescaledb_cache.cache_inval_extension();
|
||||
CREATE OR REPLACE FUNCTION mock_function() RETURNS VOID
|
||||
AS '$libdir/timescaledb-mock-4', 'mock_function' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
8
test/loader-mock/sql/timescaledb--mock-5--mock-6.sql
Normal file
8
test/loader-mock/sql/timescaledb--mock-5--mock-6.sql
Normal file
@ -0,0 +1,8 @@
|
||||
--test that the extension is deactivated during upgrade
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
--intentionally forget to updat func
|
||||
--CREATE OR REPLACE FUNCTION mock_function() RETURNS VOID
|
||||
-- AS '$libdir/timescaledb-mock-6', 'mock_function' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
4
test/loader-mock/sql/timescaledb--mock-5.sql
Normal file
4
test/loader-mock/sql/timescaledb--mock-5.sql
Normal file
@ -0,0 +1,4 @@
|
||||
CREATE SCHEMA IF NOT EXISTS _timescaledb_cache;
|
||||
CREATE TABLE IF NOT EXISTS _timescaledb_cache.cache_inval_extension();
|
||||
CREATE OR REPLACE FUNCTION mock_function() RETURNS VOID
|
||||
AS '$libdir/timescaledb-mock-5', 'mock_function' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
4
test/loader-mock/sql/timescaledb--mock-6.sql
Normal file
4
test/loader-mock/sql/timescaledb--mock-6.sql
Normal file
@ -0,0 +1,4 @@
|
||||
CREATE SCHEMA IF NOT EXISTS _timescaledb_cache;
|
||||
CREATE TABLE IF NOT EXISTS _timescaledb_cache.cache_inval_extension();
|
||||
CREATE OR REPLACE FUNCTION mock_function() RETURNS VOID
|
||||
AS '$libdir/timescaledb-mock-6', 'mock_function' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
@ -0,0 +1,7 @@
|
||||
--test that the extension is deactivated during upgrade
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
CREATE OR REPLACE FUNCTION mock_function() RETURNS VOID
|
||||
AS '$libdir/timescaledb-mock-5', 'mock_function' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
4
test/loader-mock/sql/timescaledb--mock-broken.sql
Normal file
4
test/loader-mock/sql/timescaledb--mock-broken.sql
Normal file
@ -0,0 +1,4 @@
|
||||
CREATE SCHEMA IF NOT EXISTS _timescaledb_cache;
|
||||
CREATE TABLE IF NOT EXISTS _timescaledb_cache.cache_inval_extension();
|
||||
CREATE OR REPLACE FUNCTION mock_function() RETURNS VOID
|
||||
AS '$libdir/timescaledb-mock-broken', 'mock_function' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
38
test/loader-mock/src/CMakeLists.txt
Normal file
38
test/loader-mock/src/CMakeLists.txt
Normal file
@ -0,0 +1,38 @@
|
||||
set(SOURCES
|
||||
init.c
|
||||
../../../src/extension.c
|
||||
../../../src/guc.c
|
||||
)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_library(${PROJECT_NAME}-mock-1 MODULE ${SOURCES} version.h)
|
||||
add_library(${PROJECT_NAME}-mock-2 MODULE ${SOURCES} version.h)
|
||||
add_library(${PROJECT_NAME}-mock-3 MODULE ${SOURCES} version.h)
|
||||
#mock-4 will be broken mismatched .so
|
||||
add_library(${PROJECT_NAME}-mock-4 MODULE ${SOURCES} version.h)
|
||||
add_library(${PROJECT_NAME}-mock-5 MODULE ${SOURCES} version.h)
|
||||
add_library(${PROJECT_NAME}-mock-broken MODULE ${SOURCES} version.h)
|
||||
add_library(${PROJECT_NAME}-mock-6 MODULE ${SOURCES} version.h)
|
||||
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}-mock-1 PRIVATE TIMESCALEDB_VERSION_MOD="mock-1" BROKEN=0)
|
||||
target_compile_definitions(${PROJECT_NAME}-mock-2 PRIVATE TIMESCALEDB_VERSION_MOD="mock-2" BROKEN=0)
|
||||
target_compile_definitions(${PROJECT_NAME}-mock-3 PRIVATE TIMESCALEDB_VERSION_MOD="mock-3" BROKEN=0)
|
||||
#mock 4 is intentionally incorrect version mod
|
||||
target_compile_definitions(${PROJECT_NAME}-mock-4 PRIVATE TIMESCALEDB_VERSION_MOD="mock-4-mismatch" BROKEN=0)
|
||||
target_compile_definitions(${PROJECT_NAME}-mock-5 PRIVATE TIMESCALEDB_VERSION_MOD="mock-5" BROKEN=0)
|
||||
target_compile_definitions(${PROJECT_NAME}-mock-broken PRIVATE TIMESCALEDB_VERSION_MOD="mock-broken" BROKEN=1)
|
||||
target_compile_definitions(${PROJECT_NAME}-mock-6 PRIVATE TIMESCALEDB_VERSION_MOD="mock-6" BROKEN=0)
|
||||
|
||||
foreach(MOCK_VERSION mock-1 mock-2 mock-3 mock-4 mock-broken mock-5 mock-6)
|
||||
set_target_properties(${PROJECT_NAME}-${MOCK_VERSION} PROPERTIES
|
||||
OUTPUT_NAME ${PROJECT_NAME}-${MOCK_VERSION}
|
||||
PREFIX "")
|
||||
|
||||
install(
|
||||
TARGETS ${PROJECT_NAME}-${MOCK_VERSION}
|
||||
DESTINATION ${PG_PKGLIBDIR} OPTIONAL)
|
||||
endforeach(MOCK_VERSION)
|
||||
|
||||
|
86
test/loader-mock/src/init.c
Normal file
86
test/loader-mock/src/init.c
Normal file
@ -0,0 +1,86 @@
|
||||
#include <postgres.h>
|
||||
#include <pg_config.h>
|
||||
#include <access/xact.h>
|
||||
#include <commands/extension.h>
|
||||
#include <miscadmin.h>
|
||||
#include <utils/guc.h>
|
||||
#include <utils/inval.h>
|
||||
#include <parser/analyze.h>
|
||||
#include <nodes/print.h>
|
||||
|
||||
#define STR_EXPAND(x) #x
|
||||
#define STR(x) STR_EXPAND(x)
|
||||
|
||||
#define TS_FUNCTION_INFO_V1(fn) \
|
||||
PGDLLEXPORT Datum fn(PG_FUNCTION_ARGS); \
|
||||
PG_FUNCTION_INFO_V1(fn)
|
||||
|
||||
#ifdef PG_MODULE_MAGIC
|
||||
PG_MODULE_MAGIC;
|
||||
#endif
|
||||
|
||||
extern void PGDLLEXPORT _PG_init(void);
|
||||
extern void PGDLLEXPORT _PG_fini(void);
|
||||
|
||||
post_parse_analyze_hook_type prev_post_parse_analyze_hook;
|
||||
|
||||
bool extension_invalidate(Oid relid);
|
||||
bool extension_is_loaded(void);
|
||||
void extension_check_version(const char *actual_version);
|
||||
|
||||
static void
|
||||
cache_invalidate_callback(Datum arg, Oid relid)
|
||||
{
|
||||
extension_invalidate(relid);
|
||||
}
|
||||
|
||||
static void
|
||||
post_analyze_hook(ParseState *pstate, Query *query)
|
||||
{
|
||||
if (extension_is_loaded())
|
||||
elog(WARNING, "mock post_analyze_hook " STR(TIMESCALEDB_VERSION_MOD));
|
||||
if (prev_post_parse_analyze_hook != NULL)
|
||||
elog(ERROR, "The extension called with a loader should always have a NULL prev hook");
|
||||
if(BROKEN && !creating_extension)
|
||||
elog(ERROR, "mock broken "STR(TIMESCALEDB_VERSION_MOD));
|
||||
}
|
||||
|
||||
void
|
||||
_PG_init(void)
|
||||
{
|
||||
/*
|
||||
* Check extension_is loaded to catch certain errors such as calls to
|
||||
* functions defined on the wrong extension version
|
||||
*/
|
||||
extension_check_version(TIMESCALEDB_VERSION_MOD);
|
||||
elog(WARNING, "mock init " STR(TIMESCALEDB_VERSION_MOD));
|
||||
prev_post_parse_analyze_hook = post_parse_analyze_hook;
|
||||
if (prev_post_parse_analyze_hook != NULL)
|
||||
elog(ERROR, "The extension loaded with a loader should always have a NULL prev hook");
|
||||
post_parse_analyze_hook = post_analyze_hook;
|
||||
CacheRegisterRelcacheCallback(cache_invalidate_callback, PointerGetDatum(NULL));
|
||||
}
|
||||
|
||||
void
|
||||
_PG_fini(void)
|
||||
{
|
||||
post_parse_analyze_hook = prev_post_parse_analyze_hook;
|
||||
/* No way to unregister relcache callback */
|
||||
}
|
||||
|
||||
/* mock for extension.c */
|
||||
void catalog_reset(void);
|
||||
void
|
||||
catalog_reset()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TS_FUNCTION_INFO_V1(mock_function);
|
||||
|
||||
Datum
|
||||
mock_function(PG_FUNCTION_ARGS)
|
||||
{
|
||||
elog(WARNING, "mock function call " STR(TIMESCALEDB_VERSION_MOD));
|
||||
PG_RETURN_VOID();
|
||||
}
|
1
test/loader-mock/src/version.h
Normal file
1
test/loader-mock/src/version.h
Normal file
@ -0,0 +1 @@
|
||||
/* Overwrite main version.h so we could inject our own version #s here. */
|
@ -7,6 +7,7 @@ PG_REGRESS_PSQL=$1
|
||||
PSQL=${PSQL:-$PG_REGRESS_PSQL}
|
||||
TEST_PGUSER=${TEST_PGUSER:-postgres}
|
||||
TEST_DBNAME=${TEST_DBNAME:-single}
|
||||
TEST_DBNAME2=${TEST_DBNAME2:-${TEST_DBNAME}_2}
|
||||
TEST_INPUT_DIR=${TEST_INPUT_DIR:-${EXE_DIR}}
|
||||
TEST_OUTPUT_DIR=${TEST_OUTPUT_DIR:-${EXE_DIR}}
|
||||
|
||||
@ -36,9 +37,11 @@ mkdir -p ${TEST_TABLESPACE2_PATH}
|
||||
mkdir -p dump
|
||||
|
||||
# set role permissions and reset database
|
||||
${PSQL} $@ -U $USER -v ECHO=none -c "ALTER USER $TEST_ROLE_SUPERUSER WITH SUPERUSER;"
|
||||
${PSQL} $@ -U $USER -d postgres -v ECHO=none -c "ALTER USER $TEST_ROLE_SUPERUSER WITH SUPERUSER;"
|
||||
${PSQL} $@ -U $TEST_ROLE_SUPERUSER -d postgres -v ECHO=none -c "DROP DATABASE $TEST_DBNAME;" >/dev/null 2>&1 || :
|
||||
${PSQL} $@ -U $TEST_ROLE_SUPERUSER -d postgres -v ECHO=none -c "DROP DATABASE $TEST_DBNAME2;" >/dev/null 2>&1 || :
|
||||
${PSQL} $@ -U $TEST_ROLE_SUPERUSER -d postgres -v ECHO=none -c "CREATE DATABASE $TEST_DBNAME;"
|
||||
${PSQL} $@ -U $TEST_ROLE_SUPERUSER -d postgres -v ECHO=none -c "CREATE DATABASE $TEST_DBNAME2;"
|
||||
${PSQL} $@ -U $TEST_ROLE_SUPERUSER -d single -v ECHO=none -c "CREATE EXTENSION timescaledb;"
|
||||
${PSQL} $@ -U $TEST_ROLE_SUPERUSER -d single -v ECHO=none < ${EXE_DIR}/sql/utils/testsupport.sql >/dev/null 2>&1 || :
|
||||
|
||||
|
@ -49,6 +49,11 @@ set(TEST_FILES
|
||||
vacuum.sql
|
||||
version.sql)
|
||||
|
||||
IF(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
list(APPEND TEST_FILES
|
||||
loader.sql)
|
||||
ENDIF(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
|
||||
set(TEST_TEMPLATES
|
||||
parallel.sql.in
|
||||
partitioning.sql.in)
|
||||
|
167
test/sql/loader.sql
Normal file
167
test/sql/loader.sql
Normal file
@ -0,0 +1,167 @@
|
||||
\c single :ROLE_SUPERUSER
|
||||
|
||||
DROP EXTENSION timescaledb;
|
||||
--no extension
|
||||
\dx
|
||||
SELECT 1;
|
||||
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-1';
|
||||
--same backend as create extension;
|
||||
SELECT 1;
|
||||
\dx
|
||||
|
||||
--start new backend;
|
||||
\c single :ROLE_DEFAULT_PERM_USER
|
||||
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
--test fn call after load
|
||||
SELECT mock_function();
|
||||
\dx
|
||||
|
||||
\c single :ROLE_DEFAULT_PERM_USER
|
||||
--test fn call as first command
|
||||
SELECT mock_function();
|
||||
|
||||
|
||||
--use guc to prevent loading
|
||||
\c single :ROLE_SUPERUSER
|
||||
SET timescaledb.disable_load = 'on';
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
SET timescaledb.disable_load = 'off';
|
||||
SELECT 1;
|
||||
\set ON_ERROR_STOP 0
|
||||
SET timescaledb.disable_load = 'not bool';
|
||||
\set ON_ERROR_STOP 1
|
||||
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
--cannot update extension after .so of previous version already loaded
|
||||
ALTER EXTENSION timescaledb UPDATE TO 'mock-2';
|
||||
\set ON_ERROR_STOP 1
|
||||
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
\dx
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-1';
|
||||
\dx
|
||||
--start a new backend to update
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
ALTER EXTENSION timescaledb UPDATE TO 'mock-2';
|
||||
SELECT 1;
|
||||
\dx
|
||||
|
||||
--drop extension
|
||||
DROP EXTENSION timescaledb;
|
||||
SELECT 1;
|
||||
\dx
|
||||
|
||||
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-2';
|
||||
SELECT 1;
|
||||
\dx
|
||||
|
||||
--single still has old version
|
||||
\c single :ROLE_SUPERUSER
|
||||
SELECT 1;
|
||||
\dx
|
||||
|
||||
--try a broken upgrade
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
\dx
|
||||
\set ON_ERROR_STOP 0
|
||||
ALTER EXTENSION timescaledb UPDATE TO 'mock-3';
|
||||
\set ON_ERROR_STOP 1
|
||||
--should still be on mock-2
|
||||
SELECT 1;
|
||||
\dx
|
||||
|
||||
--drop extension
|
||||
DROP EXTENSION timescaledb;
|
||||
SELECT 1;
|
||||
\dx
|
||||
|
||||
--create extension anew, only upgrade was broken
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-3';
|
||||
SELECT 1;
|
||||
\dx
|
||||
DROP EXTENSION timescaledb;
|
||||
SELECT 1;
|
||||
|
||||
--mismatched version errors
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
\set ON_ERROR_STOP 0
|
||||
--mock-4 has mismatched versions, so the .so load should throw an error
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-4';
|
||||
\set ON_ERROR_STOP 1
|
||||
--mock-4 not installed.
|
||||
\dx
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
--should not allow since the errored-out mock-4 above already poisoned the well.
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-5';
|
||||
\set ON_ERROR_STOP 1
|
||||
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
--broken version and drop
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-broken';
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
--intentional broken version
|
||||
\dx
|
||||
SELECT 1;
|
||||
SELECT 1;
|
||||
--cannot drop extension; already loaded broken version
|
||||
DROP EXTENSION timescaledb;
|
||||
\set ON_ERROR_STOP 1
|
||||
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
--can drop extension now. Since drop first command.
|
||||
DROP EXTENSION timescaledb;
|
||||
\dx
|
||||
|
||||
--broken version and update to fixed
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-broken';
|
||||
\set ON_ERROR_STOP 0
|
||||
--intentional broken version
|
||||
SELECT 1;
|
||||
--cannot update extension; already loaded bad version
|
||||
ALTER EXTENSION timescaledb UPDATE TO 'mock-5';
|
||||
\set ON_ERROR_STOP 1
|
||||
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
--can update extension now.
|
||||
ALTER EXTENSION timescaledb UPDATE TO 'mock-5';
|
||||
SELECT 1;
|
||||
SELECT mock_function();
|
||||
|
||||
\c single_2 :ROLE_SUPERUSER
|
||||
ALTER EXTENSION timescaledb UPDATE TO 'mock-6';
|
||||
\set ON_ERROR_STOP 0
|
||||
--The mock-5->mock_6 upgrade is intentionally broken.
|
||||
--The mock_function was never changed to point to mock-6 in the update script.
|
||||
--Thus mock_function is defined incorrectly to point to the mock-5.so
|
||||
--This should be an error.
|
||||
SELECT mock_function();
|
||||
\set ON_ERROR_STOP 1
|
||||
\dx
|
||||
|
||||
--TEST: create extension when old .so already loaded
|
||||
\c single :ROLE_SUPERUSER
|
||||
--force load of extension with (\dx)
|
||||
\dx
|
||||
DROP EXTENSION timescaledb;
|
||||
\dx
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-2';
|
||||
\set ON_ERROR_STOP 1
|
||||
\dx
|
||||
--can create in a new session.
|
||||
\c single :ROLE_SUPERUSER
|
||||
CREATE EXTENSION timescaledb VERSION 'mock-2';
|
||||
\dx
|
||||
|
@ -1,7 +1,7 @@
|
||||
# timescaledb extension
|
||||
comment = 'Enables scalable inserts and complex queries for time-series data'
|
||||
default_version = '@PROJECT_VERSION_MOD@'
|
||||
module_pathname = '$libdir/timescaledb'
|
||||
module_pathname = '$libdir/timescaledb-@PROJECT_VERSION_MOD@'
|
||||
#extension cannot be relocatable once installed because it uses multiple schemas and that is forbidden by PG.
|
||||
#(though this extension is relocatable during installation).
|
||||
relocatable = false
|
||||
|
Loading…
x
Reference in New Issue
Block a user