You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To reproduce I set up some tables like below, with a base table example_table and a history table example_table_history. The example_table has a versioning TRIGGER which runs this function: https://github.com/nearform/temporal_tables/blob/master/versioning_function.sql whenever an update / delete / insert is done on the main table in order to preserve history.
CREATETABLEexample_table_history
(
id INTEGERNOT NULL,
col1 VARCHARNOT NULL,
col2 VARCHARNOT NULL,
last_changed TIMESTAMPTZNOT NULL,
system_period tstzrange NOT NULL DEFAULT TSTZRANGE(CURRENT_TIMESTAMP, NULL)
) PARTITION BY RANGE (last_changed);
CREATETABLEexample_table_history_table_template
(
LIKE example_table_history
);
ALTERTABLE example_table_history_table_template ADD PRIMARY KEY (id, last_changed);
SELECTpartman.create_parent(
'public.example_table_history',
'last_changed',
'1 month',
p_template_table :='public.example_table_history_table_template',
p_premake :=6);
UPDATEpartman.part_configSET retention ='2 months'::INTERVAL WHERE parent_table ='public.example_table_history';
CREATETABLEexample_table
(
id INTEGERNOT NULL,
col1 VARCHARNOT NULL,
col2 VARCHARNOT NULL,
last_changed TIMESTAMPTZNOT NULL DEFAULT NOW(),
system_period tstzrange NOT NULL DEFAULT TSTZRANGE(CURRENT_TIMESTAMP, NULL)
) PARTITION BY RANGE (last_changed);
CREATETABLEexample_table_table_template
(
LIKE example_table
);
ALTERTABLE example_table_table_template
ADD PRIMARY KEY (id);
SELECTpartman.create_parent(
'public.example_table',
'last_changed',
'1 month',
p_template_table :='public.example_table_table_template',
p_premake :=6);
UPDATEpartman.part_configSET retention ='4 months'::INTERVAL
WHERE parent_table ='public.example_table';
CREATETRIGGERversioning_trigger
BEFORE INSERT ORUPDATEORDELETEON example_table
FOR EACH ROW
EXECUTE PROCEDURE versioning(
'system_period', 'example_table_history', TRUE
);
INSERT INTO example_table (id, col1, col2)
VALUES (1, 'sad', '1'),
(2, 'ok', '2'),
(3, 'happy', '3');
Only now when I run the final query is where things go wrong. Only the columns that were updated by the initial update statement are also updated by this statement. Even though it says UPDATE 3, only 1 row is actually updated.
Expected behavior: no values in col1 are null and all columns are updated based on col1_old.
Actual behavior: only the rows updated in a statement executed previously in the same transaction are updated.
The issue doesn't happen without the versioning function trigger, though the behavior of the versioning function doesn't seem to me like it should be problematic. Maybe I'm misunderstanding how a trigger like this interacts with a partitioned table or how to correctly update partitioned tables, please let me know if that's the case. Changing the order of the updates and moving the ALTER to the start of the transaction produces the correct behavior.
Thank you for your time and help :)
The text was updated successfully, but these errors were encountered:
Apologies, but I'm not quite sure why this is happening. It's not anything particular to pg_partman that I can see so far, but just partitioning in general with PG. I think you may get better answers on the PG mailing lists. Can try the general one first and if you don't get a response, maybe the hackers or bugs list.
If I have a chance I'll try and come back to revisit this as well and see if I can figure anything out, but I at least wanted to point you to some additional help in case I don't get back to it for a while. If you do find an answer on the lists, I'd appreciate you letting me know as well. Thanks!
Thanks for your reply! I wasn't sure what or where the problem exactly was either, I'll take a look at the mailing list and will post here if I find anything.
To reproduce I set up some tables like below, with a base table
example_table
and a history tableexample_table_history
. Theexample_table
has a versioning TRIGGER which runs this function: https://github.com/nearform/temporal_tables/blob/master/versioning_function.sql whenever an update / delete / insert is done on the main table in order to preserve history.So far so good, we have a table with 3 rows:
Now things go wrong if I run the following update and schema changes in a single transaction:
The first update:
UPDATE example_table SET col2 = '4', last_changed = now() WHERE id = 1
runs correctly:The alter table also works as expected:
Only now when I run the final query is where things go wrong. Only the columns that were updated by the initial update statement are also updated by this statement. Even though it says
UPDATE 3
, only 1 row is actually updated.Expected behavior: no values in
col1
are null and all columns are updated based oncol1_old
.Actual behavior: only the rows updated in a statement executed previously in the same transaction are updated.
The issue doesn't happen without the versioning function trigger, though the behavior of the versioning function doesn't seem to me like it should be problematic. Maybe I'm misunderstanding how a trigger like this interacts with a partitioned table or how to correctly update partitioned tables, please let me know if that's the case. Changing the order of the updates and moving the ALTER to the start of the transaction produces the correct behavior.
Thank you for your time and help :)
The text was updated successfully, but these errors were encountered: