Re: BUG #14809: Heap Corruption with deeply nested triggers.

From: Matthew Maurer <matthew(dot)r(dot)maurer(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-bugs(at)postgresql(dot)org
Subject: Re: BUG #14809: Heap Corruption with deeply nested triggers.
Date: 2017-09-09 17:58:44
Message-ID: CAM22NNC+=h6uYpD9OW5J8-rSgFMM=0V15emCVwJC9PbB_HR4Gg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

In case it helps, I was running Ubuntu Xenial inside docker.

On Sat, Sep 9, 2017 at 1:46 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> matthew(dot)r(dot)maurer(at)gmail(dot)com writes:
>> Log looks like: https://bpaste.net/show/4c1d3940ca27
>> https://data.maurer.codes/clique.sql contains a reproduction case.
>
> For the archives' sake, it'd have been better to include the test case.
> The test isn't very large so I'll attach it below.
>
>> On my machine, this consistently causes the glibc heap assertion in about 9
>> seconds on a fresh database. If you get "ERROR: stack depth limit exceeded"
>> you may need to increase your max_stack_depth to observe the error (mine was
>> 2MB, but is a release build, debug builds might need more to hit this).
>
> I tried a few different max_stack_depth settings on both 9.6 and HEAD,
> but was unable to reproduce a crash. I see either a clean "stack depth
> limit exceeded" failure, or successful completion of the query (at
> stack depths above circa 3MB for me). Tested on RHEL6 x86_64; maybe
> some other platform would show the problem.
>
> regards, tom lane
>
>
> -- General initialization
> CREATE SCHEMA facts;
> -- Define predicates
> CREATE TABLE facts.edge (id serial PRIMARY KEY, arg0 bigint, arg1 bigint);
> CREATE TABLE facts.reachable (id serial PRIMARY KEY, arg0 bigint, arg1 bigint);
> CREATE TABLE facts.same_clique (id serial PRIMARY KEY, arg0 bigint, arg1 bigint);
> -- Restrict predicates to contain unique facts
> CREATE UNIQUE INDEX pred_edge_unique ON facts.edge (arg0,arg1);
> CREATE UNIQUE INDEX pred_reachable_unique ON facts.reachable (arg0,arg1);
> CREATE UNIQUE INDEX pred_same_clique_unique ON facts.same_clique (arg0,arg1);
> -- Add triggers to automate rules
>
> CREATE FUNCTION holmes_rule_reach_edge_0() RETURNS trigger AS $reach_edge$
> BEGIN
> INSERT INTO facts.reachable (arg0, arg1) (SELECT NEW.arg0, NEW.arg1 ) ON CONFLICT DO NOTHING;
> RETURN NULL;
> END;
> $reach_edge$ LANGUAGE plpgsql;
> CREATE TRIGGER holmes_rule_reach_edge_0 AFTER INSERT ON facts.edge FOR EACH ROW EXECUTE PROCEDURE holmes_rule_reach_edge_0();
> ;
>
> CREATE FUNCTION holmes_rule_reach_trans_0() RETURNS trigger AS $reach_trans$
> BEGIN
> INSERT INTO facts.reachable (arg0, arg1) (SELECT NEW.arg0, t0.arg1 FROM facts.reachable as t0 WHERE NEW.arg1 = t0.arg0) ON CONFLICT DO NOTHING;
> RETURN NULL;
> END;
> $reach_trans$ LANGUAGE plpgsql;
> CREATE TRIGGER holmes_rule_reach_trans_0 AFTER INSERT ON facts.edge FOR EACH ROW EXECUTE PROCEDURE holmes_rule_reach_trans_0();
>
>
> CREATE FUNCTION holmes_rule_reach_trans_1() RETURNS trigger AS $reach_trans$
> BEGIN
> INSERT INTO facts.reachable (arg0, arg1) (SELECT t0.arg0, NEW.arg1 FROM facts.edge as t0 WHERE t0.arg1 = NEW.arg0) ON CONFLICT DO NOTHING;
> RETURN NULL;
> END;
> $reach_trans$ LANGUAGE plpgsql;
> CREATE TRIGGER holmes_rule_reach_trans_1 AFTER INSERT ON facts.reachable FOR EACH ROW EXECUTE PROCEDURE holmes_rule_reach_trans_1();
> ;
>
> CREATE FUNCTION holmes_rule_scc_0() RETURNS trigger AS $scc$
> BEGIN
> INSERT INTO facts.same_clique (arg0, arg1) (SELECT NEW.arg0, NEW.arg1 FROM facts.reachable as t0 WHERE NEW.arg1 = t0.arg0 AND NEW.arg0 = t0.arg1) ON CONFLICT DO NOTHING;
> RETURN NULL;
> END;
> $scc$ LANGUAGE plpgsql;
> CREATE TRIGGER holmes_rule_scc_0 AFTER INSERT ON facts.reachable FOR EACH ROW EXECUTE PROCEDURE holmes_rule_scc_0();
>
>
> CREATE FUNCTION holmes_rule_scc_1() RETURNS trigger AS $scc$
> BEGIN
> INSERT INTO facts.same_clique (arg0, arg1) (SELECT t0.arg0, t0.arg1 FROM facts.reachable as t0 WHERE t0.arg1 = NEW.arg0 AND t0.arg0 = NEW.arg1) ON CONFLICT DO NOTHING;
> RETURN NULL;
> END;
> $scc$ LANGUAGE plpgsql;
> CREATE TRIGGER holmes_rule_scc_1 AFTER INSERT ON facts.reachable FOR EACH ROW EXECUTE PROCEDURE holmes_rule_scc_1();
> ;
>
> CREATE FUNCTION insert_for_clique(iters int) RETURNS VOID as $$
> DECLARE
> counter integer := 0;
> BEGIN
> LOOP
> EXIT WHEN counter = iters;
> INSERT INTO facts.edge (arg0, arg1) values (counter, counter + 1);
> counter := counter + 1;
> END LOOP;
> INSERT INTO facts.edge (arg0, arg1) values (counter, 0);
> END ; $$ LANGUAGE plpgsql;
>
> SELECT insert_for_clique(1000);
>

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Tom Lane 2017-09-09 18:59:54 Re: BUG #14808: V10-beta4, backend abort
Previous Message Tom Lane 2017-09-09 17:46:56 Re: BUG #14809: Heap Corruption with deeply nested triggers.