pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Tomas Vondra <tomas.vondra@enterprisedb.com>
To: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Subject: Assert failure in CTE inlining with view and correlated subquery
Date: Wed, 20 Apr 2022 23:33:19 +0200
Message-ID: <29196a1e-ed47-c7ca-9be2-b1c636816183@enterprisedb.com> (raw)

Hi,

it seems there's something wrong with CTE inlining when there's a view
containing a correlated subquery referencing the CTE. Consider a simple
example like this:

    create table results (
      id          serial primary key,
      run         text,
      tps         float4
    );

    create view results_agg as
    with base_tps as (
      select run, tps from results
    )
    select
        run,
        count(*) as runs,

        (select tps from base_tps b where b.run = r.run) AS base_tps

    from results r
    group by
        run
    order by
        run;

    explain SELECT run FROM results_agg ORDER BY 1;


This crashes on this assert in inline_cte():

    Assert(context.refcount == 0);

because the refcount value remains 1. There's a backtrace attached.

I don't know why exactly this happens, my knowledge of CTE inlining is
somewhat limited. The counter is clearly out of sync


but a couple more observations:

1) it fails all the way back to PG12, where CTE inlining was added

2) it does not happen if the CTE is defined as MATERIALIZED

                   QUERY PLAN
    -----------------------------------------
     Subquery Scan on results_agg
       ->  Sort
             Sort Key: r.run
             CTE base_tps
               ->  Seq Scan on results
             ->  HashAggregate
                   Group Key: r.run
                   ->  Seq Scan on results r
    (8 rows)

3) without asserts, it seems to work and the query generates this plan

                   QUERY PLAN
    -----------------------------------------
     Subquery Scan on results_agg
       ->  Sort
             Sort Key: r.run
             ->  HashAggregate
                   Group Key: r.run
                   ->  Seq Scan on results r
    (6 rows)

4) it does not seem to happen without the view, i.e. this works

    explain
    with base_tps as (
      select run, tps from results
    )
    select run from (
      select
        run,
        count(*) as runs,

        (select tps from base_tps b where b.run = r.run) AS base_tps

    from results r
    group by
        run
    order by
        run
    ) results_agg order by 1;

The difference between plans in (2) and (3) is interesting, because it
seems the CTE got inlined, so why was the refcount not decremented?


regards

-- 
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

Attachments:

  test.sql (application/sql, 710B) download

backtrace.txt (text/plain, 3.0K) download Missing separate debuginfos, use: dnf debuginfo-install libgcc-11.2.1-9.fc34.x86_64 (gdb) bt #0 0x00007159d9be82a2 in raise () from /lib64/libc.so.6 #1 0x00007159d9bd18a4 in abort () from /lib64/libc.so.6 #2 0x000000000096d3fa in ExceptionalCondition (conditionName=conditionName@entry=0xae4ed3 "context.refcount == 0", errorType=errorType@entry=0x9c3017 "FailedAssertion", fileName=fileName@entry=0xae4da6 "subselect.c", lineNumber=lineNumber@entry=1166) at assert.c:69 #3 0x000000000078acda in inline_cte (cte=0x134e240, root=0x1242298) at subselect.c:1166 #4 SS_process_ctes (root=root@entry=0x1242298) at subselect.c:963 #5 0x0000000000782fb1 in subquery_planner (glob=0x134dbc0, parse=parse@entry=0x134daa8, parent_root=parent_root@entry=0x13491e8, hasRecursion=hasRecursion@entry=false, tuple_fraction=0) at planner.c:650 #6 0x0000000000752afe in set_subquery_pathlist (rte=<optimized out>, rti=<optimized out>, rel=<optimized out>, root=<optimized out>) at allpaths.c:2572 #7 set_rel_size (root=<optimized out>, rel=<optimized out>, rti=<optimized out>, rte=<optimized out>) at allpaths.c:424 #8 0x0000000000755080 in set_base_rel_sizes (root=<optimized out>) at allpaths.c:325 #9 make_one_rel (root=root@entry=0x13491e8, joinlist=joinlist@entry=0x134e078) at allpaths.c:187 #10 0x000000000077b4c2 in query_planner (root=root@entry=0x13491e8, qp_callback=qp_callback@entry=0x77c450 <standard_qp_callback>, qp_extra=qp_extra@entry=0x7fff5a500ba0) at planmain.c:276 #11 0x0000000000781122 in grouping_planner (root=<optimized out>, tuple_fraction=<optimized out>) at planner.c:1467 #12 0x00000000007838a1 in subquery_planner (glob=glob@entry=0x134dbc0, parse=parse@entry=0x1241818, parent_root=parent_root@entry=0x0, hasRecursion=hasRecursion@entry=false, tuple_fraction=tuple_fraction@entry=0) at planner.c:1044 #13 0x0000000000783ee3 in standard_planner (parse=0x1241818, query_string=<optimized out>, cursorOptions=2048, boundParams=<optimized out>) at planner.c:406 #14 0x000000000084e7a8 in pg_plan_query (querytree=0x1241818, query_string=query_string@entry=0x12407d0 "SELECT run FROM results_agg ORDER BY 1;", cursorOptions=cursorOptions@entry=2048, boundParams=boundParams@entry=0x0) at postgres.c:883 #15 0x000000000084e8a1 in pg_plan_queries (querytrees=0x134bf00, query_string=query_string@entry=0x12407d0 "SELECT run FROM results_agg ORDER BY 1;", cursorOptions=cursorOptions@entry=2048, boundParams=boundParams@entry=0x0) at postgres.c:975 #16 0x000000000084ebab in exec_simple_query (query_string=0x12407d0 "SELECT run FROM results_agg ORDER BY 1;") at postgres.c:1169 #17 0x00000000008506df in PostgresMain (dbname=<optimized out>, username=<optimized out>) at postgres.c:4542 #18 0x00000000007c1d12 in BackendRun (port=0x1265e90, port=0x1265e90) at postmaster.c:4491 #19 BackendStartup (port=0x1265e90) at postmaster.c:4219 #20 ServerLoop () at postmaster.c:1793 #21 0x00000000007c2c20 in PostmasterMain (argc=argc@entry=3, argv=argv@entry=0x123a3b0) at postmaster.c:1465 #22 0x0000000000510725 in main (argc=3, argv=0x123a3b0) at main.c:202

view thread (8+ messages)  latest in thread

Message-ID: <29196a1e-ed47-c7ca-9be2-b1c636816183@enterprisedb.com>
Permalink:  ../29196a1e-ed47-c7ca-9be2-b1c636816183@enterprisedb.com/
Also on:    postgresql.org/message-id/29196a1e-ed47-c7ca-9be2-b1c636816183@enterprisedb.com

 · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: tomas.vondra@enterprisedb.com, pgsql-hackers@lists.postgresql.org
  Subject: Re: Assert failure in CTE inlining with view and correlated subquery
  In-Reply-To: <29196a1e-ed47-c7ca-9be2-b1c636816183@enterprisedb.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox