diff --git a/.travis.yml b/.travis.yml index 48d6af9..5d5bd49 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,19 @@ +dist: trusty +sudo: required language: c env: + - PG=10 - PG=9.6 - PG=9.5 - PG=9.4 - PG=9.3 - PG=9.2 install: + - sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main 10" > /etc/apt/sources.list.d/pgdg.list' + - wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - - PGPORT=5440 - sudo /etc/init.d/postgresql stop - - sudo apt-get update -o Dir::Etc::sourcelist=/dev/null + - sudo apt-get -o Dir::Etc::sourcelist="/etc/apt/sources.list.d/pgdg.list" -o Dir::Etc::sourceparts='-' -o APT::Get::List-Cleanup='0' update - sudo apt-get install postgresql-$PG postgresql-server-dev-$PG - sudo pg_createcluster -p $PGPORT $PG test - sudo sed -i '1i local all all trust' /etc/postgresql/$PG/test/pg_hba.conf diff --git a/GNUmakefile b/GNUmakefile index 1e6a99c..3660a3e 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -13,7 +13,7 @@ DOCS = README.md REGRESS = install no_system_period invalid_system_period \ no_history_table no_history_system_period invalid_types \ - invalid_system_period_values \ + invalid_system_period_values renaming \ versioning versioning_custom_system_time combinations \ structure uninstall diff --git a/appveyor.yml b/appveyor.yml index aff8d26..4223a18 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,14 +11,16 @@ environment: PGUSER: postgres PGPASSWORD: Password12! matrix: - - exe: postgresql-9.3.14-1-windows-%PLATFORM%.exe - - exe: postgresql-9.4.9-1-windows-%PLATFORM%.exe - - exe: postgresql-9.5.4-1-windows-%PLATFORM%.exe - - exe: postgresql-9.6.0-1-windows-%PLATFORM%.exe + - exe: postgresql-9.3.18-1-windows-%PLATFORM%.exe + - exe: postgresql-9.4.13-1-windows-%PLATFORM%.exe + - exe: postgresql-9.5.8-1-windows-%PLATFORM%.exe + - exe: postgresql-9.6.4-1-windows-%PLATFORM%.exe + - exe: postgresql-10.0-beta3-windows-%PLATFORM%.exe install: - set dist=%exe:-x86=% -- set pgversion=%exe:~11,3% +# http://www.databasesoup.com/2016/05/changing-postgresql-version-numbering.html +- for /f "tokens=2 delims=-" %%A in ("%exe%") do set pgversion=%%~nA - echo pgversion=%pgversion% - if %PLATFORM%==x64 ( set pf=%ProgramFiles%&& set x64=-x64) else set pf=%ProgramFiles(x86)% - set pgroot=%pf%\PostgreSQL\%pgversion% @@ -61,10 +63,12 @@ test_script: - net start postgresql%x64%-%pgversion% - appveyor AddTest Regression -Framework pg_regress -FileName sql\ -Outcome Running -- if %pgversion:~2,1% LEQ 4 ( set psqlopt=--psqldir) else set psqlopt=--bindir +- set psqlopt=--bindir +- if %pgversion%==9.3 set psqlopt=--psqldir +- if %pgversion%==9.4 set psqlopt=--psqldir - pg_regress "%psqlopt%=%pgroot%\bin" install no_system_period invalid_system_period no_history_table - no_history_system_period invalid_types invalid_system_period_values + no_history_system_period invalid_types invalid_system_period_values renaming versioning versioning_custom_system_time structure uninstall - if ERRORLEVEL 1 (set Outcome=Failed) else set Outcome=Passed - perl -e "my @s=stat('regression.out'); print 1000*($s[9]-$s[10]);" > duration diff --git a/expected/renaming.out b/expected/renaming.out new file mode 100644 index 0000000..c6c3a74 --- /dev/null +++ b/expected/renaming.out @@ -0,0 +1,178 @@ +CREATE TABLE versioning (a bigint, "b b" date, sys_period tstzrange); +-- Insert some data before versioning is enabled. +INSERT INTO versioning (a, sys_period) VALUES (1, tstzrange('-infinity', NULL)); +INSERT INTO versioning (a, sys_period) VALUES (2, tstzrange('2000-01-01', NULL)); +CREATE TABLE versioning_history (a bigint, c date, sys_period tstzrange); +CREATE OR REPLACE FUNCTION setup_versioning( + main regclass, + sys_period_column text, + history regclass, + adjust boolean) + RETURNS void AS +$BODY$ +begin + execute format(' +CREATE TRIGGER versioning_trigger +BEFORE INSERT OR UPDATE OR DELETE ON %I +FOR EACH ROW EXECUTE PROCEDURE versioning2(''%s'', ''%s'', %s); +', main, sys_period_column, history::oid, adjust::text); +end; +$BODY$ + LANGUAGE plpgsql; +SELECT setup_versioning('versioning', 'sys_period', 'versioning_history', false); + setup_versioning +------------------ + +(1 row) + +-- Insert. +BEGIN; +INSERT INTO versioning (a) VALUES (3); +SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM versioning ORDER BY a, sys_period; + a | b b | ?column? +---+-----+---------- + 1 | | f + 2 | | f + 3 | | t +(3 rows) + +SELECT * FROM versioning_history ORDER BY a, sys_period; + a | c | sys_period +---+---+------------ +(0 rows) + +COMMIT; +-- Make sure that the next transaction's CURRENT_TIMESTAMP is different. +SELECT pg_sleep(0.1); + pg_sleep +---------- + +(1 row) + +-- Update. +BEGIN; +UPDATE versioning SET a = 4 WHERE a = 3; +SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM versioning ORDER BY a, sys_period; + a | b b | ?column? +---+-----+---------- + 1 | | f + 2 | | f + 4 | | t +(3 rows) + +SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM versioning_history ORDER BY a, sys_period; + a | c | ?column? +---+---+---------- + 3 | | t +(1 row) + +SELECT a, "b b" FROM versioning WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period; + a | b b +---+----- + 4 | +(1 row) + +COMMIT; +-- Make sure that the next transaction's CURRENT_TIMESTAMP is different. +SELECT pg_sleep(0.1); + pg_sleep +---------- + +(1 row) + +-- Multiple updates. +BEGIN; +UPDATE versioning SET a = 5 WHERE a = 4; +UPDATE versioning SET "b b" = '2012-01-01' WHERE a = 5; +SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM versioning ORDER BY a, sys_period; + a | b b | ?column? +---+------------+---------- + 1 | | f + 2 | | f + 5 | 01-01-2012 | t +(3 rows) + +SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM versioning_history ORDER BY a, sys_period; + a | c | ?column? +---+---+---------- + 3 | | f + 4 | | t +(2 rows) + +SELECT a, "b b" FROM versioning WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period; + a | b b +---+------------ + 5 | 01-01-2012 +(1 row) + +COMMIT; +-- Make sure that the next transaction's CURRENT_TIMESTAMP is different. +SELECT pg_sleep(0.1); + pg_sleep +---------- + +(1 row) + +-- Rename both tables +ALTER TABLE versioning RENAME TO versioning_new; +ALTER TABLE versioning_history RENAME TO versioning_new_history; +-- Delete. +BEGIN; +DELETE FROM versioning_new WHERE a = 4; +SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM versioning_new ORDER BY a, sys_period; + a | b b | ?column? +---+------------+---------- + 1 | | f + 2 | | f + 5 | 01-01-2012 | f +(3 rows) + +SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM versioning_new_history ORDER BY a, sys_period; + a | c | ?column? +---+---+---------- + 3 | | f + 4 | | f +(2 rows) + +SELECT a, "b b" FROM versioning_new WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period; + a | b b +---+----- +(0 rows) + +END; +-- Make sure that the next transaction's CURRENT_TIMESTAMP is different. +SELECT pg_sleep(0.1); + pg_sleep +---------- + +(1 row) + +CREATE SCHEMA new; +ALTER TABLE versioning_new_history SET SCHEMA new; +-- Delete. +BEGIN; +DELETE FROM versioning_new; +SELECT * FROM versioning_new; + a | b b | sys_period +---+-----+------------ +(0 rows) + +SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM new.versioning_new_history ORDER BY a, sys_period; + a | c | ?column? +---+---+---------- + 1 | | t + 2 | | t + 3 | | f + 4 | | f + 5 | | t +(5 rows) + +SELECT a, "b b" FROM versioning_new WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period; + a | b b +---+----- +(0 rows) + +END; +DROP TABLE versioning_new; +DROP TABLE new.versioning_new_history; +DROP SCHEMA new; diff --git a/sql/renaming.sql b/sql/renaming.sql new file mode 100644 index 0000000..4302494 --- /dev/null +++ b/sql/renaming.sql @@ -0,0 +1,113 @@ +CREATE TABLE versioning (a bigint, "b b" date, sys_period tstzrange); + +-- Insert some data before versioning is enabled. +INSERT INTO versioning (a, sys_period) VALUES (1, tstzrange('-infinity', NULL)); +INSERT INTO versioning (a, sys_period) VALUES (2, tstzrange('2000-01-01', NULL)); + +CREATE TABLE versioning_history (a bigint, c date, sys_period tstzrange); + +CREATE OR REPLACE FUNCTION setup_versioning( + main regclass, + sys_period_column text, + history regclass, + adjust boolean) + RETURNS void AS +$BODY$ +begin + execute format(' +CREATE TRIGGER versioning_trigger +BEFORE INSERT OR UPDATE OR DELETE ON %I +FOR EACH ROW EXECUTE PROCEDURE versioning2(''%s'', ''%s'', %s); +', main, sys_period_column, history::oid, adjust::text); +end; +$BODY$ + LANGUAGE plpgsql; + +SELECT setup_versioning('versioning', 'sys_period', 'versioning_history', false); + +-- Insert. +BEGIN; + +INSERT INTO versioning (a) VALUES (3); + +SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM versioning ORDER BY a, sys_period; + +SELECT * FROM versioning_history ORDER BY a, sys_period; + +COMMIT; + +-- Make sure that the next transaction's CURRENT_TIMESTAMP is different. +SELECT pg_sleep(0.1); + +-- Update. +BEGIN; + +UPDATE versioning SET a = 4 WHERE a = 3; + +SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM versioning ORDER BY a, sys_period; + +SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM versioning_history ORDER BY a, sys_period; + +SELECT a, "b b" FROM versioning WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period; + +COMMIT; + +-- Make sure that the next transaction's CURRENT_TIMESTAMP is different. +SELECT pg_sleep(0.1); + +-- Multiple updates. +BEGIN; + +UPDATE versioning SET a = 5 WHERE a = 4; +UPDATE versioning SET "b b" = '2012-01-01' WHERE a = 5; + +SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM versioning ORDER BY a, sys_period; + +SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM versioning_history ORDER BY a, sys_period; + +SELECT a, "b b" FROM versioning WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period; + +COMMIT; + +-- Make sure that the next transaction's CURRENT_TIMESTAMP is different. +SELECT pg_sleep(0.1); + +-- Rename both tables +ALTER TABLE versioning RENAME TO versioning_new; +ALTER TABLE versioning_history RENAME TO versioning_new_history; + +-- Delete. +BEGIN; + +DELETE FROM versioning_new WHERE a = 4; + +SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM versioning_new ORDER BY a, sys_period; + +SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM versioning_new_history ORDER BY a, sys_period; + +SELECT a, "b b" FROM versioning_new WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period; + +END; + +-- Make sure that the next transaction's CURRENT_TIMESTAMP is different. +SELECT pg_sleep(0.1); + +CREATE SCHEMA new; +ALTER TABLE versioning_new_history SET SCHEMA new; + +-- Delete. +BEGIN; + +DELETE FROM versioning_new; + +SELECT * FROM versioning_new; + +SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM new.versioning_new_history ORDER BY a, sys_period; + +SELECT a, "b b" FROM versioning_new WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period; + +END; + +DROP TABLE versioning_new; +DROP TABLE new.versioning_new_history; +DROP SCHEMA new; diff --git a/temporal_tables--1.1.1.sql b/temporal_tables--1.1.1.sql index 242c702..0f0903e 100644 --- a/temporal_tables--1.1.1.sql +++ b/temporal_tables--1.1.1.sql @@ -12,6 +12,15 @@ REVOKE ALL ON FUNCTION versioning() FROM PUBLIC; COMMENT ON FUNCTION versioning() IS 'System-period temporal table trigger'; +CREATE FUNCTION versioning2() +RETURNS TRIGGER +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; + +REVOKE ALL ON FUNCTION versioning2() FROM PUBLIC; + +COMMENT ON FUNCTION versioning2() IS 'System-period temporal table trigger, use OID as text for history relation'; + CREATE FUNCTION set_system_time(timestamptz) RETURNS VOID AS 'MODULE_PATHNAME' diff --git a/versioning.c b/versioning.c index a8b5ff2..8c39dea 100644 --- a/versioning.c +++ b/versioning.c @@ -24,6 +24,9 @@ #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/rangetypes.h" +#if PG_VERSION_NUM >= 100000 +#include "utils/regproc.h" +#endif #include "utils/rel.h" #include "utils/syscache.h" #include "utils/timestamp.h" @@ -35,9 +38,13 @@ #endif PGDLLEXPORT Datum versioning(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum versioning2(PG_FUNCTION_ARGS); PGDLLEXPORT Datum set_system_time(PG_FUNCTION_ARGS); +static Datum versioning_common(bool has_oid, PG_FUNCTION_ARGS); + PG_FUNCTION_INFO_V1(versioning); +PG_FUNCTION_INFO_V1(versioning2); PG_FUNCTION_INFO_V1(set_system_time); /* Warning if system period was adjusted. */ @@ -48,6 +55,7 @@ typedef struct VersioningHashEntry { Oid relid; /* hash key (must be first) */ Oid history_relid; /* OID of the history relation */ + char history_relname[NAMEDATALEN]; TupleDesc tupdesc; /* tuple descriptor of the versioned relation */ TupleDesc history_tupdesc; /* tuple descriptor of the history relation */ @@ -99,7 +107,7 @@ static void fill_versioning_hash_entry(VersioningHashEntry *hash_entry, static void insert_history_row(HeapTuple tuple, Relation relation, - const char *history_relation_argument, + Oid history_relation_oid, const char *period_attname); static void deserialize_system_period(HeapTuple tuple, @@ -124,6 +132,9 @@ static void adjust_system_period(TypeCacheEntry *typcache, static bool modified_in_current_transaction(HeapTuple tuple); +static HeapTuple modify_tuple(Relation rel, HeapTuple tuple, + int period_attnum, RangeType *range); + static Datum versioning_insert(TriggerData *trigdata, TypeCacheEntry *typcache, int period_attnum); @@ -132,14 +143,14 @@ static Datum versioning_update(TriggerData *trigdata, TypeCacheEntry *typcache, int period_attnum, const char *period_attname, - const char *history_relation_argument, + Oid history_relation_oid, const char *adjust_argument); static Datum versioning_delete(TriggerData *trigdata, TypeCacheEntry *typcache, int period_attnum, const char *period_attname, - const char *history_relation_argument, + Oid history_relation, const char *adjust_argument); static void init_versioning_hash_table(); @@ -177,8 +188,8 @@ static VersioningHashEntry *lookup_versioning_hash_entry(Oid relid, * FOR EACH ROW EXECUTE PROCEDURE * versioning(, , ). */ -Datum -versioning(PG_FUNCTION_ARGS) +static Datum +versioning_common(bool has_oid, PG_FUNCTION_ARGS) { TriggerData *trigdata; Trigger *trigger; @@ -263,15 +274,38 @@ versioning(PG_FUNCTION_ARGS) if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) return versioning_insert(trigdata, typcache, period_attnum); - else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - return versioning_update(trigdata, typcache, - period_attnum, period_attname, - args[1], args[2]); else - /* otherwise this is ON DELETE trigger */ - return versioning_delete(trigdata, typcache, - period_attnum, period_attname, - args[1], args[2]); + { + Oid history_relation_oid; + if (has_oid) + history_relation_oid = strtoul(args[1], NULL, 10); + else + { + RangeVar *relrv = makeRangeVarFromNameList(stringToQualifiedNameList(args[1])); + history_relation_oid = RangeVarGetRelid(relrv, AccessShareLock, false);; + } + if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) + return versioning_update(trigdata, typcache, + period_attnum, period_attname, + history_relation_oid, args[2]); + else + /* otherwise this is ON DELETE trigger */ + return versioning_delete(trigdata, typcache, + period_attnum, period_attname, + history_relation_oid, args[2]); + } +} + +Datum +versioning(PG_FUNCTION_ARGS) +{ + return versioning_common(false, fcinfo); +} + +Datum +versioning2(PG_FUNCTION_ARGS) +{ + return versioning_common(true, fcinfo); } /* @@ -562,6 +596,7 @@ fill_versioning_hash_entry(VersioningHashEntry *hash_entry, oldcontext = MemoryContextSwitchTo(TopMemoryContext); hash_entry->history_relid = RelationGetRelid(history_relation); + memcpy(hash_entry->history_relname, NameStr(history_relation->rd_rel->relname), NAMEDATALEN); hash_entry->tupdesc = CreateTupleDescCopyConstr(tupdesc); hash_entry->history_tupdesc = CreateTupleDescCopyConstr(history_tupdesc); @@ -591,10 +626,9 @@ fill_versioning_hash_entry(VersioningHashEntry *hash_entry, static void insert_history_row(HeapTuple tuple, Relation relation, - const char *history_relation_name, + Oid history_relation_oid, const char *period_attname) { - RangeVar *relrv; Relation history_relation; VersioningHashEntry *hash_entry; bool found; @@ -603,9 +637,7 @@ insert_history_row(HeapTuple tuple, int natts; /* Open the history relation and obtain AccessShareLock on it. */ - relrv = makeRangeVarFromNameList(stringToQualifiedNameList(history_relation_name)); - - history_relation = heap_openrv(relrv, AccessShareLock); + history_relation = heap_open(history_relation_oid, AccessShareLock); /* Look up the cached data for the versioned relation OID. */ hash_entry = lookup_versioning_hash_entry(RelationGetRelid(relation), @@ -631,11 +663,14 @@ insert_history_row(HeapTuple tuple, * Then check that the structure of the versioned table and the history * table is intact by comparing the cached TupleDesc with the current * one. + * + * Also check whether history table name has changed. */ if (hash_entry->natts == -1 || RelationGetRelid(history_relation) != hash_entry->history_relid || !equalTupleDescs(tupdesc, hash_entry->tupdesc) || - !equalTupleDescs(history_tupdesc, hash_entry->history_tupdesc)) + !equalTupleDescs(history_tupdesc, hash_entry->history_tupdesc) || + 0 != strncmp(NameStr(history_relation->rd_rel->relname), hash_entry->history_relname, NAMEDATALEN)) { /* Mark the entry invalid. */ hash_entry->natts = -1; @@ -863,6 +898,25 @@ modified_in_current_transaction(HeapTuple tuple) return TransactionIdIsCurrentTransactionId(oldxmin); } +/* + * Tuple modification wrapper around SPI_modifytuple for PG<10 + * and heap_modify_tuple_by_cols for PG 10 + */ +static HeapTuple +modify_tuple(Relation rel, HeapTuple tuple, int period_attnum, RangeType *range) +{ + int colnum[1] = { period_attnum }; + Datum values[1] = { RangeTypeGetDatum(range) }; +#if PG_VERSION_NUM >= 100000 + bool nulls[1] = { false }; + return heap_modify_tuple_by_cols(tuple, RelationGetDescr(rel), 1, colnum, values, nulls); +#else + char nulls[1] = { ' ' }; + return SPI_modifytuple(rel, tuple, 1, colnum, values, nulls); +#endif +} + + /* * Set system period attribute value of the current row to * "[system_time, )". @@ -875,9 +929,6 @@ versioning_insert(TriggerData *trigdata, RangeBound lower; RangeBound upper; RangeType *range; - int colnum[1]; - Datum values[1]; - char nulls[1]; /* Construct a period for the current row. */ lower.val = TimestampTzGetDatum(get_system_time()); @@ -891,14 +942,7 @@ versioning_insert(TriggerData *trigdata, range = make_range(typcache, &lower, &upper, false); - /* Modify the current row and return it. */ - colnum[0] = period_attnum; - values[0] = RangeTypeGetDatum(range); - nulls[0] = ' '; - - return PointerGetDatum(SPI_modifytuple(trigdata->tg_relation, - trigdata->tg_trigtuple, - 1, colnum, values, nulls)); + return PointerGetDatum(modify_tuple(trigdata->tg_relation, trigdata->tg_trigtuple, period_attnum, range)); } /* @@ -918,7 +962,7 @@ versioning_update(TriggerData *trigdata, TypeCacheEntry *typcache, int period_attnum, const char *period_attname, - const char *history_relation_argument, + Oid history_relation_oid, const char *adjust_argument) { HeapTuple tuple; @@ -927,9 +971,6 @@ versioning_update(TriggerData *trigdata, RangeBound upper; RangeType *range; HeapTuple history_tuple; - int colnum[1]; - Datum values[1]; - char nulls[1]; tuple = trigdata->tg_trigtuple; @@ -952,14 +993,9 @@ versioning_update(TriggerData *trigdata, range = make_range(typcache, &lower, &upper, false); - /* Construct and insert the history row. */ - colnum[0] = period_attnum; - values[0] = RangeTypeGetDatum(range); - nulls[0] = ' '; - - history_tuple = SPI_modifytuple(relation, tuple, 1, colnum, values, nulls); + history_tuple = modify_tuple(relation, tuple, period_attnum, range); - insert_history_row(history_tuple, relation, history_relation_argument, + insert_history_row(history_tuple, relation, history_relation_oid, period_attname); /* Construct a period for the current row. */ @@ -972,13 +1008,7 @@ versioning_update(TriggerData *trigdata, range = make_range(typcache, &lower, &upper, false); - /* Modify the current row and return it. */ - colnum[0] = period_attnum; - values[0] = RangeTypeGetDatum(range); - nulls[0] = ' '; - - return PointerGetDatum(SPI_modifytuple(relation, trigdata->tg_newtuple, - 1, colnum, values, nulls)); + return PointerGetDatum(modify_tuple(relation, trigdata->tg_newtuple, period_attnum, range)); } /* @@ -994,7 +1024,7 @@ versioning_delete(TriggerData *trigdata, TypeCacheEntry *typcache, int period_attnum, const char *period_attname, - const char *history_relation_argument, + Oid history_relation_oid, const char *adjust_argument) { HeapTuple tuple; @@ -1002,9 +1032,6 @@ versioning_delete(TriggerData *trigdata, RangeBound lower; RangeBound upper; RangeType *range; - int colnum[1]; - Datum values[1]; - char nulls[1]; HeapTuple history_tuple; tuple = trigdata->tg_trigtuple; @@ -1028,14 +1055,9 @@ versioning_delete(TriggerData *trigdata, range = make_range(typcache, &lower, &upper, false); - /* Construct and insert the history row. */ - colnum[0] = period_attnum; - values[0] = RangeTypeGetDatum(range); - nulls[0] = ' '; - - history_tuple = SPI_modifytuple(relation, tuple, 1, colnum, values, nulls); + history_tuple = modify_tuple(relation, tuple, period_attnum, range); - insert_history_row(history_tuple, relation, history_relation_argument, + insert_history_row(history_tuple, relation, history_relation_oid, period_attname); return PointerGetDatum(tuple);