mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-22 22:11:29 +08:00
Previously we used postgres dependency tracking to ensure consistent deletes between various continuous agg postgres objects (views and tables). This does not work with dump/restore and thus this PR removes that dependency tracking in favor of handling these deps ourselves in various drop hooks. This PR also adds logic for deleting rows in the continuous_agg metadata table when the view is dropped. It does not yet handle deleting associated threshold metadata, that's left for a future PR. Most of this logic is in the apache-licensed code and not in the TSL since we want people who downgraded from TSL to apache to still be able to drop continuous views.
183 lines
4.1 KiB
C
183 lines
4.1 KiB
C
/*
|
|
* This file and its contents are licensed under the Timescale License.
|
|
* Please see the included NOTICE for copyright information and
|
|
* LICENSE-TIMESCALE for a copy of the license.
|
|
*/
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <postgres.h>
|
|
#include <fmgr.h>
|
|
|
|
#include "export.h"
|
|
#include "process_utility.h"
|
|
|
|
#include "compat.h"
|
|
#include "event_trigger.h"
|
|
#include "cross_module_fn.h"
|
|
|
|
TS_FUNCTION_INFO_V1(ts_test_ddl_command_hook_reg);
|
|
TS_FUNCTION_INFO_V1(ts_test_ddl_command_hook_unreg);
|
|
|
|
static List *tsl_delayed_execution_list = NIL;
|
|
|
|
static void
|
|
test_ddl_command_start(ProcessUtilityArgs *args)
|
|
{
|
|
Cache *hcache;
|
|
ListCell *cell;
|
|
Hypertable *ht;
|
|
|
|
elog(NOTICE,
|
|
"test_ddl_command_start: %d hypertables, query: %s",
|
|
list_length(args->hypertable_list),
|
|
args->query_string);
|
|
|
|
/*
|
|
* Hypertable oid from those commands is available in hypertable_list but
|
|
* cannot be resolved here until standard utility hook will synchronize new
|
|
* relation name and schema.
|
|
*
|
|
* Save hypertable list here for command_end execution to avoid statement
|
|
* parsing for second time.
|
|
*/
|
|
switch (nodeTag(args->parsetree))
|
|
{
|
|
case T_AlterObjectSchemaStmt:
|
|
case T_RenameStmt:
|
|
elog(NOTICE, "test_ddl_command_start: wait for ddl_command_end");
|
|
tsl_delayed_execution_list = list_copy(args->hypertable_list);
|
|
return;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
hcache = ts_hypertable_cache_pin();
|
|
|
|
foreach (cell, args->hypertable_list)
|
|
{
|
|
Oid relid = lfirst_oid(cell);
|
|
|
|
ht = ts_hypertable_cache_get_entry(hcache, relid);
|
|
Assert(ht != NULL);
|
|
|
|
elog(NOTICE,
|
|
"test_ddl_command_start: %s.%s",
|
|
NameStr(ht->fd.schema_name),
|
|
NameStr(ht->fd.table_name));
|
|
}
|
|
|
|
ts_cache_release(hcache);
|
|
}
|
|
|
|
static void
|
|
test_ddl_command_end(EventTriggerData *command)
|
|
{
|
|
Cache *hcache;
|
|
ListCell *cell;
|
|
Hypertable *ht;
|
|
|
|
elog(NOTICE, "test_ddl_command_end: %s", command->tag);
|
|
|
|
if (tsl_delayed_execution_list == NIL)
|
|
return;
|
|
|
|
elog(NOTICE,
|
|
"test_ddl_command_end: %d hypertables scheduled",
|
|
list_length(tsl_delayed_execution_list));
|
|
|
|
hcache = ts_hypertable_cache_pin();
|
|
|
|
foreach (cell, tsl_delayed_execution_list)
|
|
{
|
|
Oid relid = lfirst_oid(cell);
|
|
|
|
ht = ts_hypertable_cache_get_entry(hcache, relid);
|
|
Assert(ht != NULL);
|
|
|
|
elog(NOTICE,
|
|
"test_ddl_command_end: %s.%s",
|
|
NameStr(ht->fd.schema_name),
|
|
NameStr(ht->fd.table_name));
|
|
}
|
|
|
|
ts_cache_release(hcache);
|
|
|
|
pfree(tsl_delayed_execution_list);
|
|
tsl_delayed_execution_list = NIL;
|
|
}
|
|
|
|
static void
|
|
test_sql_drop(List *dropped_objects)
|
|
{
|
|
ListCell *lc;
|
|
|
|
foreach (lc, dropped_objects)
|
|
{
|
|
EventTriggerDropObject *obj = lfirst(lc);
|
|
|
|
switch (obj->type)
|
|
{
|
|
case EVENT_TRIGGER_DROP_TABLE_CONSTRAINT:
|
|
{
|
|
EventTriggerDropTableConstraint *event = (EventTriggerDropTableConstraint *) obj;
|
|
|
|
elog(NOTICE,
|
|
"test_sql_drop: constraint: %s.%s.%s",
|
|
event->schema,
|
|
event->table,
|
|
event->constraint_name);
|
|
break;
|
|
}
|
|
case EVENT_TRIGGER_DROP_INDEX:
|
|
{
|
|
elog(NOTICE, "test_sql_drop: index");
|
|
break;
|
|
}
|
|
case EVENT_TRIGGER_DROP_TABLE:
|
|
{
|
|
EventTriggerDropTable *event = (EventTriggerDropTable *) obj;
|
|
|
|
elog(NOTICE, "test_sql_drop: table: %s.%s", event->schema, event->table_name);
|
|
break;
|
|
}
|
|
case EVENT_TRIGGER_DROP_SCHEMA:
|
|
{
|
|
EventTriggerDropSchema *event = (EventTriggerDropSchema *) obj;
|
|
|
|
elog(NOTICE, "test_sql_drop: schema: %s", event->schema);
|
|
break;
|
|
}
|
|
case EVENT_TRIGGER_DROP_TRIGGER:
|
|
{
|
|
elog(NOTICE, "test_sql_drop: trigger");
|
|
break;
|
|
}
|
|
case EVENT_TRIGGER_DROP_VIEW:
|
|
{
|
|
elog(NOTICE, "test_sql_drop: view");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Datum
|
|
ts_test_ddl_command_hook_reg(PG_FUNCTION_ARGS)
|
|
{
|
|
Assert(ts_cm_functions->ddl_command_start == NULL);
|
|
ts_cm_functions->ddl_command_start = test_ddl_command_start;
|
|
ts_cm_functions->ddl_command_end = test_ddl_command_end;
|
|
ts_cm_functions->sql_drop = test_sql_drop;
|
|
PG_RETURN_VOID();
|
|
}
|
|
|
|
Datum
|
|
ts_test_ddl_command_hook_unreg(PG_FUNCTION_ARGS)
|
|
{
|
|
Assert(ts_cm_functions->ddl_command_start == test_ddl_command_start);
|
|
ts_cm_functions->ddl_command_start = NULL;
|
|
ts_cm_functions->ddl_command_end = NULL;
|
|
ts_cm_functions->sql_drop = NULL;
|
|
PG_RETURN_VOID();
|
|
}
|