Skip to content

Commit 4b6e2a6

Browse files
committed
fixup! verionsing using oid
1 parent 6b92758 commit 4b6e2a6

File tree

3 files changed

+36
-107
lines changed

3 files changed

+36
-107
lines changed

expected/renaming.out

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ SELECT pg_sleep(0.1);
147147

148148
(1 row)
149149

150+
CREATE SCHEMA IF NOT EXISTS new;
151+
ALTER TABLE versioning_new_history SET SCHEMA new;
150152
-- Delete.
151153
BEGIN;
152154
DELETE FROM versioning_new;
@@ -155,7 +157,7 @@ SELECT * FROM versioning_new;
155157
---+-----+------------
156158
(0 rows)
157159

158-
SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM versioning_new_history ORDER BY a, sys_period;
160+
SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM new.versioning_new_history ORDER BY a, sys_period;
159161
a | c | ?column?
160162
---+---+----------
161163
1 | | t
@@ -172,4 +174,5 @@ SELECT a, "b b" FROM versioning_new WHERE lower(sys_period) = CURRENT_TIMESTAMP
172174

173175
END;
174176
DROP TABLE versioning_new;
175-
DROP TABLE versioning_new_history;
177+
DROP TABLE new.versioning_new_history;
178+
DROP SCHEMA new;

sql/renaming.sql

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ SELECT pg_sleep(0.1);
7474

7575
-- Rename both tables
7676
ALTER TABLE versioning RENAME TO versioning_new;
77-
7877
ALTER TABLE versioning_history RENAME TO versioning_new_history;
7978

8079
-- Delete.
@@ -93,18 +92,22 @@ END;
9392
-- Make sure that the next transaction's CURRENT_TIMESTAMP is different.
9493
SELECT pg_sleep(0.1);
9594

95+
CREATE SCHEMA IF NOT EXISTS new;
96+
ALTER TABLE versioning_new_history SET SCHEMA new;
97+
9698
-- Delete.
9799
BEGIN;
98100

99101
DELETE FROM versioning_new;
100102

101103
SELECT * FROM versioning_new;
102104

103-
SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM versioning_new_history ORDER BY a, sys_period;
105+
SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM new.versioning_new_history ORDER BY a, sys_period;
104106

105107
SELECT a, "b b" FROM versioning_new WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period;
106108

107109
END;
108110

109111
DROP TABLE versioning_new;
110-
DROP TABLE versioning_new_history;
112+
DROP TABLE new.versioning_new_history;
113+
DROP SCHEMA new;

versioning.c

Lines changed: 25 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ PGDLLEXPORT Datum versioning(PG_FUNCTION_ARGS);
4141
PGDLLEXPORT Datum versioning2(PG_FUNCTION_ARGS);
4242
PGDLLEXPORT Datum set_system_time(PG_FUNCTION_ARGS);
4343

