mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-15 01:53:41 +08:00
Add parameter check_config to alter_job
Previously users had no way to update the check function registered with add_job. This commit adds a parameter check_config to alter_job to allow updating the check function field. Also, previously the signature expected from a check was of the form (job_id, config) and there was no validation that the check function given had the correct signature. This commit removes the job_id as it is not required and also checks that the check function has the correct signature when it is registered with add_job, preventing an error being thrown at job runtime.
This commit is contained in:
parent
e0f3e17575
commit
dc145b7485
@ -24,9 +24,10 @@ CREATE OR REPLACE FUNCTION @extschema@.alter_job(
|
||||
scheduled BOOL = NULL,
|
||||
config JSONB = NULL,
|
||||
next_start TIMESTAMPTZ = NULL,
|
||||
if_exists BOOL = FALSE
|
||||
if_exists BOOL = FALSE,
|
||||
check_config REGPROC = NULL
|
||||
)
|
||||
RETURNS TABLE (job_id INTEGER, schedule_interval INTERVAL, max_runtime INTERVAL, max_retries INTEGER, retry_period INTERVAL, scheduled BOOL, config JSONB, next_start TIMESTAMPTZ)
|
||||
RETURNS TABLE (job_id INTEGER, schedule_interval INTERVAL, max_runtime INTERVAL, max_retries INTEGER, retry_period INTERVAL, scheduled BOOL, config JSONB, next_start TIMESTAMPTZ, check_config TEXT)
|
||||
AS '@MODULE_PATHNAME@', 'ts_job_alter'
|
||||
LANGUAGE C VOLATILE;
|
||||
|
||||
|
@ -6,7 +6,7 @@ CREATE OR REPLACE PROCEDURE _timescaledb_internal.policy_retention(job_id INTEGE
|
||||
AS '@MODULE_PATHNAME@', 'ts_policy_retention_proc'
|
||||
LANGUAGE C;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.policy_retention_check(job_id INTEGER, config JSONB)
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.policy_retention_check(config JSONB)
|
||||
RETURNS void AS '@MODULE_PATHNAME@', 'ts_policy_retention_check'
|
||||
LANGUAGE C;
|
||||
|
||||
@ -14,7 +14,7 @@ CREATE OR REPLACE PROCEDURE _timescaledb_internal.policy_reorder(job_id INTEGER,
|
||||
AS '@MODULE_PATHNAME@', 'ts_policy_reorder_proc'
|
||||
LANGUAGE C;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.policy_reorder_check(job_id INTEGER, config JSONB)
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.policy_reorder_check(config JSONB)
|
||||
RETURNS void AS '@MODULE_PATHNAME@', 'ts_policy_reorder_check'
|
||||
LANGUAGE C;
|
||||
|
||||
@ -22,7 +22,7 @@ CREATE OR REPLACE PROCEDURE _timescaledb_internal.policy_recompression(job_id IN
|
||||
AS '@MODULE_PATHNAME@', 'ts_policy_recompression_proc'
|
||||
LANGUAGE C;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.policy_compression_check(job_id INTEGER, config JSONB)
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.policy_compression_check(config JSONB)
|
||||
RETURNS void AS '@MODULE_PATHNAME@', 'ts_policy_compression_check'
|
||||
LANGUAGE C;
|
||||
|
||||
@ -30,7 +30,7 @@ CREATE OR REPLACE PROCEDURE _timescaledb_internal.policy_refresh_continuous_aggr
|
||||
AS '@MODULE_PATHNAME@', 'ts_policy_refresh_cagg_proc'
|
||||
LANGUAGE C;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.policy_refresh_continuous_aggregate_check(job_id INTEGER, config JSONB)
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.policy_refresh_continuous_aggregate_check(config JSONB)
|
||||
RETURNS void AS '@MODULE_PATHNAME@', 'ts_policy_refresh_cagg_check'
|
||||
LANGUAGE C;
|
||||
|
||||
|
@ -22,11 +22,8 @@ ALTER TABLE _timescaledb_catalog.chunk
|
||||
|
||||
CREATE INDEX chunk_osm_chunk_idx ON _timescaledb_catalog.chunk (osm_chunk, hypertable_id);
|
||||
|
||||
DROP FUNCTION IF EXISTS @extschema@.add_job;
|
||||
DROP FUNCTION IF EXISTS _timescaledb_internal.policy_retention_check(INTEGER, JSONB);
|
||||
DROP FUNCTION IF EXISTS _timescaledb_internal.policy_compression_check(INTEGER, JSONB);
|
||||
DROP FUNCTION IF EXISTS _timescaledb_internal.policy_reorder_check(INTEGER, JSONB);
|
||||
DROP FUNCTION IF EXISTS _timescaledb_internal.policy_refresh_continuous_aggregate_check(INTEGER, JSONB);
|
||||
DROP FUNCTION IF EXISTS @extschema@.add_job(REGPROC, INTERVAL, JSONB, TIMESTAMPTZ, BOOL);
|
||||
DROP FUNCTION IF EXISTS @extschema@.alter_job(INTEGER, INTERVAL, INTERVAL, INTEGER, INTERVAL, BOOL, JSONB, TIMESTAMPTZ, BOOL);
|
||||
|
||||
-- add fields for check function
|
||||
ALTER TABLE _timescaledb_config.bgw_job
|
||||
@ -71,3 +68,5 @@ SET
|
||||
check_name = 'policy_refresh_continuous_aggregate_check'
|
||||
WHERE proc_schema = '_timescaledb_internal'
|
||||
AND proc_name = 'policy_refresh_continuous_aggregate';
|
||||
|
||||
DROP VIEW IF EXISTS timescaledb_information.jobs;
|
||||
|
@ -176,7 +176,7 @@ DROP TABLE _timescaledb_config.bgw_job;
|
||||
|
||||
CREATE SEQUENCE _timescaledb_config.bgw_job_id_seq MINVALUE 1000;
|
||||
SELECT pg_catalog.pg_extension_config_dump('_timescaledb_config.bgw_job_id_seq', '');
|
||||
SELECT setval('_timescaledb_config.bgw_job_id_seq', last_value, is_called)
|
||||
SELECT pg_catalog.setval('_timescaledb_config.bgw_job_id_seq', last_value, is_called)
|
||||
FROM _timescaledb_internal.tmp_bgw_job_seq_value;
|
||||
DROP TABLE _timescaledb_internal.tmp_bgw_job_seq_value;
|
||||
|
||||
@ -218,8 +218,31 @@ ALTER TABLE _timescaledb_internal.bgw_policy_chunk_stats
|
||||
FOREIGN KEY(job_id) REFERENCES _timescaledb_config.bgw_job(id)
|
||||
ON DELETE CASCADE;
|
||||
|
||||
DROP FUNCTION IF EXISTS @extschema@.add_job;
|
||||
DROP FUNCTION IF EXISTS @extschema@.add_job(REGPROC, INTERVAL, JSONB, TIMESTAMPTZ, BOOL, REGPROC);
|
||||
DROP FUNCTION IF EXISTS _timescaledb_internal.policy_retention_check(JSONB);
|
||||
DROP FUNCTION IF EXISTS _timescaledb_internal.policy_compression_check(JSONB);
|
||||
DROP FUNCTION IF EXISTS _timescaledb_internal.policy_reorder_check(JSONB);
|
||||
DROP FUNCTION IF EXISTS _timescaledb_internal.policy_refresh_continuous_aggregate_check(JSONB);
|
||||
DROP FUNCTION IF EXISTS @extschema@.alter_job(INTEGER, INTERVAL, INTERVAL, INTEGER, INTERVAL, BOOL, JSONB, TIMESTAMPTZ, BOOL, REGPROC);
|
||||
|
||||
CREATE FUNCTION @extschema@.add_job(proc REGPROC,
|
||||
schedule_interval INTERVAL,
|
||||
config JSONB = NULL,
|
||||
initial_start TIMESTAMPTZ = NULL,
|
||||
scheduled BOOL = true)
|
||||
RETURNS INTEGER AS '@MODULE_PATHNAME@', 'ts_job_add' LANGUAGE C VOLATILE;
|
||||
|
||||
CREATE FUNCTION @extschema@.alter_job(
|
||||
job_id INTEGER,
|
||||
schedule_interval INTERVAL = NULL,
|
||||
max_runtime INTERVAL = NULL,
|
||||
max_retries INTEGER = NULL,
|
||||
retry_period INTERVAL = NULL,
|
||||
scheduled BOOL = NULL,
|
||||
config JSONB = NULL,
|
||||
next_start TIMESTAMPTZ = NULL,
|
||||
if_exists BOOL = FALSE
|
||||
)
|
||||
RETURNS TABLE (job_id INTEGER, schedule_interval INTERVAL, max_runtime INTERVAL, max_retries INTEGER, retry_period INTERVAL, scheduled BOOL, config JSONB, next_start TIMESTAMPTZ)
|
||||
AS '@MODULE_PATHNAME@', 'ts_job_alter'
|
||||
LANGUAGE C VOLATILE;
|
||||
|
@ -98,7 +98,9 @@ SELECT j.id AS job_id,
|
||||
j.config,
|
||||
js.next_start,
|
||||
ht.schema_name AS hypertable_schema,
|
||||
ht.table_name AS hypertable_name
|
||||
ht.table_name AS hypertable_name,
|
||||
j.check_schema,
|
||||
j.check_name
|
||||
FROM _timescaledb_config.bgw_job j
|
||||
LEFT JOIN _timescaledb_catalog.hypertable ht ON ht.id = j.hypertable_id
|
||||
LEFT JOIN _timescaledb_internal.bgw_job_stat js ON js.job_id = j.id;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <catalog/pg_authid.h>
|
||||
#include <nodes/makefuncs.h>
|
||||
#include <parser/parse_func.h>
|
||||
#include <parser/parser.h>
|
||||
#include <postmaster/bgworker.h>
|
||||
#include <storage/ipc.h>
|
||||
#include <tcop/tcopprot.h>
|
||||
@ -109,16 +110,21 @@ job_execute_procedure(FuncExpr *funcexpr)
|
||||
void
|
||||
ts_bgw_job_run_config_check(Oid check, int32 job_id, Jsonb *config)
|
||||
{
|
||||
List *args =
|
||||
list_make2(makeConst(INT4OID, -1, InvalidOid, 4, Int32GetDatum(job_id), false, true),
|
||||
makeConst(JSONBOID, -1, InvalidOid, -1, JsonbPGetDatum(config), false, false));
|
||||
FuncExpr *funcexpr =
|
||||
makeFuncExpr(check, VOIDOID, args, InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL);
|
||||
|
||||
/* Nothing to check if there is no check function provided */
|
||||
if (!OidIsValid(check))
|
||||
return;
|
||||
|
||||
/* NULL config may be valid */
|
||||
Const *arg;
|
||||
if (config == NULL)
|
||||
arg = makeNullConst(JSONBOID, -1, InvalidOid);
|
||||
else
|
||||
arg = makeConst(JSONBOID, -1, InvalidOid, -1, JsonbPGetDatum(config), false, false);
|
||||
|
||||
List *args = list_make1(arg);
|
||||
FuncExpr *funcexpr =
|
||||
makeFuncExpr(check, VOIDOID, args, InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL);
|
||||
|
||||
switch (get_func_prokind(check))
|
||||
{
|
||||
case PROKIND_FUNCTION:
|
||||
@ -140,10 +146,8 @@ ts_bgw_job_run_config_check(Oid check, int32 job_id, Jsonb *config)
|
||||
static void
|
||||
job_config_check(BgwJob *job, Jsonb *config)
|
||||
{
|
||||
const Oid proc_args[] = { INT4OID, JSONBOID };
|
||||
List *name;
|
||||
Oid proc;
|
||||
bool started = false;
|
||||
ObjectWithArgs *object;
|
||||
|
||||
/* Both should either be empty or contain a schema and name */
|
||||
Assert((strlen(NameStr(job->fd.check_schema)) == 0) ==
|
||||
@ -153,27 +157,25 @@ job_config_check(BgwJob *job, Jsonb *config)
|
||||
if (strlen(NameStr(job->fd.check_name)) == 0)
|
||||
return;
|
||||
|
||||
if (!IsTransactionOrTransactionBlock())
|
||||
{
|
||||
started = true;
|
||||
StartTransactionCommand();
|
||||
/* executing sql functions requires snapshot */
|
||||
PushActiveSnapshot(GetTransactionSnapshot());
|
||||
}
|
||||
object = makeNode(ObjectWithArgs);
|
||||
|
||||
/* We are using LookupFuncName here, which will find functions but not
|
||||
* procedures. We could use LookupFuncWithArgs here instead. */
|
||||
name = list_make2(makeString(NameStr(job->fd.check_schema)),
|
||||
makeString(NameStr(job->fd.check_name)));
|
||||
proc = LookupFuncName(name, 2, proc_args, false);
|
||||
ts_bgw_job_run_config_check(proc, job->fd.id, config);
|
||||
if (started)
|
||||
{
|
||||
/* if job does its own transaction handling it might not have set a snapshot */
|
||||
if (ActiveSnapshotSet())
|
||||
PopActiveSnapshot();
|
||||
CommitTransactionCommand();
|
||||
}
|
||||
object->objname = list_make2(makeString(NameStr(job->fd.check_schema)),
|
||||
makeString(NameStr(job->fd.check_name)));
|
||||
object->objargs = list_make1(SystemTypeName("jsonb"));
|
||||
proc = LookupFuncWithArgs(OBJECT_ROUTINE, object, true);
|
||||
|
||||
/* a check function has been registered but it can't be found anymore
|
||||
because it was dropped or renamed. Allow alter_job to run if that's the case
|
||||
without validating the config but also print a warning */
|
||||
if (OidIsValid(proc))
|
||||
ts_bgw_job_run_config_check(proc, job->fd.id, config);
|
||||
else
|
||||
elog(WARNING,
|
||||
"function or procedure %s.%s(config jsonb) not found, skipping config validation for "
|
||||
"job %d",
|
||||
NameStr(job->fd.check_schema),
|
||||
NameStr(job->fd.check_name),
|
||||
job->fd.id);
|
||||
}
|
||||
|
||||
static BgwJob *
|
||||
@ -782,9 +784,24 @@ bgw_job_tuple_update_by_id(TupleInfo *ti, void *const data)
|
||||
repl[AttrNumberGetAttrOffset(Anum_bgw_job_scheduled)] = true;
|
||||
|
||||
repl[AttrNumberGetAttrOffset(Anum_bgw_job_config)] = true;
|
||||
|
||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_check_schema)] =
|
||||
NameGetDatum(&updated_job->fd.check_schema);
|
||||
repl[AttrNumberGetAttrOffset(Anum_bgw_job_check_schema)] = true;
|
||||
|
||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_check_name)] =
|
||||
NameGetDatum(&updated_job->fd.check_name);
|
||||
repl[AttrNumberGetAttrOffset(Anum_bgw_job_check_name)] = true;
|
||||
|
||||
if (strlen(NameStr(updated_job->fd.check_name)) == 0)
|
||||
{
|
||||
isnull[AttrNumberGetAttrOffset(Anum_bgw_job_check_name)] = true;
|
||||
isnull[AttrNumberGetAttrOffset(Anum_bgw_job_check_schema)] = true;
|
||||
}
|
||||
|
||||
if (updated_job->fd.config)
|
||||
{
|
||||
job_config_check(bgw_job_from_tupleinfo(ti, sizeof(BgwJob)), updated_job->fd.config);
|
||||
job_config_check(updated_job, updated_job->fd.config);
|
||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_config)] =
|
||||
JsonbPGetDatum(updated_job->fd.config);
|
||||
}
|
||||
|
@ -6,10 +6,8 @@
|
||||
|
||||
#include <postgres.h>
|
||||
#include <utils/builtins.h>
|
||||
#include <jsonb_utils.h>
|
||||
|
||||
#include "bgw/job.h"
|
||||
#include "dimension.h"
|
||||
#include "policy.h"
|
||||
|
||||
void
|
||||
|
@ -158,11 +158,8 @@ validate_compress_after_type(Oid partitioning_type, Oid compress_after_type)
|
||||
Datum
|
||||
policy_compression_check(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (PG_NARGS() != 2 || PG_ARGISNULL(0) || PG_ARGISNULL(1))
|
||||
PG_RETURN_VOID();
|
||||
|
||||
PolicyCompressionData policy_data;
|
||||
policy_compression_read_and_validate_config(PG_GETARG_JSONB_P(1), &policy_data);
|
||||
policy_compression_read_and_validate_config(PG_GETARG_JSONB_P(0), &policy_data);
|
||||
ts_cache_release(policy_data.hcache);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
|
@ -220,10 +220,7 @@ policy_refresh_cagg_proc(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
policy_refresh_cagg_check(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (PG_NARGS() != 2 || PG_ARGISNULL(0) || PG_ARGISNULL(1))
|
||||
PG_RETURN_VOID();
|
||||
|
||||
policy_refresh_cagg_read_and_validate_config(PG_GETARG_JSONB_P(1), NULL);
|
||||
policy_refresh_cagg_read_and_validate_config(PG_GETARG_JSONB_P(0), NULL);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
@ -10,6 +10,9 @@
|
||||
#include <utils/acl.h>
|
||||
#include <utils/builtins.h>
|
||||
|
||||
#include <parser/parse_func.h>
|
||||
#include <parser/parser.h>
|
||||
|
||||
#include <bgw/job.h>
|
||||
#include <bgw/job_stat.h>
|
||||
|
||||
@ -25,7 +28,37 @@
|
||||
/* Default retry period for reorder_jobs is currently 5 minutes */
|
||||
#define DEFAULT_RETRY_PERIOD (5 * USECS_PER_MINUTE)
|
||||
|
||||
#define ALTER_JOB_NUM_COLS 8
|
||||
#define ALTER_JOB_NUM_COLS 9
|
||||
|
||||
/*
|
||||
* This function ensures that the check function has the required signature
|
||||
* @param check A valid Oid
|
||||
*/
|
||||
static inline void
|
||||
validate_check_signature(Oid check)
|
||||
{
|
||||
Oid proc = InvalidOid;
|
||||
ObjectWithArgs *object;
|
||||
NameData check_name = { 0 };
|
||||
NameData check_schema = { 0 };
|
||||
|
||||
namestrcpy(&check_schema, get_namespace_name(get_func_namespace(check)));
|
||||
namestrcpy(&check_name, get_func_name(check));
|
||||
|
||||
object = makeNode(ObjectWithArgs);
|
||||
object->objname =
|
||||
list_make2(makeString(NameStr(check_schema)), makeString(NameStr(check_name)));
|
||||
object->objargs = list_make1(SystemTypeName("jsonb"));
|
||||
proc = LookupFuncWithArgs(OBJECT_ROUTINE, object, true);
|
||||
|
||||
if (!OidIsValid(proc))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("function or procedure %s.%s(config jsonb) not found",
|
||||
NameStr(check_schema),
|
||||
NameStr(check_name)),
|
||||
errhint("The check function's signature must be (config jsonb).")));
|
||||
}
|
||||
|
||||
/*
|
||||
* CREATE FUNCTION add_job(
|
||||
@ -110,8 +143,11 @@ job_add(PG_FUNCTION_ARGS)
|
||||
namestrcpy(&proc_name, func_name);
|
||||
namestrcpy(&owner_name, GetUserNameFromId(owner, false));
|
||||
|
||||
if (config)
|
||||
ts_bgw_job_run_config_check(check, 0, config);
|
||||
/* The check exists but may not have the expected signature: (config jsonb) */
|
||||
if (OidIsValid(check))
|
||||
validate_check_signature(check);
|
||||
|
||||
ts_bgw_job_run_config_check(check, 0, config);
|
||||
|
||||
job_id = ts_bgw_job_insert_relation(&application_name,
|
||||
schedule_interval,
|
||||
@ -206,6 +242,7 @@ job_run(PG_FUNCTION_ARGS)
|
||||
* 6 config JSONB = NULL,
|
||||
* 7 next_start TIMESTAMPTZ = NULL
|
||||
* 8 if_exists BOOL = FALSE,
|
||||
* 9 check_config REGPROC = NULL
|
||||
* ) RETURNS TABLE (
|
||||
* job_id INTEGER,
|
||||
* schedule_interval INTERVAL,
|
||||
@ -215,6 +252,7 @@ job_run(PG_FUNCTION_ARGS)
|
||||
* scheduled BOOL,
|
||||
* config JSONB,
|
||||
* next_start TIMESTAMPTZ
|
||||
* check_config TEXT
|
||||
* )
|
||||
*/
|
||||
Datum
|
||||
@ -229,6 +267,13 @@ job_alter(PG_FUNCTION_ARGS)
|
||||
int job_id = PG_GETARG_INT32(0);
|
||||
bool if_exists = PG_GETARG_BOOL(8);
|
||||
BgwJob *job;
|
||||
NameData check_name = { 0 };
|
||||
NameData check_schema = { 0 };
|
||||
Oid check = PG_ARGISNULL(9) ? InvalidOid : PG_GETARG_OID(9);
|
||||
char *check_name_str = NULL;
|
||||
/* Added space for period and NULL */
|
||||
char schema_qualified_check_name[2 * NAMEDATALEN + 2] = { 0 };
|
||||
bool unregister_check = (!PG_ARGISNULL(9) && !OidIsValid(check));
|
||||
|
||||
TS_PREVENT_FUNC_IF_READ_ONLY();
|
||||
|
||||
@ -259,6 +304,50 @@ job_alter(PG_FUNCTION_ARGS)
|
||||
if (!PG_ARGISNULL(6))
|
||||
job->fd.config = PG_GETARG_JSONB_P(6);
|
||||
|
||||
if (!PG_ARGISNULL(9))
|
||||
{
|
||||
if (OidIsValid(check))
|
||||
{
|
||||
check_name_str = get_func_name(check);
|
||||
if (check_name_str == NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("function with OID %d does not exist", check)));
|
||||
|
||||
if (pg_proc_aclcheck(check, GetUserId(), ACL_EXECUTE) != ACLCHECK_OK)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("permission denied for function \"%s\"", check_name_str),
|
||||
errhint("Job owner must have EXECUTE privilege on the function.")));
|
||||
|
||||
namestrcpy(&check_schema, get_namespace_name(get_func_namespace(check)));
|
||||
namestrcpy(&check_name, check_name_str);
|
||||
|
||||
/* The check exists but may not have the expected signature: (config jsonb) */
|
||||
validate_check_signature(check);
|
||||
|
||||
namestrcpy(&job->fd.check_schema, NameStr(check_schema));
|
||||
namestrcpy(&job->fd.check_name, NameStr(check_name));
|
||||
snprintf(schema_qualified_check_name,
|
||||
sizeof(schema_qualified_check_name) / sizeof(schema_qualified_check_name[0]),
|
||||
"%s.%s",
|
||||
NameStr(check_schema),
|
||||
check_name_str);
|
||||
}
|
||||
}
|
||||
else
|
||||
snprintf(schema_qualified_check_name,
|
||||
sizeof(schema_qualified_check_name) / sizeof(schema_qualified_check_name[0]),
|
||||
"%s.%s",
|
||||
NameStr(job->fd.check_schema),
|
||||
NameStr(job->fd.check_name));
|
||||
|
||||
if (unregister_check)
|
||||
{
|
||||
NameData empty_namedata = { 0 };
|
||||
namestrcpy(&job->fd.check_schema, NameStr(empty_namedata));
|
||||
namestrcpy(&job->fd.check_name, NameStr(empty_namedata));
|
||||
}
|
||||
ts_bgw_job_update_by_id(job_id, job);
|
||||
|
||||
if (!PG_ARGISNULL(7))
|
||||
@ -285,6 +374,13 @@ job_alter(PG_FUNCTION_ARGS)
|
||||
|
||||
values[7] = TimestampTzGetDatum(next_start);
|
||||
|
||||
if (unregister_check)
|
||||
nulls[8] = true;
|
||||
else if (strlen(NameStr(job->fd.check_schema)) > 0)
|
||||
values[8] = CStringGetTextDatum(schema_qualified_check_name);
|
||||
else
|
||||
nulls[8] = true;
|
||||
|
||||
tuple = heap_form_tuple(tupdesc, values, nulls);
|
||||
return HeapTupleGetDatum(tuple);
|
||||
}
|
||||
|
@ -109,12 +109,9 @@ check_valid_index(Hypertable *ht, Name index_name)
|
||||
Datum
|
||||
policy_reorder_check(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (PG_NARGS() != 2 || PG_ARGISNULL(0) || PG_ARGISNULL(1))
|
||||
PG_RETURN_VOID();
|
||||
|
||||
TS_PREVENT_FUNC_IF_READ_ONLY();
|
||||
|
||||
policy_reorder_read_and_validate_config(PG_GETARG_JSONB_P(1), NULL);
|
||||
policy_reorder_read_and_validate_config(PG_GETARG_JSONB_P(0), NULL);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
@ -43,12 +43,9 @@ policy_retention_proc(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
policy_retention_check(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (PG_NARGS() != 2 || PG_ARGISNULL(0) || PG_ARGISNULL(1))
|
||||
PG_RETURN_VOID();
|
||||
|
||||
TS_PREVENT_FUNC_IF_READ_ONLY();
|
||||
|
||||
policy_retention_read_and_validate_config(PG_GETARG_JSONB_P(1), NULL);
|
||||
policy_retention_read_and_validate_config(PG_GETARG_JSONB_P(0), NULL);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
@ -74,13 +74,13 @@ SELECT add_job('custom_func_definer', '1h', config:='{"type":"function"}'::jsonb
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM timescaledb_information.jobs WHERE job_id != 1 ORDER BY 1;
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name
|
||||
--------+----------------------------+-------------------+-------------+-------------+--------------+-------------+---------------------+-------------------+-----------+-----------------------+------------+-------------------+-----------------
|
||||
1000 | User-Defined Action [1000] | @ 1 hour | @ 0 | -1 | @ 5 mins | public | custom_func | default_perm_user | t | {"type": "function"} | | |
|
||||
1001 | User-Defined Action [1001] | @ 1 hour | @ 0 | -1 | @ 5 mins | public | custom_proc | default_perm_user | t | {"type": "procedure"} | | |
|
||||
1002 | User-Defined Action [1002] | @ 1 hour | @ 0 | -1 | @ 5 mins | public | custom_proc2 | default_perm_user | t | {"type": "procedure"} | | |
|
||||
1003 | User-Defined Action [1003] | @ 1 hour | @ 0 | -1 | @ 5 mins | public | custom_func | default_perm_user | t | {"type": "function"} | | |
|
||||
1004 | User-Defined Action [1004] | @ 1 hour | @ 0 | -1 | @ 5 mins | public | custom_func_definer | default_perm_user | t | {"type": "function"} | | |
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name | check_schema | check_name
|
||||
--------+----------------------------+-------------------+-------------+-------------+--------------+-------------+---------------------+-------------------+-----------+-----------------------+------------+-------------------+-----------------+--------------+------------
|
||||
1000 | User-Defined Action [1000] | @ 1 hour | @ 0 | -1 | @ 5 mins | public | custom_func | default_perm_user | t | {"type": "function"} | | | | |
|
||||
1001 | User-Defined Action [1001] | @ 1 hour | @ 0 | -1 | @ 5 mins | public | custom_proc | default_perm_user | t | {"type": "procedure"} | | | | |
|
||||
1002 | User-Defined Action [1002] | @ 1 hour | @ 0 | -1 | @ 5 mins | public | custom_proc2 | default_perm_user | t | {"type": "procedure"} | | | | |
|
||||
1003 | User-Defined Action [1003] | @ 1 hour | @ 0 | -1 | @ 5 mins | public | custom_func | default_perm_user | t | {"type": "function"} | | | | |
|
||||
1004 | User-Defined Action [1004] | @ 1 hour | @ 0 | -1 | @ 5 mins | public | custom_func_definer | default_perm_user | t | {"type": "function"} | | | | |
|
||||
(5 rows)
|
||||
|
||||
SELECT count(*) FROM _timescaledb_config.bgw_job WHERE config->>'type' IN ('procedure', 'function');
|
||||
@ -574,3 +574,328 @@ SELECT _timescaledb_internal.stop_background_workers();
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT _timescaledb_internal.restart_background_workers();
|
||||
restart_background_workers
|
||||
----------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
-- add test for custom jobs with custom check functions
|
||||
-- create the functions/procedures to be used as checking functions
|
||||
CREATE OR REPLACE PROCEDURE test_config_check_proc(config jsonb)
|
||||
LANGUAGE PLPGSQL
|
||||
AS $$
|
||||
DECLARE
|
||||
drop_after interval;
|
||||
BEGIN
|
||||
SELECT jsonb_object_field_text (config, 'drop_after')::interval INTO STRICT drop_after;
|
||||
IF drop_after IS NULL THEN
|
||||
RAISE EXCEPTION 'Config must be not NULL and have drop_after';
|
||||
END IF ;
|
||||
END
|
||||
$$;
|
||||
CREATE OR REPLACE FUNCTION test_config_check_func(config jsonb) RETURNS VOID
|
||||
AS $$
|
||||
DECLARE
|
||||
drop_after interval;
|
||||
BEGIN
|
||||
IF config IS NULL THEN
|
||||
RETURN;
|
||||
END IF;
|
||||
SELECT jsonb_object_field_text (config, 'drop_after')::interval INTO STRICT drop_after;
|
||||
IF drop_after IS NULL THEN
|
||||
RAISE EXCEPTION 'Config can be NULL but must have drop_after if not';
|
||||
END IF ;
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
-- step 2, create a procedure to run as a custom job
|
||||
CREATE OR REPLACE PROCEDURE test_proc_with_check(job_id int, config jsonb)
|
||||
LANGUAGE PLPGSQL
|
||||
AS $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'Will only print this if config passes checks, my config is %', config;
|
||||
END
|
||||
$$;
|
||||
-- step 3, add the job with the config check function passed as argument
|
||||
-- test procedures
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_config_check_proc'::regproc);
|
||||
ERROR: Config must be not NULL and have drop_after
|
||||
select add_job('test_proc_with_check', '5 secs', config => NULL, check_config => 'test_config_check_proc'::regproc);
|
||||
ERROR: Config must be not NULL and have drop_after
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{"drop_after": "chicken"}', check_config => 'test_config_check_proc'::regproc);
|
||||
ERROR: invalid input syntax for type interval: "chicken"
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{"drop_after": "2 weeks"}', check_config => 'test_config_check_proc'::regproc)
|
||||
as job_with_proc_check_id \gset
|
||||
-- test functions
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_config_check_func'::regproc);
|
||||
ERROR: Config can be NULL but must have drop_after if not
|
||||
select add_job('test_proc_with_check', '5 secs', config => NULL, check_config => 'test_config_check_func'::regproc);
|
||||
add_job
|
||||
---------
|
||||
1006
|
||||
(1 row)
|
||||
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{"drop_after": "chicken"}', check_config => 'test_config_check_func'::regproc);
|
||||
ERROR: invalid input syntax for type interval: "chicken"
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{"drop_after": "2 weeks"}', check_config => 'test_config_check_func'::regproc)
|
||||
as job_with_func_check_id \gset
|
||||
--- test alter_job
|
||||
select alter_job(:job_with_func_check_id, config => '{"drop_after":"chicken"}');
|
||||
ERROR: invalid input syntax for type interval: "chicken"
|
||||
select alter_job(:job_with_func_check_id, config => '{"drop_after":"5 years"}');
|
||||
alter_job
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
(1007,"@ 5 secs","@ 0",-1,"@ 5 mins",t,"{""drop_after"": ""5 years""}",-infinity,public.test_config_check_func)
|
||||
(1 row)
|
||||
|
||||
select alter_job(:job_with_proc_check_id, config => '{"drop_after":"4 days"}');
|
||||
alter_job
|
||||
----------------------------------------------------------------------------------------------------------------
|
||||
(1005,"@ 5 secs","@ 0",-1,"@ 5 mins",t,"{""drop_after"": ""4 days""}",-infinity,public.test_config_check_proc)
|
||||
(1 row)
|
||||
|
||||
-- test that jobs with an incorrect check function signature will not be registered
|
||||
-- these are all incorrect function signatures
|
||||
CREATE OR REPLACE FUNCTION test_config_check_func_0args() RETURNS VOID
|
||||
AS $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'I take no arguments and will validate anything you give me!';
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
CREATE OR REPLACE FUNCTION test_config_check_func_2args(config jsonb, intarg int) RETURNS VOID
|
||||
AS $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'I take two arguments (jsonb, int) and I should fail to run!';
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
CREATE OR REPLACE FUNCTION test_config_check_func_intarg(config int) RETURNS VOID
|
||||
AS $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'I take one argument which is an integer and I should fail to run!';
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
-- -- this should fail, it has an incorrect check function
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_config_check_func_0args'::regproc);
|
||||
ERROR: function or procedure public.test_config_check_func_0args(config jsonb) not found
|
||||
-- -- so should this
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_config_check_func_2args'::regproc);
|
||||
ERROR: function or procedure public.test_config_check_func_2args(config jsonb) not found
|
||||
-- and this
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_config_check_func_intarg'::regproc);
|
||||
ERROR: function or procedure public.test_config_check_func_intarg(config jsonb) not found
|
||||
-- and this fails as it calls a nonexistent function
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_nonexistent_check_func'::regproc);
|
||||
ERROR: function "test_nonexistent_check_func" does not exist at character 82
|
||||
-- when called with a valid check function and a NULL config no check should occur
|
||||
CREATE OR REPLACE FUNCTION test_config_check_func(config jsonb) RETURNS VOID
|
||||
AS $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'This message will get printed for both NULL and not NULL config';
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
SET client_min_messages = NOTICE;
|
||||
-- check done for both NULL and non-NULL config
|
||||
select add_job('test_proc_with_check', '5 secs', config => NULL, check_config => 'test_config_check_func'::regproc);
|
||||
NOTICE: This message will get printed for both NULL and not NULL config
|
||||
add_job
|
||||
---------
|
||||
1008
|
||||
(1 row)
|
||||
|
||||
-- check done
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_config_check_func'::regproc) as job_id \gset
|
||||
NOTICE: This message will get printed for both NULL and not NULL config
|
||||
-- check function not returning void
|
||||
CREATE OR REPLACE FUNCTION test_config_check_func_returns_int(config jsonb) RETURNS INT
|
||||
AS $$
|
||||
BEGIN
|
||||
raise notice 'I print a message, and then I return least(1,2)';
|
||||
RETURN LEAST(1, 2);
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_config_check_func_returns_int'::regproc) as job_id_int \gset
|
||||
NOTICE: I print a message, and then I return least(1,2)
|
||||
-- drop the registered check function, verify that alter_job will work and print a warning that
|
||||
-- the check is being skipped due to the check function missing
|
||||
ALTER FUNCTION test_config_check_func RENAME TO renamed_func;
|
||||
select alter_job(:job_id, schedule_interval => '1 hour');
|
||||
WARNING: function or procedure public.test_config_check_func(config jsonb) not found, skipping config validation for job 1009
|
||||
alter_job
|
||||
------------------------------------------------------------------------------------
|
||||
(1009,"@ 1 hour","@ 0",-1,"@ 5 mins",t,{},-infinity,public.test_config_check_func)
|
||||
(1 row)
|
||||
|
||||
DROP FUNCTION test_config_check_func_returns_int;
|
||||
select alter_job(:job_id_int, config => '{"field":"value"}');
|
||||
WARNING: function or procedure public.test_config_check_func_returns_int(config jsonb) not found, skipping config validation for job 1010
|
||||
alter_job
|
||||
----------------------------------------------------------------------------------------------------------------------
|
||||
(1010,"@ 5 secs","@ 0",-1,"@ 5 mins",t,"{""field"": ""value""}",-infinity,public.test_config_check_func_returns_int)
|
||||
(1 row)
|
||||
|
||||
-- rename the check function and then call alter_job to register the new name
|
||||
select alter_job(:job_id, check_config => 'renamed_func'::regproc);
|
||||
NOTICE: This message will get printed for both NULL and not NULL config
|
||||
alter_job
|
||||
--------------------------------------------------------------------------
|
||||
(1009,"@ 1 hour","@ 0",-1,"@ 5 mins",t,{},-infinity,public.renamed_func)
|
||||
(1 row)
|
||||
|
||||
-- run alter again, should get a config check
|
||||
select alter_job(:job_id, config => '{}');
|
||||
NOTICE: This message will get printed for both NULL and not NULL config
|
||||
alter_job
|
||||
--------------------------------------------------------------------------
|
||||
(1009,"@ 1 hour","@ 0",-1,"@ 5 mins",t,{},-infinity,public.renamed_func)
|
||||
(1 row)
|
||||
|
||||
-- do not drop the current check function but register a new one
|
||||
CREATE OR REPLACE FUNCTION substitute_check_func(config jsonb) RETURNS VOID
|
||||
AS $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'This message is a substitute of the previously printed one';
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
-- register the new check
|
||||
select alter_job(:job_id, check_config => 'substitute_check_func');
|
||||
NOTICE: This message is a substitute of the previously printed one
|
||||
alter_job
|
||||
-----------------------------------------------------------------------------------
|
||||
(1009,"@ 1 hour","@ 0",-1,"@ 5 mins",t,{},-infinity,public.substitute_check_func)
|
||||
(1 row)
|
||||
|
||||
select alter_job(:job_id, config => '{}');
|
||||
NOTICE: This message is a substitute of the previously printed one
|
||||
alter_job
|
||||
-----------------------------------------------------------------------------------
|
||||
(1009,"@ 1 hour","@ 0",-1,"@ 5 mins",t,{},-infinity,public.substitute_check_func)
|
||||
(1 row)
|
||||
|
||||
RESET client_min_messages;
|
||||
-- test an oid that doesn't exist
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 17424217::regproc);
|
||||
ERROR: function with OID 17424217 does not exist
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
-- test a function with insufficient privileges
|
||||
create schema test_schema;
|
||||
create role user_noexec with login;
|
||||
grant usage on schema test_schema to user_noexec;
|
||||
CREATE OR REPLACE FUNCTION test_schema.test_config_check_func_privileges(config jsonb) RETURNS VOID
|
||||
AS $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'This message will only get printed if privileges suffice';
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
revoke execute on function test_schema.test_config_check_func_privileges from public;
|
||||
-- verify the user doesn't have execute permissions on the function
|
||||
select has_function_privilege('user_noexec', 'test_schema.test_config_check_func_privileges(jsonb)', 'execute');
|
||||
has_function_privilege
|
||||
------------------------
|
||||
f
|
||||
(1 row)
|
||||
|
||||
\c :TEST_DBNAME user_noexec
|
||||
-- user_noexec should not have exec permissions on this function
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_schema.test_config_check_func_privileges'::regproc);
|
||||
ERROR: permission denied for function "test_config_check_func_privileges"
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
-- check that alter_job rejects a check function with invalid signature
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'renamed_func') as job_id_alter \gset
|
||||
NOTICE: This message will get printed for both NULL and not NULL config
|
||||
select alter_job(:job_id_alter, check_config => 'test_config_check_func_0args');
|
||||
ERROR: function or procedure public.test_config_check_func_0args(config jsonb) not found
|
||||
select alter_job(:job_id_alter);
|
||||
NOTICE: This message will get printed for both NULL and not NULL config
|
||||
alter_job
|
||||
--------------------------------------------------------------------------
|
||||
(1011,"@ 5 secs","@ 0",-1,"@ 5 mins",t,{},-infinity,public.renamed_func)
|
||||
(1 row)
|
||||
|
||||
-- test that we can unregister the check function
|
||||
select alter_job(:job_id_alter, check_config => 0);
|
||||
alter_job
|
||||
-------------------------------------------------------
|
||||
(1011,"@ 5 secs","@ 0",-1,"@ 5 mins",t,{},-infinity,)
|
||||
(1 row)
|
||||
|
||||
-- no message printed now
|
||||
select alter_job(:job_id_alter, config => '{}');
|
||||
alter_job
|
||||
-------------------------------------------------------
|
||||
(1011,"@ 5 secs","@ 0",-1,"@ 5 mins",t,{},-infinity,)
|
||||
(1 row)
|
||||
|
||||
-- test what happens if the check function contains a COMMIT
|
||||
-- procedure with transaction handling
|
||||
CREATE OR REPLACE PROCEDURE custom_proc2_jsonb(config jsonb) LANGUAGE PLPGSQL AS
|
||||
$$
|
||||
BEGIN
|
||||
-- RAISE NOTICE 'Starting some transactions inside procedure';
|
||||
INSERT INTO custom_log VALUES(1, $1, 'custom_proc 1 COMMIT');
|
||||
COMMIT;
|
||||
END
|
||||
$$;
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}') as job_id_err \gset
|
||||
select alter_job(:job_id_err, check_config => 'custom_proc2_jsonb');
|
||||
ERROR: portal snapshots (0) did not account for all active snapshots (1)
|
||||
select alter_job(:job_id_err, schedule_interval => '3 minutes');
|
||||
alter_job
|
||||
-------------------------------------------------------
|
||||
(1012,"@ 3 mins","@ 0",-1,"@ 5 mins",t,{},-infinity,)
|
||||
(1 row)
|
||||
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'custom_proc2_jsonb') as job_id_commit \gset
|
||||
ERROR: portal snapshots (0) did not account for all active snapshots (1)
|
||||
-- test the case where we have a background job that registers jobs with a check fn
|
||||
CREATE OR REPLACE PROCEDURE add_scheduled_jobs_with_check(job_id int, config jsonb) LANGUAGE PLPGSQL AS
|
||||
$$
|
||||
BEGIN
|
||||
perform add_job('test_proc_with_check', schedule_interval => '10 secs', config => '{}', check_config => 'renamed_func');
|
||||
END
|
||||
$$;
|
||||
select add_job('add_scheduled_jobs_with_check', schedule_interval => '1 hour') as last_job_id \gset
|
||||
-- wait for enough time
|
||||
SELECT wait_for_job_to_run(:last_job_id, 1);
|
||||
wait_for_job_to_run
|
||||
---------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
select total_runs, total_successes, last_run_status from timescaledb_information.job_stats where job_id = :last_job_id;
|
||||
total_runs | total_successes | last_run_status
|
||||
------------+-----------------+-----------------
|
||||
1 | 1 | Success
|
||||
(1 row)
|
||||
|
||||
-- test coverage for alter_job
|
||||
-- registering an invalid oid
|
||||
select alter_job(:job_id_alter, check_config => 123456789::regproc);
|
||||
ERROR: function with OID 123456789 does not exist
|
||||
-- registering a function with insufficient privileges
|
||||
\c :TEST_DBNAME user_noexec
|
||||
select * from add_job('test_proc_with_check', '5 secs', config => '{}') as job_id_owner \gset
|
||||
select * from alter_job(:job_id_owner, check_config => 'test_schema.test_config_check_func_privileges'::regproc);
|
||||
ERROR: permission denied for function "test_config_check_func_privileges"
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
DROP SCHEMA test_schema CASCADE;
|
||||
NOTICE: drop cascades to function test_schema.test_config_check_func_privileges(jsonb)
|
||||
DROP ROLE user_noexec;
|
||||
-- test with aggregate check proc
|
||||
create function jsonb_add (j1 jsonb, j2 jsonb) returns jsonb
|
||||
AS $$
|
||||
BEGIN
|
||||
RETURN j1 || j2;
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
create table jsonb_values (j jsonb, i int);
|
||||
insert into jsonb_values values ('{"refresh_after":"2 weeks"}', 1), ('{"compress_after":"2 weeks"}', 2), ('{"drop_after":"2 weeks"}', 3);
|
||||
CREATE AGGREGATE sum_jsb (jsonb)
|
||||
(
|
||||
sfunc = jsonb_add,
|
||||
stype = jsonb,
|
||||
initcond = '{}'
|
||||
);
|
||||
-- for test coverage, check unsupported aggregate type
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'sum_jsb'::regproc);
|
||||
ERROR: unsupported function type
|
||||
|
@ -1420,9 +1420,9 @@ SELECT wait_for_timer_to_run(0);
|
||||
SELECT insert_job('another', 'bgw_test_job_1', INTERVAL '100ms', INTERVAL '100s', INTERVAL '1s') AS job_id \gset
|
||||
-- call alter_job to trigger cache invalidation
|
||||
SELECT alter_job(:job_id,scheduled:=true);
|
||||
alter_job
|
||||
----------------------------------------------------------------
|
||||
(1026,"@ 0.1 secs","@ 1 min 40 secs",5,"@ 1 sec",t,,-infinity)
|
||||
alter_job
|
||||
-----------------------------------------------------------------
|
||||
(1026,"@ 0.1 secs","@ 1 min 40 secs",5,"@ 1 sec",t,,-infinity,)
|
||||
(1 row)
|
||||
|
||||
SELECT ts_bgw_params_reset_time(50000, true);
|
||||
@ -1522,9 +1522,9 @@ SELECT wait_for_timer_to_run(400000);
|
||||
SELECT insert_job('new_job', 'bgw_test_job_1', INTERVAL '10ms', INTERVAL '100s', INTERVAL '1s') AS job_id \gset
|
||||
-- call alter_job to trigger cache invalidation
|
||||
SELECT alter_job(:job_id,scheduled:=true);
|
||||
alter_job
|
||||
-----------------------------------------------------------------
|
||||
(1027,"@ 0.01 secs","@ 1 min 40 secs",5,"@ 1 sec",t,,-infinity)
|
||||
alter_job
|
||||
------------------------------------------------------------------
|
||||
(1027,"@ 0.01 secs","@ 1 min 40 secs",5,"@ 1 sec",t,,-infinity,)
|
||||
(1 row)
|
||||
|
||||
SELECT ts_bgw_params_reset_time(450000, true);
|
||||
|
@ -102,9 +102,9 @@ SELECT count(*) FROM _timescaledb_config.bgw_job WHERE proc_schema = '_timescale
|
||||
|
||||
-- job was created
|
||||
SELECT * FROM timescaledb_information.jobs WHERE job_id=:reorder_job_id;
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name
|
||||
--------+-----------------------+-------------------+-------------+-------------+--------------+-----------------------+----------------+-------------------+-----------+-------------------------------------------------------------------+------------+-------------------+--------------------
|
||||
1000 | Reorder Policy [1000] | @ 4 days | @ 0 | -1 | @ 5 mins | _timescaledb_internal | policy_reorder | default_perm_user | t | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} | | public | test_reorder_table
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name | check_schema | check_name
|
||||
--------+-----------------------+-------------------+-------------+-------------+--------------+-----------------------+----------------+-------------------+-----------+-------------------------------------------------------------------+------------+-------------------+--------------------+-----------------------+----------------------
|
||||
1000 | Reorder Policy [1000] | @ 4 days | @ 0 | -1 | @ 5 mins | _timescaledb_internal | policy_reorder | default_perm_user | t | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} | | public | test_reorder_table | _timescaledb_internal | policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
-- no stats
|
||||
@ -138,9 +138,9 @@ SELECT * FROM sorted_bgw_log;
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM timescaledb_information.jobs WHERE job_id=:reorder_job_id;
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name
|
||||
--------+-----------------------+-------------------+-------------+-------------+--------------+-----------------------+----------------+-------------------+-----------+-------------------------------------------------------------------+------------------------------+-------------------+--------------------
|
||||
1000 | Reorder Policy [1000] | @ 4 days | @ 0 | -1 | @ 5 mins | _timescaledb_internal | policy_reorder | default_perm_user | t | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} | Fri Dec 31 16:00:00 1999 PST | public | test_reorder_table
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name | check_schema | check_name
|
||||
--------+-----------------------+-------------------+-------------+-------------+--------------+-----------------------+----------------+-------------------+-----------+-------------------------------------------------------------------+------------------------------+-------------------+--------------------+-----------------------+----------------------
|
||||
1000 | Reorder Policy [1000] | @ 4 days | @ 0 | -1 | @ 5 mins | _timescaledb_internal | policy_reorder | default_perm_user | t | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} | Fri Dec 31 16:00:00 1999 PST | public | test_reorder_table | _timescaledb_internal | policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
-- job ran once, successfully
|
||||
@ -178,9 +178,9 @@ SELECT * FROM sorted_bgw_log;
|
||||
(4 rows)
|
||||
|
||||
SELECT * FROM timescaledb_information.jobs WHERE job_id=:reorder_job_id;
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name
|
||||
--------+-----------------------+-------------------+-------------+-------------+--------------+-----------------------+----------------+-------------------+-----------+-------------------------------------------------------------------+----------------------------------+-------------------+--------------------
|
||||
1000 | Reorder Policy [1000] | @ 4 days | @ 0 | -1 | @ 5 mins | _timescaledb_internal | policy_reorder | default_perm_user | t | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} | Fri Dec 31 16:00:00.025 1999 PST | public | test_reorder_table
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name | check_schema | check_name
|
||||
--------+-----------------------+-------------------+-------------+-------------+--------------+-----------------------+----------------+-------------------+-----------+-------------------------------------------------------------------+----------------------------------+-------------------+--------------------+-----------------------+----------------------
|
||||
1000 | Reorder Policy [1000] | @ 4 days | @ 0 | -1 | @ 5 mins | _timescaledb_internal | policy_reorder | default_perm_user | t | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} | Fri Dec 31 16:00:00.025 1999 PST | public | test_reorder_table | _timescaledb_internal | policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
-- two runs
|
||||
@ -222,9 +222,9 @@ SELECT * FROM sorted_bgw_log;
|
||||
(6 rows)
|
||||
|
||||
SELECT * FROM timescaledb_information.jobs WHERE job_id=:reorder_job_id;
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name
|
||||
--------+-----------------------+-------------------+-------------+-------------+--------------+-----------------------+----------------+-------------------+-----------+-------------------------------------------------------------------+---------------------------------+-------------------+--------------------
|
||||
1000 | Reorder Policy [1000] | @ 4 days | @ 0 | -1 | @ 5 mins | _timescaledb_internal | policy_reorder | default_perm_user | t | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} | Tue Jan 04 16:00:00.05 2000 PST | public | test_reorder_table
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name | check_schema | check_name
|
||||
--------+-----------------------+-------------------+-------------+-------------+--------------+-----------------------+----------------+-------------------+-----------+-------------------------------------------------------------------+---------------------------------+-------------------+--------------------+-----------------------+----------------------
|
||||
1000 | Reorder Policy [1000] | @ 4 days | @ 0 | -1 | @ 5 mins | _timescaledb_internal | policy_reorder | default_perm_user | t | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} | Tue Jan 04 16:00:00.05 2000 PST | public | test_reorder_table | _timescaledb_internal | policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
SELECT *
|
||||
@ -266,9 +266,9 @@ SELECT * FROM sorted_bgw_log;
|
||||
(7 rows)
|
||||
|
||||
SELECT * FROM timescaledb_information.jobs WHERE job_id=:reorder_job_id;
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name
|
||||
--------+-----------------------+-------------------+-------------+-------------+--------------+-----------------------+----------------+-------------------+-----------+-------------------------------------------------------------------+---------------------------------+-------------------+--------------------
|
||||
1000 | Reorder Policy [1000] | @ 4 days | @ 0 | -1 | @ 5 mins | _timescaledb_internal | policy_reorder | default_perm_user | t | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} | Tue Jan 04 16:00:00.05 2000 PST | public | test_reorder_table
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name | check_schema | check_name
|
||||
--------+-----------------------+-------------------+-------------+-------------+--------------+-----------------------+----------------+-------------------+-----------+-------------------------------------------------------------------+---------------------------------+-------------------+--------------------+-----------------------+----------------------
|
||||
1000 | Reorder Policy [1000] | @ 4 days | @ 0 | -1 | @ 5 mins | _timescaledb_internal | policy_reorder | default_perm_user | t | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} | Tue Jan 04 16:00:00.05 2000 PST | public | test_reorder_table | _timescaledb_internal | policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
SELECT *
|
||||
@ -305,8 +305,8 @@ SELECT remove_reorder_policy('test_reorder_table');
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM timescaledb_information.jobs WHERE job_id=:reorder_job_id;
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name
|
||||
--------+------------------+-------------------+-------------+-------------+--------------+-------------+-----------+-------+-----------+--------+------------+-------------------+-----------------
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name | check_schema | check_name
|
||||
--------+------------------+-------------------+-------------+-------------+--------------+-------------+-----------+-------+-----------+--------+------------+-------------------+-----------------+--------------+------------
|
||||
(0 rows)
|
||||
|
||||
SELECT job_id, next_start, last_finish as until_next, last_run_success, total_runs, total_successes, total_failures, total_crashes
|
||||
@ -336,8 +336,8 @@ SELECT * FROM sorted_bgw_log;
|
||||
(8 rows)
|
||||
|
||||
SELECT * FROM timescaledb_information.jobs WHERE job_id=:reorder_job_id;
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name
|
||||
--------+------------------+-------------------+-------------+-------------+--------------+-------------+-----------+-------+-----------+--------+------------+-------------------+-----------------
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name | check_schema | check_name
|
||||
--------+------------------+-------------------+-------------+-------------+--------------+-------------+-----------+-------+-----------+--------+------------+-------------------+-----------------+--------------+------------
|
||||
(0 rows)
|
||||
|
||||
-- still only 3 chunks clustered
|
||||
@ -409,15 +409,15 @@ SELECT count(*) FROM _timescaledb_config.bgw_job WHERE proc_schema = '_timescale
|
||||
(1 row)
|
||||
|
||||
SELECT alter_job(:drop_chunks_job_id, schedule_interval => INTERVAL '1 second');
|
||||
alter_job
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
(1001,"@ 1 sec","@ 5 mins",-1,"@ 5 mins",t,"{""drop_after"": ""@ 4 mons"", ""hypertable_id"": 2}",-infinity)
|
||||
alter_job
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1001,"@ 1 sec","@ 5 mins",-1,"@ 5 mins",t,"{""drop_after"": ""@ 4 mons"", ""hypertable_id"": 2}",-infinity,_timescaledb_internal.policy_retention_check)
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM timescaledb_information.jobs WHERE job_id=:drop_chunks_job_id;
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name
|
||||
--------+-------------------------+-------------------+-------------+-------------+--------------+-----------------------+------------------+-------------------+-----------+------------------------------------------------+------------+-------------------+------------------------
|
||||
1001 | Retention Policy [1001] | @ 1 sec | @ 5 mins | -1 | @ 5 mins | _timescaledb_internal | policy_retention | default_perm_user | t | {"drop_after": "@ 4 mons", "hypertable_id": 2} | | public | test_drop_chunks_table
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name | check_schema | check_name
|
||||
--------+-------------------------+-------------------+-------------+-------------+--------------+-----------------------+------------------+-------------------+-----------+------------------------------------------------+------------+-------------------+------------------------+-----------------------+------------------------
|
||||
1001 | Retention Policy [1001] | @ 1 sec | @ 5 mins | -1 | @ 5 mins | _timescaledb_internal | policy_retention | default_perm_user | t | {"drop_after": "@ 4 mons", "hypertable_id": 2} | | public | test_drop_chunks_table | _timescaledb_internal | policy_retention_check
|
||||
(1 row)
|
||||
|
||||
-- no stats
|
||||
@ -454,9 +454,9 @@ SELECT * FROM sorted_bgw_log;
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM timescaledb_information.jobs WHERE job_id=:drop_chunks_job_id;
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name
|
||||
--------+-------------------------+-------------------+-------------+-------------+--------------+-----------------------+------------------+-------------------+-----------+------------------------------------------------+------------------------------+-------------------+------------------------
|
||||
1001 | Retention Policy [1001] | @ 1 sec | @ 5 mins | -1 | @ 5 mins | _timescaledb_internal | policy_retention | default_perm_user | t | {"drop_after": "@ 4 mons", "hypertable_id": 2} | Fri Dec 31 16:00:01 1999 PST | public | test_drop_chunks_table
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name | check_schema | check_name
|
||||
--------+-------------------------+-------------------+-------------+-------------+--------------+-----------------------+------------------+-------------------+-----------+------------------------------------------------+------------------------------+-------------------+------------------------+-----------------------+------------------------
|
||||
1001 | Retention Policy [1001] | @ 1 sec | @ 5 mins | -1 | @ 5 mins | _timescaledb_internal | policy_retention | default_perm_user | t | {"drop_after": "@ 4 mons", "hypertable_id": 2} | Fri Dec 31 16:00:01 1999 PST | public | test_drop_chunks_table | _timescaledb_internal | policy_retention_check
|
||||
(1 row)
|
||||
|
||||
-- job ran once, successfully
|
||||
@ -493,9 +493,9 @@ SELECT * FROM sorted_bgw_log;
|
||||
(3 rows)
|
||||
|
||||
SELECT * FROM timescaledb_information.jobs WHERE job_id=:drop_chunks_job_id;
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name
|
||||
--------+-------------------------+-------------------+-------------+-------------+--------------+-----------------------+------------------+-------------------+-----------+------------------------------------------------+------------------------------+-------------------+------------------------
|
||||
1001 | Retention Policy [1001] | @ 1 sec | @ 5 mins | -1 | @ 5 mins | _timescaledb_internal | policy_retention | default_perm_user | t | {"drop_after": "@ 4 mons", "hypertable_id": 2} | Fri Dec 31 16:00:01 1999 PST | public | test_drop_chunks_table
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name | check_schema | check_name
|
||||
--------+-------------------------+-------------------+-------------+-------------+--------------+-----------------------+------------------+-------------------+-----------+------------------------------------------------+------------------------------+-------------------+------------------------+-----------------------+------------------------
|
||||
1001 | Retention Policy [1001] | @ 1 sec | @ 5 mins | -1 | @ 5 mins | _timescaledb_internal | policy_retention | default_perm_user | t | {"drop_after": "@ 4 mons", "hypertable_id": 2} | Fri Dec 31 16:00:01 1999 PST | public | test_drop_chunks_table | _timescaledb_internal | policy_retention_check
|
||||
(1 row)
|
||||
|
||||
-- still only 1 run
|
||||
@ -545,9 +545,9 @@ SELECT * FROM sorted_bgw_log;
|
||||
(6 rows)
|
||||
|
||||
SELECT * FROM timescaledb_information.jobs WHERE job_id=:drop_chunks_job_id;
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name
|
||||
--------+-------------------------+-------------------+-------------+-------------+--------------+-----------------------+------------------+-------------------+-----------+------------------------------------------------+------------------------------+-------------------+------------------------
|
||||
1001 | Retention Policy [1001] | @ 1 sec | @ 5 mins | -1 | @ 5 mins | _timescaledb_internal | policy_retention | default_perm_user | t | {"drop_after": "@ 4 mons", "hypertable_id": 2} | Fri Dec 31 16:00:02 1999 PST | public | test_drop_chunks_table
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name | check_schema | check_name
|
||||
--------+-------------------------+-------------------+-------------+-------------+--------------+-----------------------+------------------+-------------------+-----------+------------------------------------------------+------------------------------+-------------------+------------------------+-----------------------+------------------------
|
||||
1001 | Retention Policy [1001] | @ 1 sec | @ 5 mins | -1 | @ 5 mins | _timescaledb_internal | policy_retention | default_perm_user | t | {"drop_after": "@ 4 mons", "hypertable_id": 2} | Fri Dec 31 16:00:02 1999 PST | public | test_drop_chunks_table | _timescaledb_internal | policy_retention_check
|
||||
(1 row)
|
||||
|
||||
-- 2 runs
|
||||
@ -622,16 +622,16 @@ SELECT add_retention_policy('test_drop_chunks_table_tsntz', INTERVAL '4 months')
|
||||
-- Test that retention policy is being logged
|
||||
SELECT alter_job(id,config:=jsonb_set(config,'{verbose_log}', 'true'))
|
||||
FROM _timescaledb_config.bgw_job WHERE id = :drop_chunks_date_job_id;
|
||||
alter_job
|
||||
-------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1002,"@ 1 day","@ 5 mins",-1,"@ 5 mins",t,"{""drop_after"": ""@ 4 mons"", ""verbose_log"": true, ""hypertable_id"": 3}",-infinity)
|
||||
alter_job
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1002,"@ 1 day","@ 5 mins",-1,"@ 5 mins",t,"{""drop_after"": ""@ 4 mons"", ""verbose_log"": true, ""hypertable_id"": 3}",-infinity,_timescaledb_internal.policy_retention_check)
|
||||
(1 row)
|
||||
|
||||
SELECT alter_job(id,config:=jsonb_set(config,'{verbose_log}', 'true'))
|
||||
FROM _timescaledb_config.bgw_job WHERE id = :drop_chunks_tsntz_job_id;
|
||||
alter_job
|
||||
-------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1003,"@ 1 day","@ 5 mins",-1,"@ 5 mins",t,"{""drop_after"": ""@ 4 mons"", ""verbose_log"": true, ""hypertable_id"": 4}",-infinity)
|
||||
alter_job
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1003,"@ 1 day","@ 5 mins",-1,"@ 5 mins",t,"{""drop_after"": ""@ 4 mons"", ""verbose_log"": true, ""hypertable_id"": 4}",-infinity,_timescaledb_internal.policy_retention_check)
|
||||
(1 row)
|
||||
|
||||
CALL run_job(:drop_chunks_date_job_id);
|
||||
|
@ -269,9 +269,9 @@ SELECT ts_bgw_params_reset_time((extract(epoch from interval '12 hour')::bigint
|
||||
|
||||
--alter the refresh interval and check if next_start is altered
|
||||
SELECT alter_job(:job_id, schedule_interval => '1m', retry_period => '1m');
|
||||
alter_job
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 min","@ 0",-1,"@ 1 min",t,"{""end_offset"": 4, ""start_offset"": null, ""mat_hypertable_id"": 2}","Sat Jan 01 04:01:00 2000 PST")
|
||||
alter_job
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 min","@ 0",-1,"@ 1 min",t,"{""end_offset"": 4, ""start_offset"": null, ""mat_hypertable_id"": 2}","Sat Jan 01 04:01:00 2000 PST",_timescaledb_internal.policy_refresh_continuous_aggregate_check)
|
||||
(1 row)
|
||||
|
||||
SELECT job_id, next_start - last_finish as until_next, total_runs
|
||||
@ -309,9 +309,9 @@ SELECT (next_start - '30s'::interval) AS "NEW_NEXT_START"
|
||||
FROM _timescaledb_internal.bgw_job_stat
|
||||
WHERE job_id=:job_id \gset
|
||||
SELECT alter_job(:job_id, next_start => :'NEW_NEXT_START');
|
||||
alter_job
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 min","@ 0",-1,"@ 1 min",t,"{""end_offset"": 4, ""start_offset"": null, ""mat_hypertable_id"": 2}","Sat Jan 01 04:02:30 2000 PST")
|
||||
alter_job
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 min","@ 0",-1,"@ 1 min",t,"{""end_offset"": 4, ""start_offset"": null, ""mat_hypertable_id"": 2}","Sat Jan 01 04:02:30 2000 PST",_timescaledb_internal.policy_refresh_continuous_aggregate_check)
|
||||
(1 row)
|
||||
|
||||
SELECT ts_bgw_params_reset_time((extract(epoch from interval '12 hour')::bigint * 1000000)+(extract(epoch from interval '2 minute 30 seconds')::bigint * 1000000), true);
|
||||
|
@ -301,9 +301,9 @@ SELECT ts_bgw_params_reset_time((extract(epoch from interval '12 hour')::bigint
|
||||
|
||||
--alter the refresh interval and check if next_start is altered
|
||||
SELECT alter_job(:job_id, schedule_interval => '1m', retry_period => '1m');
|
||||
alter_job
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 min","@ 0",-1,"@ 1 min",t,"{""end_offset"": 4, ""start_offset"": null, ""mat_hypertable_id"": 2}","Sat Jan 01 04:01:00 2000 PST")
|
||||
alter_job
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 min","@ 0",-1,"@ 1 min",t,"{""end_offset"": 4, ""start_offset"": null, ""mat_hypertable_id"": 2}","Sat Jan 01 04:01:00 2000 PST",_timescaledb_internal.policy_refresh_continuous_aggregate_check)
|
||||
(1 row)
|
||||
|
||||
SELECT job_id, next_start - last_finish as until_next, total_runs
|
||||
@ -341,9 +341,9 @@ SELECT (next_start - '30s'::interval) AS "NEW_NEXT_START"
|
||||
FROM _timescaledb_internal.bgw_job_stat
|
||||
WHERE job_id=:job_id \gset
|
||||
SELECT alter_job(:job_id, next_start => :'NEW_NEXT_START');
|
||||
alter_job
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 min","@ 0",-1,"@ 1 min",t,"{""end_offset"": 4, ""start_offset"": null, ""mat_hypertable_id"": 2}","Sat Jan 01 04:02:30 2000 PST")
|
||||
alter_job
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 min","@ 0",-1,"@ 1 min",t,"{""end_offset"": 4, ""start_offset"": null, ""mat_hypertable_id"": 2}","Sat Jan 01 04:02:30 2000 PST",_timescaledb_internal.policy_refresh_continuous_aggregate_check)
|
||||
(1 row)
|
||||
|
||||
SELECT ts_bgw_params_reset_time((extract(epoch from interval '12 hour')::bigint * 1000000)+(extract(epoch from interval '2 minute 30 seconds')::bigint * 1000000), true);
|
||||
|
@ -97,9 +97,9 @@ WHERE hypertable_name = '_materialized_hypertable_2' ORDER BY range_start_intege
|
||||
|
||||
SELECT add_retention_policy( 'drop_chunks_view1', drop_after => 10) as drop_chunks_job_id1 \gset
|
||||
SELECT alter_job(:drop_chunks_job_id1, schedule_interval => INTERVAL '1 second');
|
||||
alter_job
|
||||
----------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 sec","@ 5 mins",-1,"@ 5 mins",t,"{""drop_after"": 10, ""hypertable_id"": 2}",-infinity)
|
||||
alter_job
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 sec","@ 5 mins",-1,"@ 5 mins",t,"{""drop_after"": 10, ""hypertable_id"": 2}",-infinity,_timescaledb_internal.policy_retention_check)
|
||||
(1 row)
|
||||
|
||||
SELECT ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(2000000);
|
||||
|
@ -579,9 +579,9 @@ SELECT _timescaledb_internal.alter_job_set_hypertable_id( :job_id, 'max_mat_view
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM timescaledb_information.jobs WHERE job_id != 1 ORDER BY 1;
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name
|
||||
--------+----------------------------+-------------------+-------------+-------------+--------------+-------------+-------------+-------------------+-----------+----------------------+------------+-----------------------+----------------------------
|
||||
1026 | User-Defined Action [1026] | @ 1 hour | @ 0 | -1 | @ 5 mins | public | custom_func | default_perm_user | t | {"type": "function"} | | _timescaledb_internal | _materialized_hypertable_5
|
||||
job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | config | next_start | hypertable_schema | hypertable_name | check_schema | check_name
|
||||
--------+----------------------------+-------------------+-------------+-------------+--------------+-------------+-------------+-------------------+-----------+----------------------+------------+-----------------------+----------------------------+--------------+------------
|
||||
1026 | User-Defined Action [1026] | @ 1 hour | @ 0 | -1 | @ 5 mins | public | custom_func | default_perm_user | t | {"type": "function"} | | _timescaledb_internal | _materialized_hypertable_5 | |
|
||||
(1 row)
|
||||
|
||||
SELECT timescaledb_experimental.remove_all_policies('max_mat_view_date', true); -- ignore custom job
|
||||
|
@ -101,9 +101,9 @@ SELECT schedule_interval FROM _timescaledb_config.bgw_job WHERE id = 1000;
|
||||
|
||||
-- You can change this setting with ALTER VIEW (equivalently, specify in WITH clause of CREATE VIEW)
|
||||
SELECT alter_job(1000, schedule_interval := '1h');
|
||||
alter_job
|
||||
----------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 hour","@ 0",-1,"@ 2 hours",t,"{""end_offset"": ""@ 2 hours"", ""start_offset"": null, ""mat_hypertable_id"": 2}",-infinity)
|
||||
alter_job
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 hour","@ 0",-1,"@ 2 hours",t,"{""end_offset"": ""@ 2 hours"", ""start_offset"": null, ""mat_hypertable_id"": 2}",-infinity,_timescaledb_internal.policy_refresh_continuous_aggregate_check)
|
||||
(1 row)
|
||||
|
||||
SELECT schedule_interval FROM _timescaledb_config.bgw_job WHERE id = 1000;
|
||||
|
@ -81,9 +81,9 @@ SELECT count(*) FROM _timescaledb_config.bgw_job WHERE proc_schema = '_timescale
|
||||
(1 row)
|
||||
|
||||
SELECT alter_job(:retention_job_id, schedule_interval => INTERVAL '1 second');
|
||||
alter_job
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 sec","@ 5 mins",-1,"@ 5 mins",t,"{""drop_after"": ""@ 4 mons"", ""hypertable_id"": 1}",-infinity)
|
||||
alter_job
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 sec","@ 5 mins",-1,"@ 5 mins",t,"{""drop_after"": ""@ 4 mons"", ""hypertable_id"": 1}",-infinity,_timescaledb_internal.policy_retention_check)
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM _timescaledb_config.bgw_job where id=:retention_job_id;
|
||||
|
@ -38,17 +38,17 @@ select * from _timescaledb_config.bgw_job where id = :compressjob_id;
|
||||
(1 row)
|
||||
|
||||
select * from alter_job(:compressjob_id, schedule_interval=>'1s');
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+-------------+-------------+--------------+-----------+-----------------------------------------------------+------------
|
||||
1000 | @ 1 sec | @ 0 | -1 | @ 1 hour | t | {"hypertable_id": 1, "compress_after": "@ 60 days"} | -infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+-------------+-------------+--------------+-----------+-----------------------------------------------------+------------+------------------------------------------------
|
||||
1000 | @ 1 sec | @ 0 | -1 | @ 1 hour | t | {"hypertable_id": 1, "compress_after": "@ 60 days"} | -infinity | _timescaledb_internal.policy_compression_check
|
||||
(1 row)
|
||||
|
||||
--enable maxchunks to 1 so that only 1 chunk is compressed by the job
|
||||
SELECT alter_job(id,config:=jsonb_set(config,'{maxchunks_to_compress}', '1'))
|
||||
FROM _timescaledb_config.bgw_job WHERE id = :compressjob_id;
|
||||
alter_job
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 sec","@ 0",-1,"@ 1 hour",t,"{""hypertable_id"": 1, ""compress_after"": ""@ 60 days"", ""maxchunks_to_compress"": 1}",-infinity)
|
||||
alter_job
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 sec","@ 0",-1,"@ 1 hour",t,"{""hypertable_id"": 1, ""compress_after"": ""@ 60 days"", ""maxchunks_to_compress"": 1}",-infinity,_timescaledb_internal.policy_compression_check)
|
||||
(1 row)
|
||||
|
||||
select * from _timescaledb_config.bgw_job where id >= 1000 ORDER BY id;
|
||||
@ -328,16 +328,16 @@ SELECT add_compression_policy AS job_id
|
||||
-- job compresses only 1 chunk at a time --
|
||||
SELECT alter_job(id,config:=jsonb_set(config,'{maxchunks_to_compress}', '1'))
|
||||
FROM _timescaledb_config.bgw_job WHERE id = :job_id;
|
||||
alter_job
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1004,"@ 12 hours","@ 0",-1,"@ 1 hour",t,"{""hypertable_id"": 11, ""compress_after"": ""@ 1 day"", ""maxchunks_to_compress"": 1}",-infinity)
|
||||
alter_job
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1004,"@ 12 hours","@ 0",-1,"@ 1 hour",t,"{""hypertable_id"": 11, ""compress_after"": ""@ 1 day"", ""maxchunks_to_compress"": 1}",-infinity,_timescaledb_internal.policy_compression_check)
|
||||
(1 row)
|
||||
|
||||
SELECT alter_job(id,config:=jsonb_set(config,'{verbose_log}', 'true'))
|
||||
FROM _timescaledb_config.bgw_job WHERE id = :job_id;
|
||||
alter_job
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1004,"@ 12 hours","@ 0",-1,"@ 1 hour",t,"{""verbose_log"": true, ""hypertable_id"": 11, ""compress_after"": ""@ 1 day"", ""maxchunks_to_compress"": 1}",-infinity)
|
||||
alter_job
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1004,"@ 12 hours","@ 0",-1,"@ 1 hour",t,"{""verbose_log"": true, ""hypertable_id"": 11, ""compress_after"": ""@ 1 day"", ""maxchunks_to_compress"": 1}",-infinity,_timescaledb_internal.policy_compression_check)
|
||||
(1 row)
|
||||
|
||||
set client_min_messages TO LOG;
|
||||
@ -553,9 +553,9 @@ SELECT chunk_status FROM compressed_chunk_info_view WHERE hypertable_name = 'met
|
||||
|
||||
-- disable recompress in compress job
|
||||
SELECT alter_job(id,config:=jsonb_set(config,'{recompress}','false')) FROM _timescaledb_config.bgw_job WHERE id = :JOB_COMPRESS;
|
||||
alter_job
|
||||
--------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1006,"@ 7 days","@ 0",-1,"@ 5 mins",t,"{""recompress"": false, ""hypertable_id"": 16, ""compress_after"": ""@ 7 days""}",-infinity)
|
||||
alter_job
|
||||
---------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1006,"@ 7 days","@ 0",-1,"@ 5 mins",t,"{""recompress"": false, ""hypertable_id"": 16, ""compress_after"": ""@ 7 days""}",-infinity,)
|
||||
(1 row)
|
||||
|
||||
-- nothing to do
|
||||
@ -587,9 +587,9 @@ SELECT chunk_status FROM compressed_chunk_info_view WHERE hypertable_name = 'met
|
||||
|
||||
-- reenable recompress in compress job
|
||||
SELECT alter_job(id,config:=jsonb_set(config,'{recompress}','true')) FROM _timescaledb_config.bgw_job WHERE id = :JOB_COMPRESS;
|
||||
alter_job
|
||||
-------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1006,"@ 7 days","@ 0",-1,"@ 5 mins",t,"{""recompress"": true, ""hypertable_id"": 16, ""compress_after"": ""@ 7 days""}",-infinity)
|
||||
alter_job
|
||||
--------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1006,"@ 7 days","@ 0",-1,"@ 5 mins",t,"{""recompress"": true, ""hypertable_id"": 16, ""compress_after"": ""@ 7 days""}",-infinity,)
|
||||
(1 row)
|
||||
|
||||
-- should recompress now
|
||||
|
@ -855,9 +855,9 @@ SELECT add_continuous_aggregate_policy('mat_with_test', NULL, '5 h'::interval, '
|
||||
(1 row)
|
||||
|
||||
SELECT alter_job(id, schedule_interval => '1h') FROM _timescaledb_config.bgw_job;
|
||||
alter_job
|
||||
------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1001,"@ 1 hour","@ 0",-1,"@ 12 hours",t,"{""end_offset"": ""@ 5 hours"", ""start_offset"": null, ""mat_hypertable_id"": 20}",-infinity)
|
||||
alter_job
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1001,"@ 1 hour","@ 0",-1,"@ 12 hours",t,"{""end_offset"": ""@ 5 hours"", ""start_offset"": null, ""mat_hypertable_id"": 20}",-infinity,_timescaledb_internal.policy_refresh_continuous_aggregate_check)
|
||||
(1 row)
|
||||
|
||||
SELECT schedule_interval FROM _timescaledb_config.bgw_job;
|
||||
@ -867,9 +867,9 @@ SELECT schedule_interval FROM _timescaledb_config.bgw_job;
|
||||
(1 row)
|
||||
|
||||
SELECT alter_job(id, schedule_interval => '2h') FROM _timescaledb_config.bgw_job;
|
||||
alter_job
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1001,"@ 2 hours","@ 0",-1,"@ 12 hours",t,"{""end_offset"": ""@ 5 hours"", ""start_offset"": null, ""mat_hypertable_id"": 20}",-infinity)
|
||||
alter_job
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1001,"@ 2 hours","@ 0",-1,"@ 12 hours",t,"{""end_offset"": ""@ 5 hours"", ""start_offset"": null, ""mat_hypertable_id"": 20}",-infinity,_timescaledb_internal.policy_refresh_continuous_aggregate_check)
|
||||
(1 row)
|
||||
|
||||
SELECT schedule_interval FROM _timescaledb_config.bgw_job;
|
||||
@ -948,9 +948,9 @@ SELECT add_continuous_aggregate_policy('mat_with_test', NULL, 500::integer, '12
|
||||
(1 row)
|
||||
|
||||
SELECT alter_job(id, schedule_interval => '2h') FROM _timescaledb_config.bgw_job;
|
||||
alter_job
|
||||
---------------------------------------------------------------------------------------------------------------------------------
|
||||
(1002,"@ 2 hours","@ 0",-1,"@ 12 hours",t,"{""end_offset"": 500, ""start_offset"": null, ""mat_hypertable_id"": 23}",-infinity)
|
||||
alter_job
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1002,"@ 2 hours","@ 0",-1,"@ 12 hours",t,"{""end_offset"": 500, ""start_offset"": null, ""mat_hypertable_id"": 23}",-infinity,_timescaledb_internal.policy_refresh_continuous_aggregate_check)
|
||||
(1 row)
|
||||
|
||||
SELECT schedule_interval FROM _timescaledb_config.bgw_job;
|
||||
|
@ -869,9 +869,9 @@ SELECT add_continuous_aggregate_policy('mat_with_test', NULL, '5 h'::interval, '
|
||||
(1 row)
|
||||
|
||||
SELECT alter_job(id, schedule_interval => '1h') FROM _timescaledb_config.bgw_job;
|
||||
alter_job
|
||||
------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1001,"@ 1 hour","@ 0",-1,"@ 12 hours",t,"{""end_offset"": ""@ 5 hours"", ""start_offset"": null, ""mat_hypertable_id"": 20}",-infinity)
|
||||
alter_job
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1001,"@ 1 hour","@ 0",-1,"@ 12 hours",t,"{""end_offset"": ""@ 5 hours"", ""start_offset"": null, ""mat_hypertable_id"": 20}",-infinity,_timescaledb_internal.policy_refresh_continuous_aggregate_check)
|
||||
(1 row)
|
||||
|
||||
SELECT schedule_interval FROM _timescaledb_config.bgw_job;
|
||||
@ -881,9 +881,9 @@ SELECT schedule_interval FROM _timescaledb_config.bgw_job;
|
||||
(1 row)
|
||||
|
||||
SELECT alter_job(id, schedule_interval => '2h') FROM _timescaledb_config.bgw_job;
|
||||
alter_job
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1001,"@ 2 hours","@ 0",-1,"@ 12 hours",t,"{""end_offset"": ""@ 5 hours"", ""start_offset"": null, ""mat_hypertable_id"": 20}",-infinity)
|
||||
alter_job
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1001,"@ 2 hours","@ 0",-1,"@ 12 hours",t,"{""end_offset"": ""@ 5 hours"", ""start_offset"": null, ""mat_hypertable_id"": 20}",-infinity,_timescaledb_internal.policy_refresh_continuous_aggregate_check)
|
||||
(1 row)
|
||||
|
||||
SELECT schedule_interval FROM _timescaledb_config.bgw_job;
|
||||
@ -967,9 +967,9 @@ SELECT add_continuous_aggregate_policy('mat_with_test', NULL, 500::integer, '12
|
||||
(1 row)
|
||||
|
||||
SELECT alter_job(id, schedule_interval => '2h') FROM _timescaledb_config.bgw_job;
|
||||
alter_job
|
||||
---------------------------------------------------------------------------------------------------------------------------------
|
||||
(1002,"@ 2 hours","@ 0",-1,"@ 12 hours",t,"{""end_offset"": 500, ""start_offset"": null, ""mat_hypertable_id"": 23}",-infinity)
|
||||
alter_job
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1002,"@ 2 hours","@ 0",-1,"@ 12 hours",t,"{""end_offset"": 500, ""start_offset"": null, ""mat_hypertable_id"": 23}",-infinity,_timescaledb_internal.policy_refresh_continuous_aggregate_check)
|
||||
(1 row)
|
||||
|
||||
SELECT schedule_interval FROM _timescaledb_config.bgw_job;
|
||||
|
@ -660,9 +660,9 @@ select * from _timescaledb_config.bgw_job where id = :compressjob_id;
|
||||
(1 row)
|
||||
|
||||
select * from alter_job(:compressjob_id, schedule_interval=>'1s');
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+-------------+-------------+--------------+-----------+-----------------------------------------------------+------------
|
||||
1000 | @ 1 sec | @ 0 | -1 | @ 1 hour | t | {"hypertable_id": 2, "compress_after": "@ 60 days"} | -infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+-------------+-------------+--------------+-----------+-----------------------------------------------------+------------+------------------------------------------------
|
||||
1000 | @ 1 sec | @ 0 | -1 | @ 1 hour | t | {"hypertable_id": 2, "compress_after": "@ 60 days"} | -infinity | _timescaledb_internal.policy_compression_check
|
||||
(1 row)
|
||||
|
||||
select * from _timescaledb_config.bgw_job where id >= 1000 ORDER BY id;
|
||||
@ -674,9 +674,9 @@ select * from _timescaledb_config.bgw_job where id >= 1000 ORDER BY id;
|
||||
-- we want only 1 chunk to be compressed --
|
||||
SELECT alter_job(id,config:=jsonb_set(config,'{maxchunks_to_compress}', '1'))
|
||||
FROM _timescaledb_config.bgw_job WHERE id = :compressjob_id;
|
||||
alter_job
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 sec","@ 0",-1,"@ 1 hour",t,"{""hypertable_id"": 2, ""compress_after"": ""@ 60 days"", ""maxchunks_to_compress"": 1}",-infinity)
|
||||
alter_job
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
(1000,"@ 1 sec","@ 0",-1,"@ 1 hour",t,"{""hypertable_id"": 2, ""compress_after"": ""@ 60 days"", ""maxchunks_to_compress"": 1}",-infinity,_timescaledb_internal.policy_compression_check)
|
||||
(1 row)
|
||||
|
||||
insert into conditions
|
||||
|
@ -626,72 +626,72 @@ select add_reorder_policy('test_table', 'test_table_time_idx') as job_id \gset
|
||||
|
||||
-- No change
|
||||
select * from alter_job(:job_id);
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+-------------+-------------+--------------+-----------+-----------------------------------------------------------+------------
|
||||
1014 | @ 84 hours | @ 0 | -1 | @ 5 mins | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+-------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+--------------------------------------------
|
||||
1014 | @ 84 hours | @ 0 | -1 | @ 5 mins | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
-- Changes expected
|
||||
select * from alter_job(:job_id, INTERVAL '3 years', INTERVAL '5 min', 5, INTERVAL '123 sec');
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+-------------+-------------+-----------------+-----------+-----------------------------------------------------------+------------
|
||||
1014 | @ 3 years | @ 5 mins | 5 | @ 2 mins 3 secs | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+-------------+-------------+-----------------+-----------+-----------------------------------------------------------+------------+--------------------------------------------
|
||||
1014 | @ 3 years | @ 5 mins | 5 | @ 2 mins 3 secs | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
select * from alter_job(:job_id, INTERVAL '123 years');
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+-------------+-------------+-----------------+-----------+-----------------------------------------------------------+------------
|
||||
1014 | @ 123 years | @ 5 mins | 5 | @ 2 mins 3 secs | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+-------------+-------------+-----------------+-----------+-----------------------------------------------------------+------------+--------------------------------------------
|
||||
1014 | @ 123 years | @ 5 mins | 5 | @ 2 mins 3 secs | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
select * from alter_job(:job_id, retry_period => INTERVAL '33 hours');
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+-------------+-------------+--------------+-----------+-----------------------------------------------------------+------------
|
||||
1014 | @ 123 years | @ 5 mins | 5 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+-------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+--------------------------------------------
|
||||
1014 | @ 123 years | @ 5 mins | 5 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
select * from alter_job(:job_id, max_runtime => INTERVAL '456 sec');
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------
|
||||
1014 | @ 123 years | @ 7 mins 36 secs | 5 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+--------------------------------------------
|
||||
1014 | @ 123 years | @ 7 mins 36 secs | 5 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
select * from alter_job(:job_id, max_retries => 0);
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------
|
||||
1014 | @ 123 years | @ 7 mins 36 secs | 0 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+--------------------------------------------
|
||||
1014 | @ 123 years | @ 7 mins 36 secs | 0 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
select * from alter_job(:job_id, max_retries => -1);
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------
|
||||
1014 | @ 123 years | @ 7 mins 36 secs | -1 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+--------------------------------------------
|
||||
1014 | @ 123 years | @ 7 mins 36 secs | -1 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
select * from alter_job(:job_id, max_retries => 20);
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------
|
||||
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+--------------------------------------------
|
||||
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
-- No change
|
||||
select * from alter_job(:job_id, max_runtime => NULL);
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------
|
||||
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+--------------------------------------------
|
||||
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
select * from alter_job(:job_id, max_retries => NULL);
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------
|
||||
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+--------------------------------------------
|
||||
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
--change schedule_interval when bgw_job_stat does not exist
|
||||
select * from alter_job(:job_id, schedule_interval=>'1 min');
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------
|
||||
1014 | @ 1 min | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+--------------------------------------------
|
||||
1014 | @ 1 min | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
select count(*) = 0 from _timescaledb_internal.bgw_job_stat where job_id = :job_id;
|
||||
@ -702,23 +702,23 @@ select count(*) = 0 from _timescaledb_internal.bgw_job_stat where job_id = :job_
|
||||
|
||||
--set next_start when bgw_job_stat does not exist
|
||||
select * from alter_job(:job_id, next_start=>'2001-01-01 01:01:01');
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------
|
||||
1014 | @ 1 min | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Mon Jan 01 01:01:01 2001 PST
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------+--------------------------------------------
|
||||
1014 | @ 1 min | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Mon Jan 01 01:01:01 2001 PST | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
--change schedule_interval when no last_finish set
|
||||
select * from alter_job(:job_id, schedule_interval=>'10 min');
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------
|
||||
1014 | @ 10 mins | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+--------------------------------------------
|
||||
1014 | @ 10 mins | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
--next_start overrides any schedule_interval changes
|
||||
select * from alter_job(:job_id, schedule_interval=>'20 min', next_start=>'2002-01-01 01:01:01');
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------
|
||||
1014 | @ 20 mins | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Tue Jan 01 01:01:01 2002 PST
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------+--------------------------------------------
|
||||
1014 | @ 20 mins | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Tue Jan 01 01:01:01 2002 PST | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
--set the last_finish manually
|
||||
@ -727,30 +727,30 @@ UPDATE _timescaledb_internal.bgw_job_stat SET last_finish = '2003-01-01:01:01:01
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||
--not changing the interval doesn't change the next_start
|
||||
select * from alter_job(:job_id, schedule_interval=>'20 min');
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------
|
||||
1014 | @ 20 mins | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Tue Jan 01 01:01:01 2002 PST
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------+--------------------------------------------
|
||||
1014 | @ 20 mins | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Tue Jan 01 01:01:01 2002 PST | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
--changing the interval changes next_start
|
||||
select * from alter_job(:job_id, schedule_interval=>'30 min');
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------
|
||||
1014 | @ 30 mins | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Wed Jan 01 01:31:01 2003 PST
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------+--------------------------------------------
|
||||
1014 | @ 30 mins | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Wed Jan 01 01:31:01 2003 PST | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
--explicit next start overrides.
|
||||
select * from alter_job(:job_id, schedule_interval=>'40 min', next_start=>'2004-01-01 01:01:01');
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------
|
||||
1014 | @ 40 mins | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Thu Jan 01 01:01:01 2004 PST
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------+--------------------------------------------
|
||||
1014 | @ 40 mins | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Thu Jan 01 01:01:01 2004 PST | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
--test pausing
|
||||
select * from alter_job(:job_id, next_start=>'infinity');
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------
|
||||
1014 | @ 40 mins | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | infinity
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+--------------------------------------------
|
||||
1014 | @ 40 mins | @ 7 mins 36 secs | 20 | @ 33 hours | t | {"index_name": "test_table_time_idx", "hypertable_id": 7} | infinity | _timescaledb_internal.policy_reorder_check
|
||||
(1 row)
|
||||
|
||||
--test that you can use now() to unpause
|
||||
@ -805,9 +805,9 @@ ERROR: configuration hypertable id 47 not found
|
||||
-- Check if_exists boolean works correctly
|
||||
select * from alter_job(1234, if_exists => TRUE);
|
||||
NOTICE: job 1234 not found, skipping
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start
|
||||
--------+-------------------+-------------+-------------+--------------+-----------+--------+------------
|
||||
| | | | | | |
|
||||
job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config
|
||||
--------+-------------------+-------------+-------------+--------------+-----------+--------+------------+--------------
|
||||
| | | | | | | |
|
||||
(1 row)
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
|
@ -98,15 +98,15 @@ ORDER BY pronamespace::regnamespace::text COLLATE "C", p.oid::regprocedure::text
|
||||
_timescaledb_internal.partialize_agg(anyelement)
|
||||
_timescaledb_internal.ping_data_node(name)
|
||||
_timescaledb_internal.policy_compression(integer,jsonb)
|
||||
_timescaledb_internal.policy_compression_check(integer,jsonb)
|
||||
_timescaledb_internal.policy_compression_check(jsonb)
|
||||
_timescaledb_internal.policy_compression_execute(integer,integer,anyelement,integer,boolean,boolean)
|
||||
_timescaledb_internal.policy_recompression(integer,jsonb)
|
||||
_timescaledb_internal.policy_refresh_continuous_aggregate(integer,jsonb)
|
||||
_timescaledb_internal.policy_refresh_continuous_aggregate_check(integer,jsonb)
|
||||
_timescaledb_internal.policy_refresh_continuous_aggregate_check(jsonb)
|
||||
_timescaledb_internal.policy_reorder(integer,jsonb)
|
||||
_timescaledb_internal.policy_reorder_check(integer,jsonb)
|
||||
_timescaledb_internal.policy_reorder_check(jsonb)
|
||||
_timescaledb_internal.policy_retention(integer,jsonb)
|
||||
_timescaledb_internal.policy_retention_check(integer,jsonb)
|
||||
_timescaledb_internal.policy_retention_check(jsonb)
|
||||
_timescaledb_internal.process_ddl_event()
|
||||
_timescaledb_internal.range_value_to_pretty(bigint,regtype)
|
||||
_timescaledb_internal.relation_size(regclass)
|
||||
@ -140,7 +140,7 @@ ORDER BY pronamespace::regnamespace::text COLLATE "C", p.oid::regprocedure::text
|
||||
add_job(regproc,interval,jsonb,timestamp with time zone,boolean,regproc)
|
||||
add_reorder_policy(regclass,name,boolean)
|
||||
add_retention_policy(regclass,"any",boolean,interval)
|
||||
alter_job(integer,interval,interval,integer,interval,boolean,jsonb,timestamp with time zone,boolean)
|
||||
alter_job(integer,interval,interval,integer,interval,boolean,jsonb,timestamp with time zone,boolean,regproc)
|
||||
approximate_row_count(regclass)
|
||||
attach_data_node(name,regclass,boolean,boolean)
|
||||
attach_tablespace(name,regclass,boolean)
|
||||
|
@ -317,3 +317,248 @@ FROM _timescaledb_config.bgw_job WHERE id = :job_id_5;
|
||||
|
||||
-- Stop Background Workers
|
||||
SELECT _timescaledb_internal.stop_background_workers();
|
||||
|
||||
SELECT _timescaledb_internal.restart_background_workers();
|
||||
|
||||
\set ON_ERROR_STOP 0
|
||||
-- add test for custom jobs with custom check functions
|
||||
-- create the functions/procedures to be used as checking functions
|
||||
CREATE OR REPLACE PROCEDURE test_config_check_proc(config jsonb)
|
||||
LANGUAGE PLPGSQL
|
||||
AS $$
|
||||
DECLARE
|
||||
drop_after interval;
|
||||
BEGIN
|
||||
SELECT jsonb_object_field_text (config, 'drop_after')::interval INTO STRICT drop_after;
|
||||
IF drop_after IS NULL THEN
|
||||
RAISE EXCEPTION 'Config must be not NULL and have drop_after';
|
||||
END IF ;
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION test_config_check_func(config jsonb) RETURNS VOID
|
||||
AS $$
|
||||
DECLARE
|
||||
drop_after interval;
|
||||
BEGIN
|
||||
IF config IS NULL THEN
|
||||
RETURN;
|
||||
END IF;
|
||||
SELECT jsonb_object_field_text (config, 'drop_after')::interval INTO STRICT drop_after;
|
||||
IF drop_after IS NULL THEN
|
||||
RAISE EXCEPTION 'Config can be NULL but must have drop_after if not';
|
||||
END IF ;
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
|
||||
-- step 2, create a procedure to run as a custom job
|
||||
CREATE OR REPLACE PROCEDURE test_proc_with_check(job_id int, config jsonb)
|
||||
LANGUAGE PLPGSQL
|
||||
AS $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'Will only print this if config passes checks, my config is %', config;
|
||||
END
|
||||
$$;
|
||||
|
||||
-- step 3, add the job with the config check function passed as argument
|
||||
-- test procedures
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_config_check_proc'::regproc);
|
||||
select add_job('test_proc_with_check', '5 secs', config => NULL, check_config => 'test_config_check_proc'::regproc);
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{"drop_after": "chicken"}', check_config => 'test_config_check_proc'::regproc);
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{"drop_after": "2 weeks"}', check_config => 'test_config_check_proc'::regproc)
|
||||
as job_with_proc_check_id \gset
|
||||
|
||||
-- test functions
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_config_check_func'::regproc);
|
||||
select add_job('test_proc_with_check', '5 secs', config => NULL, check_config => 'test_config_check_func'::regproc);
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{"drop_after": "chicken"}', check_config => 'test_config_check_func'::regproc);
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{"drop_after": "2 weeks"}', check_config => 'test_config_check_func'::regproc)
|
||||
as job_with_func_check_id \gset
|
||||
|
||||
|
||||
--- test alter_job
|
||||
select alter_job(:job_with_func_check_id, config => '{"drop_after":"chicken"}');
|
||||
select alter_job(:job_with_func_check_id, config => '{"drop_after":"5 years"}');
|
||||
|
||||
select alter_job(:job_with_proc_check_id, config => '{"drop_after":"4 days"}');
|
||||
|
||||
|
||||
-- test that jobs with an incorrect check function signature will not be registered
|
||||
-- these are all incorrect function signatures
|
||||
|
||||
CREATE OR REPLACE FUNCTION test_config_check_func_0args() RETURNS VOID
|
||||
AS $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'I take no arguments and will validate anything you give me!';
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
|
||||
CREATE OR REPLACE FUNCTION test_config_check_func_2args(config jsonb, intarg int) RETURNS VOID
|
||||
AS $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'I take two arguments (jsonb, int) and I should fail to run!';
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
|
||||
CREATE OR REPLACE FUNCTION test_config_check_func_intarg(config int) RETURNS VOID
|
||||
AS $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'I take one argument which is an integer and I should fail to run!';
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
|
||||
-- -- this should fail, it has an incorrect check function
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_config_check_func_0args'::regproc);
|
||||
-- -- so should this
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_config_check_func_2args'::regproc);
|
||||
-- and this
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_config_check_func_intarg'::regproc);
|
||||
-- and this fails as it calls a nonexistent function
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_nonexistent_check_func'::regproc);
|
||||
|
||||
-- when called with a valid check function and a NULL config no check should occur
|
||||
CREATE OR REPLACE FUNCTION test_config_check_func(config jsonb) RETURNS VOID
|
||||
AS $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'This message will get printed for both NULL and not NULL config';
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
|
||||
SET client_min_messages = NOTICE;
|
||||
-- check done for both NULL and non-NULL config
|
||||
select add_job('test_proc_with_check', '5 secs', config => NULL, check_config => 'test_config_check_func'::regproc);
|
||||
-- check done
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_config_check_func'::regproc) as job_id \gset
|
||||
|
||||
-- check function not returning void
|
||||
CREATE OR REPLACE FUNCTION test_config_check_func_returns_int(config jsonb) RETURNS INT
|
||||
AS $$
|
||||
BEGIN
|
||||
raise notice 'I print a message, and then I return least(1,2)';
|
||||
RETURN LEAST(1, 2);
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_config_check_func_returns_int'::regproc) as job_id_int \gset
|
||||
|
||||
-- drop the registered check function, verify that alter_job will work and print a warning that
|
||||
-- the check is being skipped due to the check function missing
|
||||
ALTER FUNCTION test_config_check_func RENAME TO renamed_func;
|
||||
select alter_job(:job_id, schedule_interval => '1 hour');
|
||||
DROP FUNCTION test_config_check_func_returns_int;
|
||||
select alter_job(:job_id_int, config => '{"field":"value"}');
|
||||
|
||||
-- rename the check function and then call alter_job to register the new name
|
||||
select alter_job(:job_id, check_config => 'renamed_func'::regproc);
|
||||
-- run alter again, should get a config check
|
||||
select alter_job(:job_id, config => '{}');
|
||||
-- do not drop the current check function but register a new one
|
||||
CREATE OR REPLACE FUNCTION substitute_check_func(config jsonb) RETURNS VOID
|
||||
AS $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'This message is a substitute of the previously printed one';
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
-- register the new check
|
||||
select alter_job(:job_id, check_config => 'substitute_check_func');
|
||||
select alter_job(:job_id, config => '{}');
|
||||
|
||||
RESET client_min_messages;
|
||||
|
||||
-- test an oid that doesn't exist
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 17424217::regproc);
|
||||
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
-- test a function with insufficient privileges
|
||||
create schema test_schema;
|
||||
create role user_noexec with login;
|
||||
grant usage on schema test_schema to user_noexec;
|
||||
|
||||
CREATE OR REPLACE FUNCTION test_schema.test_config_check_func_privileges(config jsonb) RETURNS VOID
|
||||
AS $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'This message will only get printed if privileges suffice';
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
|
||||
revoke execute on function test_schema.test_config_check_func_privileges from public;
|
||||
-- verify the user doesn't have execute permissions on the function
|
||||
select has_function_privilege('user_noexec', 'test_schema.test_config_check_func_privileges(jsonb)', 'execute');
|
||||
|
||||
\c :TEST_DBNAME user_noexec
|
||||
-- user_noexec should not have exec permissions on this function
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'test_schema.test_config_check_func_privileges'::regproc);
|
||||
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
|
||||
-- check that alter_job rejects a check function with invalid signature
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'renamed_func') as job_id_alter \gset
|
||||
select alter_job(:job_id_alter, check_config => 'test_config_check_func_0args');
|
||||
select alter_job(:job_id_alter);
|
||||
-- test that we can unregister the check function
|
||||
select alter_job(:job_id_alter, check_config => 0);
|
||||
-- no message printed now
|
||||
select alter_job(:job_id_alter, config => '{}');
|
||||
|
||||
-- test what happens if the check function contains a COMMIT
|
||||
-- procedure with transaction handling
|
||||
CREATE OR REPLACE PROCEDURE custom_proc2_jsonb(config jsonb) LANGUAGE PLPGSQL AS
|
||||
$$
|
||||
BEGIN
|
||||
-- RAISE NOTICE 'Starting some transactions inside procedure';
|
||||
INSERT INTO custom_log VALUES(1, $1, 'custom_proc 1 COMMIT');
|
||||
COMMIT;
|
||||
END
|
||||
$$;
|
||||
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}') as job_id_err \gset
|
||||
select alter_job(:job_id_err, check_config => 'custom_proc2_jsonb');
|
||||
select alter_job(:job_id_err, schedule_interval => '3 minutes');
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'custom_proc2_jsonb') as job_id_commit \gset
|
||||
|
||||
-- test the case where we have a background job that registers jobs with a check fn
|
||||
CREATE OR REPLACE PROCEDURE add_scheduled_jobs_with_check(job_id int, config jsonb) LANGUAGE PLPGSQL AS
|
||||
$$
|
||||
BEGIN
|
||||
perform add_job('test_proc_with_check', schedule_interval => '10 secs', config => '{}', check_config => 'renamed_func');
|
||||
END
|
||||
$$;
|
||||
|
||||
select add_job('add_scheduled_jobs_with_check', schedule_interval => '1 hour') as last_job_id \gset
|
||||
-- wait for enough time
|
||||
SELECT wait_for_job_to_run(:last_job_id, 1);
|
||||
select total_runs, total_successes, last_run_status from timescaledb_information.job_stats where job_id = :last_job_id;
|
||||
|
||||
-- test coverage for alter_job
|
||||
-- registering an invalid oid
|
||||
select alter_job(:job_id_alter, check_config => 123456789::regproc);
|
||||
-- registering a function with insufficient privileges
|
||||
\c :TEST_DBNAME user_noexec
|
||||
select * from add_job('test_proc_with_check', '5 secs', config => '{}') as job_id_owner \gset
|
||||
select * from alter_job(:job_id_owner, check_config => 'test_schema.test_config_check_func_privileges'::regproc);
|
||||
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
DROP SCHEMA test_schema CASCADE;
|
||||
DROP ROLE user_noexec;
|
||||
|
||||
-- test with aggregate check proc
|
||||
create function jsonb_add (j1 jsonb, j2 jsonb) returns jsonb
|
||||
AS $$
|
||||
BEGIN
|
||||
RETURN j1 || j2;
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
|
||||
create table jsonb_values (j jsonb, i int);
|
||||
insert into jsonb_values values ('{"refresh_after":"2 weeks"}', 1), ('{"compress_after":"2 weeks"}', 2), ('{"drop_after":"2 weeks"}', 3);
|
||||
|
||||
CREATE AGGREGATE sum_jsb (jsonb)
|
||||
(
|
||||
sfunc = jsonb_add,
|
||||
stype = jsonb,
|
||||
initcond = '{}'
|
||||
);
|
||||
|
||||
-- for test coverage, check unsupported aggregate type
|
||||
select add_job('test_proc_with_check', '5 secs', config => '{}', check_config => 'sum_jsb'::regproc);
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user