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

From: Lionel Bouton <lionel(dot)bouton(at)jtek(dot)fr>
To: Perry Smith <pedz(at)easesoftware(dot)com>, pgsql-general(at)lists(dot)postgresql(dot)org
Subject: Re: What have I done!?!?!? :-)
Date: 2022-04-06 23:05:32
Message-ID: d229ba39-61bc-d62b-d703-25593826cd61@jtek.fr
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Hi Perry,

Le 07/04/2022 à 00:25, Perry Smith a écrit :
> [...]
> Notice that parent_id is suppose to refer to an id in the same table —
> at least, that is what I’m trying to do.  I’m trying to create a
> “root” entry whose parent points to themselves

Note that you don't usually define a root as having a parent_id being
the same as its id (hard to manage especially when you use a sequence
nextval() to auto-fill the "id" primary keys).
The usual way is to have parent_id being nullable and roots are then
rows with no parent_id. This matches the intuitive idea of a root which
makes code more maintainable.

> and I botched the code first time around and now I have this:
>
> files_development=# select * from files;
>  id | basename | parent_id |    dev    |   ftype   | uid  | gid  | ino
> | mode  |     mtime      | nlink | size | created_at         |        
> updated_at
> ----+----------+-----------+-----------+-----------+------+------+-----+-------+----------------+-------+------+----------------------------+----------------------------
>  11 | pedz     | *1234* | 687931150 | directory | 1000 | 1002 |   2 |
> 16877 | 18:43:29.65271 |  31 |   34 | 2022-04-06 21:58:43.570539 |
> 2022-04-06 21:58:43.570539
>  12 | pedz     |        12 | 687931150 | directory | 1000 | 1002 |   2
> | 16877 | 18:43:29.65271 |    31 |   34 | 2022-04-06 22:00:29.087417 |
> 2022-04-06 22:00:29.115021
> (2 rows)
>
>
> The record with id 11 has a parent id of 1234 which doesn’t exist.
>
> My question isn’t how do I fix it, my question is why didn’t Postgres
> back out the botched record?  Why isn’t it complaining?

Disabling referential integrity in Active Record explicitly disables
triggers that would have made PostgreSQL return an error.

>
> I’m using Active Record with the psql adapter.  It has a
> disable_referential_integrity which takes a block of code.  When the
> block of code exists, the constraints are put back.  At least, that is
> what I thought.

If you look at ActiveRecord's code
(https://www.rubydoc.info/docs/rails/ActiveRecord/ConnectionAdapters/PostgreSQL/ReferentialIntegrity#disable_referential_integrity-instance_method)
:
before the block of code the triggers are disabled, then the block is
executed and finally the triggers are enabled again (but only after they
would have had a chance to be used).

I don't think this code is meant for general use (I believe I only used
it in data migrations on rare occasions). I would bet that this isn't
safe to use in many cases : unless I missed something you could kill
your process before the triggers are enabled again leaving your
application with 0 constraints until disable_referential_integrity is
used again. What happens when several processes are using it
simultaneously is probably not what you want either (triggers being
enabled again by another process in the middle of the execution of your
code).

>
> I’m wondering if the disabled constraints are still disabled somehow.

Constraints are implemented using triggers so they aren't meant to
ensure a consistent global state, they only check that the modifications
are OK at the moment they are done.
If you disable constraints temporarily nothing prevents your data from
being inconsistent with your constraints.

>  If so, how would I check for that and how would I turn them back on?
>  Or am I way off in the weeds?

I'd say the later : in your case I would use a NULL parent_id for
root(s). Your way leads you to bend PostgreSQL until its back brakes.

Best regards,

--
Lionel Bouton
gérant de JTEK SARL
https://www.linkedin.com/in/lionelbouton/

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Perry Smith 2022-04-06 23:15:41 Re: What have I done!?!?!? :-)
Previous Message Chris Bisnett 2022-04-06 22:45:28 Re: Per-Table vacuum_freeze_min_age