Re: What have I done!?!?!? :-)

From: Magnus Hagander <magnus(at)hagander(dot)net>
To: Perry Smith <pedz(at)easesoftware(dot)com>
Cc: Jan Wieck <jan(at)wi3ck(dot)info>, Nikolay Samokhvalov <samokhvalov(at)gmail(dot)com>, pgsql-general(at)lists(dot)postgresql(dot)org
Subject: Re: What have I done!?!?!? :-)
Date: 2022-04-08 13:28:06
Message-ID: CABUevEyAprJsWVaoO_ktZd3kTVe5ozE9G=Fa74eOEz1ktORqdA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On Fri, Apr 8, 2022 at 3:27 PM Magnus Hagander <magnus(at)hagander(dot)net> wrote:

>
>
> On Fri, Apr 8, 2022 at 3:23 PM Perry Smith <pedz(at)easesoftware(dot)com> wrote:
>
>>
>>
>> On Apr 8, 2022, at 07:47, Jan Wieck <jan(at)wi3ck(dot)info> wrote:
>>
>> On 4/8/22 01:57, Nikolay Samokhvalov wrote:
>>
>> On Thu, Apr 7, 2022 at 8:10 AM Jan Wieck <jan(at)wi3ck(dot)info <
>> mailto:jan(at)wi3ck(dot)info <jan(at)wi3ck(dot)info>>> wrote:
>> So **IF** Active Record is using that feature, then it can dump any
>> amount of garbage into your PostgreSQL database and PostgreSQL will
>> happily accept it with zero integrity checking.
>> It's DISABLE TRIGGER ALL
>> https://github.com/rails/rails/blob/831031a8cec5bfe59ef653ae2857d4fe64c5698d/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity.rb#L12
>> <
>> https://github.com/rails/rails/blob/831031a8cec5bfe59ef653ae2857d4fe64c5698d/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity.rb#L12
>> >
>>
>>
>> Similar poison, same side effect.
>>
>> Looking further at that code it also directly updates the PostgreSQL
>> system catalog. This is a big, red flag.
>>
>> Why do the Rails developers think they need a sledgehammer like that? It
>> seems to be doing that for over 7 years, so it is hard to tell from the
>> commit log why they need to disable RI at all.
>>
>>
>> It has been a long time since I’ve done Rails stuff. What follows is the
>> best I can recall but please take it with a grain of salt.
>>
>> The first problem is that generally Rails does not put constraints in the
>> database. There were others like me who thought that was insane and would
>> put constraints in the database — this includes foreign key constraints,
>> check constraints, etc. About the only constraint that could be added into
>> the DB using native Rails was the “not null” constraint.
>>
>> When foreign and other constraints were added, it broke something they
>> call “Fixtures” which are present db states that are plopped into the DB
>> during testing. To “fix” that, I (and others) would add this into our code
>> base: (I’m adding this to see what you guys think of it — is it safer /
>> better or just as insane?)
>>
>> def disable_referential_integrity(&block)
>> transaction {
>> begin
>> execute "SET CONSTRAINTS ALL DEFERRED"
>> yield
>> ensure
>> execute "SET CONSTRAINTS ALL IMMEDIATE"
>> end
>> }
>> end
>>
>
> This is perfectly normal code and nothing wrong with it. DEFERRED
> constraints are how you are *supposed* to handle such things. It defers the
> check of the foreign key to the end of the transaction, but it will still
> fail to commit if the foreign key is broken *at that point*. But it lets
> you do things like modify multiple tables that refer to each other, and
> have the changes only checked when they're all done.
>
>
Oh, I should add. The code is correct. The name of the function is wrong,
because it doesn't actually disable referential integrity. It only
postpones it.

--
Magnus Hagander
Me: https://www.hagander.net/ <http://www.hagander.net/>
Work: https://www.redpill-linpro.com/ <http://www.redpill-linpro.com/>

In response to

Browse pgsql-general by date

  From Date Subject
Next Message David G. Johnston 2022-04-08 13:36:34 Re: PostgreSQL : error hint for LATERAL join
Previous Message Perry Smith 2022-04-08 13:27:27 Re: What have I done!?!?!? :-)