44+
static Datum versioning_common(bool has_oid, PG_FUNCTION_ARGS);
45+
4446
PG_FUNCTION_INFO_V1(versioning);
4547
PG_FUNCTION_INFO_V1(versioning2);
4648
PG_FUNCTION_INFO_V1(set_system_time);
@@ -53,6 +55,7 @@ typedef struct VersioningHashEntry
5355
{
5456
Oid relid; /* hash key (must be first) */
5557
Oid history_relid; /* OID of the history relation */
58+
char history_relname[NAMEDATALEN];
5659
TupleDesc tupdesc; /* tuple descriptor of the versioned relation */
5760
TupleDesc history_tupdesc; /* tuple descriptor of the history relation */
5861

@@ -185,8 +188,8 @@ static VersioningHashEntry *lookup_versioning_hash_entry(Oid relid,
185188
* FOR EACH ROW EXECUTE PROCEDURE
186189
* versioning(<system_period_column_name>, <history_relation>, <adjust>).
187190
*/
188-
Datum
189-
versioning(PG_FUNCTION_ARGS)
191+
static Datum
192+
versioning_common(bool has_oid, PG_FUNCTION_ARGS)
190193
{
191194
TriggerData *trigdata;
192195
Trigger *trigger;
@@ -273,9 +276,14 @@ versioning(PG_FUNCTION_ARGS)
273276
return versioning_insert(trigdata, typcache, period_attnum);
274277
else
275278
{
276-
RangeVar *relrv = makeRangeVarFromNameList(stringToQualifiedNameList(args[1]));
277-
Oid history_relation_oid = RangeVarGetRelid(relrv, AccessShareLock, false);;
278-
279+
Oid history_relation_oid;
280+
if (has_oid)
281+
history_relation_oid = strtoul(args[1], NULL, 10);
282+
else
283+
{
284+
RangeVar *relrv = makeRangeVarFromNameList(stringToQualifiedNameList(args[1]));
285+
history_relation_oid = RangeVarGetRelid(relrv, AccessShareLock, false);;
286+
}
279287
if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
280288
return versioning_update(trigdata, typcache,
281289
period_attnum, period_attname,
@@ -289,104 +297,15 @@ versioning(PG_FUNCTION_ARGS)
289297
}
290298

291299
Datum
292-
versioning2(PG_FUNCTION_ARGS)
300+
versioning(PG_FUNCTION_ARGS)
293301
{
294-
TriggerData *trigdata;
295-
Trigger *trigger;
296-
char **args;
297-
Relation relation;
298-
TupleDesc tupdesc;
299-
char *period_attname;
300-
int period_attnum;
301-
Form_pg_attribute period_attr;
302-
TypeCacheEntry *typcache;
303-
304-
trigdata = (TriggerData *)fcinfo->context;
305-
306-
/* Check that the trigger function was called in expected context. */
307-
if (!CALLED_AS_TRIGGER(fcinfo))
308-
ereport(ERROR,
309-
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
310-
errmsg("function \"versioning2\" was not called by trigger manager")));
311-
312-
/* Check proper event. */
313-
if (!TRIGGER_FIRED_BEFORE(trigdata->tg_event) ||
314-
!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
315-
ereport(ERROR,
316-
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
317-
errmsg("function \"versioning2\" must be fired BEFORE ROW")));
318-
319-
if (!TRIGGER_FIRED_BY_INSERT(trigdata->tg_event) &&
320-
!TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event) &&
321-
!TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
322-
ereport(ERROR,
323-
(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
324-
errmsg("function \"versioning2\" must be fired for INSERT or UPDATE or DELETE")));
325-
326-
trigger = trigdata->tg_trigger;
327-
328-
/* Check number of arguments. */
329-
if (trigger->tgnargs != 3)
330-
ereport(ERROR,
331-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
332-
errmsg("wrong number of parameters for function \"versioning2\""),
333-
errdetail("expected 3 parameters but got %d",
334-
trigger->tgnargs)));
335-
336-
args = trigger->tgargs;
337-
338-
relation = trigdata->tg_relation;
339-
340-
tupdesc = RelationGetDescr(relation);
341-
342-
period_attname = args[0];
343-
344-
/* Check that system period attribute exists in the versioned relation. */
345-
period_attnum = SPI_fnumber(tupdesc, period_attname);
346-
347-
if (period_attnum == SPI_ERROR_NOATTRIBUTE)
348-
ereport(ERROR,
349-
(errcode(ERRCODE_UNDEFINED_COLUMN),
350-
errmsg("column \"%s\" of relation \"%s\" does not exist",
351-
period_attname,
352-
RelationGetRelationName(relation))));
353-
354-
period_attr = tupdesc->attrs[period_attnum - 1];
355-
356-
/* Check that system period attribute is not dropped. */
357-
if (period_attr->attisdropped)
358-
ereport(ERROR,
359-
(errcode(ERRCODE_UNDEFINED_COLUMN),
360-
errmsg("column \"%s\" of relation \"%s\" does not exist",
361-
period_attname,
362-
RelationGetRelationName(relation))));
363-
364-
/* Check that system period attribute is not an array. */
365-
if (period_attr->attndims != 0)
366-
ereport(ERROR,
367-
(errcode(ERRCODE_DATATYPE_MISMATCH),
368-
errmsg("system period column \"%s\" of relation \"%s\" is not a range but an array",
369-
period_attname,
370-
RelationGetRelationName(relation))));
371-
372-
/* Locate the typcache entry for the type of system period attribute. */
373-
typcache = get_period_typcache(fcinfo, period_attr, relation);
302+
return versioning_common(false, fcinfo);
303+
}
374304

375-
if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
376-
return versioning_insert(trigdata, typcache, period_attnum);
377-
else
378-
{
379-
Oid oid = strtoul(args[1], NULL, 10);
380-
if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
381-
return versioning_update(trigdata, typcache,
382-
period_attnum, period_attname,
383-
oid, args[2]);
384-
else
385-
/* otherwise this is ON DELETE trigger */
386-
return versioning_delete(trigdata, typcache,
387-
period_attnum, period_attname,
388-
oid, args[2]);
389-
}
305+
Datum
306+
versioning2(PG_FUNCTION_ARGS)
307+
{
308+
return versioning_common(true, fcinfo);
390309
}
391310

392311
/*
@@ -677,6 +596,7 @@ fill_versioning_hash_entry(VersioningHashEntry *hash_entry,
677596
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
678597

679598
hash_entry->history_relid = RelationGetRelid(history_relation);
599+
memcpy(hash_entry->history_relname, NameStr(history_relation->rd_rel->relname), NAMEDATALEN);
680600
hash_entry->tupdesc = CreateTupleDescCopyConstr(tupdesc);
681601
hash_entry->history_tupdesc = CreateTupleDescCopyConstr(history_tupdesc);
682602

@@ -743,11 +663,14 @@ insert_history_row(HeapTuple tuple,
743663
* Then check that the structure of the versioned table and the history
744664
* table is intact by comparing the cached TupleDesc with the current
745665
* one.
666+
*
667+
* Also check whether history table name has changed.
746668
*/
747669
if (hash_entry->natts == -1 ||
748670
RelationGetRelid(history_relation) != hash_entry->history_relid ||
749671
!equalTupleDescs(tupdesc, hash_entry->tupdesc) ||
750-
!equalTupleDescs(history_tupdesc, hash_entry->history_tupdesc))
672+
!equalTupleDescs(history_tupdesc, hash_entry->history_tupdesc) ||
673+
0 != strncmp(NameStr(history_relation->rd_rel->relname), hash_entry->history_relname, NAMEDATALEN))
751674
{
752675
/* Mark the entry invalid. */
753676
hash_entry->natts = -1;

0 commit comments

Comments
 (0)