diff --git a/cstore_fdw--1.7.sql b/cstore_fdw--1.7.sql index 86589ca90..726085b17 100644 --- a/cstore_fdw--1.7.sql +++ b/cstore_fdw--1.7.sql @@ -59,36 +59,36 @@ CREATE EVENT TRIGGER cstore_drop_event EXECUTE PROCEDURE cstore_drop_trigger(); CREATE TABLE cstore_tables ( - relid oid, - block_row_count int, - version_major bigint, - version_minor bigint, + relid oid NOT NULL, + block_row_count int NOT NULL, + version_major bigint NOT NULL, + version_minor bigint NOT NULL, PRIMARY KEY (relid) ) WITH (user_catalog_table = true); ALTER TABLE cstore_tables SET SCHEMA pg_catalog; CREATE TABLE cstore_stripes ( - relid oid, - stripe bigint, - file_offset bigint, - skiplist_length bigint, - data_length bigint, + relid oid NOT NULL, + stripe bigint NOT NULL, + file_offset bigint NOT NULL, + skiplist_length bigint NOT NULL, + data_length bigint NOT NULL, PRIMARY KEY (relid, stripe), - FOREIGN KEY (relid) REFERENCES cstore_tables(relid) ON DELETE CASCADE + FOREIGN KEY (relid) REFERENCES cstore_tables(relid) ON DELETE CASCADE INITIALLY DEFERRED ) WITH (user_catalog_table = true); ALTER TABLE cstore_stripes SET SCHEMA pg_catalog; CREATE TABLE cstore_stripe_attr ( - relid oid, - stripe bigint, - attr int, - exists_size bigint, - value_size bigint, - skiplist_size bigint, + relid oid NOT NULL, + stripe bigint NOT NULL, + attr int NOT NULL, + exists_size bigint NOT NULL, + value_size bigint NOT NULL, + skiplist_size bigint NOT NULL, PRIMARY KEY (relid, stripe, attr), - FOREIGN KEY (relid, stripe) REFERENCES cstore_stripes(relid, stripe) ON DELETE CASCADE + FOREIGN KEY (relid, stripe) REFERENCES cstore_stripes(relid, stripe) ON DELETE CASCADE INITIALLY DEFERRED ) WITH (user_catalog_table = true); ALTER TABLE cstore_stripe_attr SET SCHEMA pg_catalog; diff --git a/cstore_metadata_tables.c b/cstore_metadata_tables.c index f5168de1e..5c381a029 100644 --- a/cstore_metadata_tables.c +++ b/cstore_metadata_tables.c @@ -50,6 +50,8 @@ static void InsertStripeAttrRow(Oid relid, uint64 stripe, AttrNumber attr, uint64 skiplistSize); static int TableBlockRowCount(Oid relid); static void DeleteTableMetadataRowIfExists(Oid relid); +static void InsertTupleAndEnforceConstraints(Relation rel, HeapTuple heapTuple); +static void DeleteTupleAndEnforceConstraints(Relation rel, HeapTuple heapTuple); static EState * create_estate_for_relation(Relation rel); /* constants for cstore_stripe_attr */ @@ -103,7 +105,7 @@ InitCStoreTableMetadata(Oid relid, int blockRowCount) tuple = heap_form_tuple(tupleDescriptor, values, nulls); - CatalogTupleInsert(cstoreTable, tuple); + InsertTupleAndEnforceConstraints(cstoreTable, tuple); CommandCounterIncrement(); @@ -132,7 +134,7 @@ InsertStripeMetadataRow(Oid relid, StripeMetadata *stripe) HeapTuple tuple = heap_form_tuple(tupleDescriptor, values, nulls); - CatalogTupleInsert(cstoreStripes, tuple); + InsertTupleAndEnforceConstraints(cstoreStripes, tuple); CommandCounterIncrement(); @@ -264,23 +266,7 @@ DeleteTableMetadataRowIfExists(Oid relid) heapTuple = systable_getnext(scanDescriptor); if (HeapTupleIsValid(heapTuple)) { - EState *estate = create_estate_for_relation(cstoreTables); - ResultRelInfo *resultRelInfo = estate->es_result_relation_info; - - ItemPointer tid = &(heapTuple->t_self); - simple_table_tuple_delete(cstoreTables, tid, estate->es_snapshot); - - /* - * Execute AFTER ROW DELETE Triggers to enforce foreign key - * constraints. - */ - ExecARDeleteTriggers(estate, resultRelInfo, - tid, NULL, NULL); - - AfterTriggerEndQuery(estate); - ExecCleanUpTriggerState(estate); - ExecResetTupleTable(estate->es_tupleTable, false); - FreeExecutorState(estate); + DeleteTupleAndEnforceConstraints(cstoreTables, heapTuple); } systable_endscan_ordered(scanDescriptor); @@ -289,6 +275,59 @@ DeleteTableMetadataRowIfExists(Oid relid) } +/* + * InsertTupleAndEnforceConstraints inserts a tuple into a relation and + * makes sure constraints (e.g. FK constraints, NOT NULL, ...) are enforced. + */ +static void +InsertTupleAndEnforceConstraints(Relation rel, HeapTuple heapTuple) +{ + EState *estate = NULL; + TupleTableSlot *slot = NULL; + + estate = create_estate_for_relation(rel); + slot = ExecInitExtraTupleSlot(estate, RelationGetDescr(rel), &TTSOpsHeapTuple); + ExecStoreHeapTuple(heapTuple, slot, false); + + ExecOpenIndices(estate->es_result_relation_info, false); + + /* ExecSimpleRelationInsert executes any constraints */ + ExecSimpleRelationInsert(estate, slot); + + ExecCloseIndices(estate->es_result_relation_info); + + AfterTriggerEndQuery(estate); + ExecCleanUpTriggerState(estate); + ExecResetTupleTable(estate->es_tupleTable, false); + FreeExecutorState(estate); +} + + + +/* + * DeleteTupleAndEnforceConstraints deletes a tuple from a relation and + * makes sure constraints (e.g. FK constraints) are enforced. + */ +static void +DeleteTupleAndEnforceConstraints(Relation rel, HeapTuple heapTuple) +{ + EState *estate = create_estate_for_relation(rel); + ResultRelInfo *resultRelInfo = estate->es_result_relation_info; + + ItemPointer tid = &(heapTuple->t_self); + simple_table_tuple_delete(rel, tid, estate->es_snapshot); + + /* execute AFTER ROW DELETE Triggers to enforce constraints */ + ExecARDeleteTriggers(estate, resultRelInfo, + tid, NULL, NULL); + + AfterTriggerEndQuery(estate); + ExecCleanUpTriggerState(estate); + ExecResetTupleTable(estate->es_tupleTable, false); + FreeExecutorState(estate); +} + + /* * Based on a similar function from * postgres/src/backend/replication/logical/worker.c. @@ -370,7 +409,7 @@ InsertStripeAttrRow(Oid relid, uint64 stripe, AttrNumber attr, HeapTuple tuple = heap_form_tuple(tupleDescriptor, values, nulls); - CatalogTupleInsert(cstoreStripeAttrs, tuple); + InsertTupleAndEnforceConstraints(cstoreStripeAttrs, tuple); CommandCounterIncrement();