Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Move more drops into event trigger system
This PR moves table, schema, and trigger drop handling into the event
trigger system. The event trigger system is a more reliable method of
intercepting object drops especially as they can CASCADE via other
object drops.

This PR also adds a test for DROP OWNED which was previously broken.
  • Loading branch information
cevian committed Mar 8, 2018
1 parent 088e71e commit 39010db
Show file tree
Hide file tree
Showing 14 changed files with 351 additions and 162 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -95,7 +95,7 @@ analysis that are not present in vanilla PostgreSQL. (For example, the `time_buc

TimescaleDB can be installed via a variety of ways:

- Linux: [yum](https://docs.timescale.com/latest/getting-started/installation/linux/installation-yum), [apt (Ubuntu)](https://docs.timescale.com/latest/getting-started/installation/linux/installation-apt-ubuntu), [apt (Debian)](https://docs.timescale.com/latest/getting-started/installation/linux/installation-apt-debian) [Docker](https://docs.timescale.com/latest/getting-started/installation/linux/installation-docker)
- Linux: [yum](https://docs.timescale.com/latest/getting-started/installation/linux/installation-yum), [apt (Ubuntu)](https://docs.timescale.com/latest/getting-started/installation/linux/installation-apt-ubuntu), [apt (Debian)](https://docs.timescale.com/latest/getting-started/installation/linux/installation-apt-debian), [Docker](https://docs.timescale.com/latest/getting-started/installation/linux/installation-docker)
- MacOS: [brew](https://docs.timescale.com/latest/getting-started/installation/mac/installation-homebrew), [Docker](https://docs.timescale.com/latest/getting-started/installation/mac/installation-docker)
- Windows: [Docker](https://docs.timescale.com/latest/getting-started/installation/windows/installation-docker)

Expand Down
36 changes: 12 additions & 24 deletions src/chunk.c
Expand Up @@ -100,7 +100,7 @@ chunk_fill(Chunk *chunk, HeapTuple tuple)
{
memcpy(&chunk->fd, GETSTRUCT(tuple), sizeof(FormData_chunk));
chunk->table_id = get_relname_relid(chunk->fd.table_name.data,
get_namespace_oid(chunk->fd.schema_name.data, false));
get_namespace_oid(chunk->fd.schema_name.data, true));
chunk->hypertable_relid = parent_relid(chunk->table_id);
}

Expand Down Expand Up @@ -1016,50 +1016,38 @@ chunk_tuple_delete(TupleInfo *ti, void *data)
}

int
chunk_delete_by_relid(Oid relid)
chunk_delete_by_name(const char *schema, const char *table)
{
NameData schema,
table;
ScanKeyData scankey[2];

if (!OidIsValid(relid))
return 0;

namestrcpy(&schema, get_namespace_name(get_rel_namespace(relid)));
namestrcpy(&table, get_rel_name(relid));

ScanKeyInit(&scankey[0], Anum_chunk_schema_name_idx_schema_name, BTEqualStrategyNumber,
F_NAMEEQ, NameGetDatum(&schema));
F_NAMEEQ, DirectFunctionCall1(namein, CStringGetDatum(schema)));
ScanKeyInit(&scankey[1], Anum_chunk_schema_name_idx_table_name, BTEqualStrategyNumber,
F_NAMEEQ, NameGetDatum(&table));
F_NAMEEQ, DirectFunctionCall1(namein, CStringGetDatum(table)));

return chunk_scan_internal(CHUNK_SCHEMA_NAME_INDEX, scankey, 2,
chunk_tuple_delete, NULL, 0,
RowExclusiveLock);
}

int
chunk_delete_by_hypertable_id(int32 hypertable_id)
chunk_delete_by_relid(Oid relid)
{
ScanKeyData scankey[1];

ScanKeyInit(&scankey[0], Anum_chunk_hypertable_id_idx_hypertable_id, BTEqualStrategyNumber,
F_INT4EQ, Int32GetDatum(hypertable_id));
if (!OidIsValid(relid))
return 0;

return chunk_scan_internal(CHUNK_HYPERTABLE_ID_INDEX, scankey, 1,
chunk_tuple_delete, NULL, 0,
RowExclusiveLock);
return chunk_delete_by_name(get_namespace_name(get_rel_namespace(relid)), get_rel_name(relid));
}

int
chunk_delete_by_schema_name(const char *schema_name)
chunk_delete_by_hypertable_id(int32 hypertable_id)
{
ScanKeyData scankey[1];

ScanKeyInit(&scankey[0], Anum_chunk_schema_name_idx_schema_name, BTEqualStrategyNumber,
F_NAMEEQ, DirectFunctionCall1(namein, CStringGetDatum(schema_name)));
ScanKeyInit(&scankey[0], Anum_chunk_hypertable_id_idx_hypertable_id, BTEqualStrategyNumber,
F_INT4EQ, Int32GetDatum(hypertable_id));

return chunk_scan_internal(CHUNK_SCHEMA_NAME_INDEX, scankey, 1,
return chunk_scan_internal(CHUNK_HYPERTABLE_ID_INDEX, scankey, 1,
chunk_tuple_delete, NULL, 0,
RowExclusiveLock);
}
Expand Down
2 changes: 1 addition & 1 deletion src/chunk.h
Expand Up @@ -75,6 +75,6 @@ extern bool chunk_exists_relid(Oid relid);
extern void chunk_recreate_all_constraints_for_dimension(Hyperspace *hs, int32 dimension_id);
extern int chunk_delete_by_relid(Oid chunk_oid);
extern int chunk_delete_by_hypertable_id(int32 hypertable_id);
extern int chunk_delete_by_schema_name(const char *schema_name);
extern int chunk_delete_by_name(const char *schema, const char *table);

#endif /* TIMESCALEDB_CHUNK_H */
8 changes: 4 additions & 4 deletions src/chunk_index.c
Expand Up @@ -446,11 +446,11 @@ chunk_index_create_from_stmt(IndexStmt *stmt,
}

static inline Oid
chunk_index_get_schemaid(Form_chunk_index chunk_index)
chunk_index_get_schemaid(Form_chunk_index chunk_index, bool missing_ok)
{
Chunk *chunk = chunk_get_by_id(chunk_index->chunk_id, 0, true);

return get_namespace_oid(NameStr(chunk->fd.schema_name), false);
return get_namespace_oid(NameStr(chunk->fd.schema_name), missing_ok);
}

#define chunk_index_tuple_get_schema(tuple) \
Expand Down Expand Up @@ -591,7 +591,7 @@ static bool
chunk_index_tuple_delete(TupleInfo *ti, void *data)
{
FormData_chunk_index *chunk_index = (FormData_chunk_index *) GETSTRUCT(ti->tuple);
Oid schemaid = chunk_index_get_schemaid(chunk_index);
Oid schemaid = chunk_index_get_schemaid(chunk_index, true);
ChunkIndexDeleteData *cid = data;

catalog_delete(ti->scanrel, ti->tuple);
Expand Down Expand Up @@ -852,7 +852,7 @@ chunk_index_tuple_set_tablespace(TupleInfo *ti, void *data)
{
char *tablespace = data;
FormData_chunk_index *chunk_index = (FormData_chunk_index *) GETSTRUCT(ti->tuple);
Oid schemaoid = chunk_index_get_schemaid(chunk_index);
Oid schemaoid = chunk_index_get_schemaid(chunk_index, false);
Oid indexrelid = get_relname_relid(NameStr(chunk_index->index_name), schemaoid);
AlterTableCmd *cmd = makeNode(AlterTableCmd);
List *cmds = NIL;
Expand Down
100 changes: 92 additions & 8 deletions src/event_trigger.c
Expand Up @@ -6,6 +6,8 @@
#include <catalog/pg_type.h>
#include <catalog/pg_constraint.h>
#include <catalog/pg_class.h>
#include <catalog/pg_namespace.h>
#include <catalog/pg_trigger.h>

#include "event_trigger.h"

Expand Down Expand Up @@ -97,7 +99,7 @@ extract_addrnames(ArrayType *arr)
}

static EventTriggerDropTableConstraint *
makeEventTriggerDropTableConstraint(char *constraint_name, char *schema, char *table)
make_event_trigger_drop_table_constraint(char *constraint_name, char *schema, char *table)
{
EventTriggerDropTableConstraint *obj = palloc(sizeof(EventTriggerDropTableConstraint));

Expand All @@ -116,7 +118,7 @@ makeEventTriggerDropTableConstraint(char *constraint_name, char *schema, char *t
}

static EventTriggerDropIndex *
makeEventTriggerDropIndex(char *index_name, char *schema)
make_event_trigger_drop_index(char *index_name, char *schema)
{
EventTriggerDropIndex *obj = palloc(sizeof(EventTriggerDropIndex));

Expand All @@ -132,6 +134,59 @@ makeEventTriggerDropIndex(char *index_name, char *schema)
return obj;
}

static EventTriggerDropTable *
make_event_trigger_drop_table(char *table_name, char *schema)
{
EventTriggerDropTable *obj = palloc(sizeof(EventTriggerDropTable));

*obj = (EventTriggerDropTable)
{
.obj =
{
.type = EVENT_TRIGGER_DROP_TABLE
},
.table_name = table_name,
.schema = schema,
};
return obj;
}

static EventTriggerDropSchema *
make_event_trigger_drop_schema(char *schema)
{
EventTriggerDropSchema *obj = palloc(sizeof(EventTriggerDropSchema));

*obj = (EventTriggerDropSchema)
{
.obj =
{
.type = EVENT_TRIGGER_DROP_SCHEMA
},
.schema = schema,
};
return obj;
}

static EventTriggerDropTrigger *
make_event_trigger_drop_trigger(char *trigger_name, char *schema, char *table)
{
EventTriggerDropTrigger *obj = palloc(sizeof(EventTriggerDropTrigger));

*obj = (EventTriggerDropTrigger)
{
.obj =
{
.type = EVENT_TRIGGER_DROP_TRIGGER
},
.trigger_name = trigger_name,
.schema = schema,
.table = table
};

return obj;
}


List *
event_trigger_dropped_objects(void)
{
Expand Down Expand Up @@ -173,22 +228,51 @@ event_trigger_dropped_objects(void)
List *addrnames = extract_addrnames(DatumGetArrayTypeP(values[10]));

objects = lappend(objects,
makeEventTriggerDropTableConstraint(lthird(addrnames),
linitial(addrnames),
lsecond(addrnames)));
make_event_trigger_drop_table_constraint(lthird(addrnames),
linitial(addrnames),
lsecond(addrnames)));
}
break;
case RelationRelationId:
objtype = TextDatumGetCString(values[6]);
if (objtype != NULL && strcmp(objtype, "index") == 0)
if (objtype == NULL)
break;
if (strcmp(objtype, "index") == 0)
{
List *addrnames = extract_addrnames(DatumGetArrayTypeP(values[10]));

objects = lappend(objects,
make_event_trigger_drop_index(lsecond(addrnames),
linitial(addrnames)));
}
else if (strcmp(objtype, "table") == 0)
{
List *addrnames = extract_addrnames(DatumGetArrayTypeP(values[10]));

objects = lappend(objects,
makeEventTriggerDropIndex(lsecond(addrnames),
linitial(addrnames)));
make_event_trigger_drop_table(lsecond(addrnames),
linitial(addrnames)));
}
break;
case NamespaceRelationId:
{
List *addrnames = extract_addrnames(DatumGetArrayTypeP(values[10]));

objects = lappend(objects,
make_event_trigger_drop_schema(linitial(addrnames)));
}
break;
case TriggerRelationId:
{
List *addrnames = extract_addrnames(DatumGetArrayTypeP(values[10]));

objects = lappend(objects,
make_event_trigger_drop_trigger(lthird(addrnames),
linitial(addrnames),
lsecond(addrnames)));
}
break;

default:
break;
}
Expand Down
24 changes: 24 additions & 0 deletions src/event_trigger.h
Expand Up @@ -8,6 +8,9 @@ typedef enum EventTriggerDropType
{
EVENT_TRIGGER_DROP_TABLE_CONSTRAINT,
EVENT_TRIGGER_DROP_INDEX,
EVENT_TRIGGER_DROP_TABLE,
EVENT_TRIGGER_DROP_SCHEMA,
EVENT_TRIGGER_DROP_TRIGGER
} EventTriggerDropType;

typedef struct EventTriggerDropObject
Expand All @@ -30,6 +33,27 @@ typedef struct EventTriggerDropIndex
char *schema;
} EventTriggerDropIndex;

typedef struct EventTriggerDropTable
{
EventTriggerDropObject obj;
char *table_name;
char *schema;
} EventTriggerDropTable;

typedef struct EventTriggerDropSchema
{
EventTriggerDropObject obj;
char *schema;
} EventTriggerDropSchema;

typedef struct EventTriggerDropTrigger
{
EventTriggerDropObject obj;
char *trigger_name;
char *schema;
char *table;
} EventTriggerDropTrigger;

extern List *event_trigger_dropped_objects(void);
extern List *event_trigger_ddl_commands(void);
extern void _event_trigger_init(void);
Expand Down
10 changes: 7 additions & 3 deletions src/hypertable.c
Expand Up @@ -301,16 +301,20 @@ hypertable_delete_by_id(int32 hypertable_id)


int
hypertable_delete_by_schema_name(const char *schema_name)
hypertable_delete_by_name(const char *schema_name, const char *table_name)
{
ScanKeyData scankey[1];
ScanKeyData scankey[2];

ScanKeyInit(&scankey[0], Anum_hypertable_name_idx_schema,
BTEqualStrategyNumber, F_NAMEEQ,
DirectFunctionCall1(namein, CStringGetDatum(schema_name)));

ScanKeyInit(&scankey[1], Anum_hypertable_name_idx_table,
BTEqualStrategyNumber, F_NAMEEQ,
DirectFunctionCall1(namein, CStringGetDatum(table_name)));

return hypertable_scan_limit_internal(scankey,
1,
2,
HYPERTABLE_NAME_INDEX,
hypertable_tuple_delete,
NULL,
Expand Down
2 changes: 1 addition & 1 deletion src/hypertable.h
Expand Up @@ -36,7 +36,7 @@ extern int hypertable_set_name(Hypertable *ht, const char *newname);
extern int hypertable_set_schema(Hypertable *ht, const char *newname);
extern int hypertable_set_num_dimensions(Hypertable *ht, int16 num_dimensions);
extern int hypertable_delete_by_id(int32 hypertable_id);
extern int hypertable_delete_by_schema_name(const char *schema_name);
extern int hypertable_delete_by_name(const char *schema_name, const char *table_name);
extern int hypertable_reset_associated_schema_name(const char *associated_schema);
extern Oid hypertable_id_to_relid(int32 hypertable_id);
extern Chunk *hypertable_get_chunk(Hypertable *h, Point *point);
Expand Down
4 changes: 4 additions & 0 deletions src/partitioning.c
Expand Up @@ -151,6 +151,10 @@ partitioning_info_create(const char *schema,
StrNCpy(pinfo->column, partcol, NAMEDATALEN);
pinfo->column_attnum = get_attnum(relid, pinfo->column);

/* handle the case that the attribute has been dropped */
if (pinfo->column_attnum == InvalidAttrNumber)
return NULL;

if (schema != NULL)
StrNCpy(pinfo->partfunc.schema, schema, NAMEDATALEN);

Expand Down

0 comments on commit 39010db

Please sign in to comment.