Search Postgresql Archives

Re: Trigger problems/questions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 06/15/2017 10:23 AM, Jim Fulton wrote:
I have an object database that's mirrored to a table with data in a JSONB column. Data are organized into "communities". Community ids aren't stored directly in content but can be found by recursively following __parent__ properties. I want to be able to index content records on their community ids.

(I originally tried to index functions that got ids, but apparently lying about immutability is a bad idea and I suffered the consequences. :-])

I tried creating a trigger to populate a community_zoid property with a community id when a record is inserted or updated. The trigger calls a recursive functions to get the community id.

Trigger: https://github.com/karlproject/karl/blob/master/karl/scripts/pgevolve.py#L261 <https://github.com/karlproject/karl/blob/master/karl/scripts/pgevolve.py#L261>

Trigger procedure: https://github.com/karlproject/karl/blob/master/karl/scripts/pgevolve.py#L236 <https://github.com/karlproject/karl/blob/master/karl/scripts/pgevolve.py#L236>

Function to find a community id: https://github.com/karlproject/karl/blob/master/karl/scripts/pgevolve.py#L209 <https://github.com/karlproject/karl/blob/master/karl/scripts/pgevolve.py#L209>

This scheme succeeds most of the time, but occasionally, it fails.

I can find records where it has failed with a query like:

   select zoid
   from newt
   where find_community_zoid(zoid, class_name, state) is not null
     and not state ? 'community_zoid';

If I update the records where it has failed:

   update newt set class_name=class_name
   where find_community_zoid(zoid, class_name, state) is not null
      and not state ? 'community_zoid';

Then retry the query above, I get 0 rows back. This would seem to indicate that the trigger is logically correct.

Questions:

  * Am I doing it wrong?  For example, is there some limitation on
    trigger procedures that I'm violating?
  * If a trigger procedure errors, is the transaction aborted? (I would
    hope so.)
  * Should I expect triggers to be reliable and rely on them for
    database integrity?
  * Any suggestions on how to debug this?

I do not pretend to fully understand what the the triggers/functions are really doing, but I did notice this:

create or replace function populate_community_zoid_triggerf()

...

new_zoid := NEW.state ->> 'community_zoid';
zoid := find_community_zoid(
            NEW.zoid, NEW.class_name, NEW.state)::text;
if zoid is null then
    if new_zoid is not null then
    NEW.state := NEW.state - 'community_zoid';
    end if;
else
    if new_zoid is null or zoid != new_zoid then
    NEW.state :=
        NEW.state || ('{"community_zoid": ' || zoid || '}')::jsonb;
    end if;
end if;

...


Not sure what happens if zoid is null and new_zoid is null also?
Or if it matters?



Jim

--
Jim Fulton
http://jimfulton.info


--
Adrian Klaver
adrian.klaver@xxxxxxxxxxx


--
Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]

  Powered by Linux