Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kOPk4-0002PG-Sp for pgsql-hackers@arkaria.postgresql.org; Fri, 02 Oct 2020 18:25:17 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1kOPk3-0006ZF-PJ for pgsql-hackers@arkaria.postgresql.org; Fri, 02 Oct 2020 18:25:15 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kOPk3-0006Z8-HU for pgsql-hackers@lists.postgresql.org; Fri, 02 Oct 2020 18:25:15 +0000 Received: from mail-ej1-x642.google.com ([2a00:1450:4864:20::642]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1kOPk0-000725-UX for pgsql-hackers@postgresql.org; Fri, 02 Oct 2020 18:25:15 +0000 Received: by mail-ej1-x642.google.com with SMTP id p9so3239936ejf.6 for ; Fri, 02 Oct 2020 11:25:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=UiENEwKTQdfdxju3cUhJU/iyx93F+GrHyY3nd7WNZPY=; b=U0u790q744d44bryx5BH4HJMU+iO0P/do6K/lWMOwDSWB5A3CWEdyO0NUNlPLQra8L B0vBF1E79PmQGD8NITDcAty3SbEHdSnJ2BJCeqXGbRaIs+uHVMSQQIVu3l19WdcFqdZM gAMIc8UymuTmr2qbzUaxfqFuvPsjEkYMfVgFo1o/u/NR1L4xBHcwH0Tc6zlzBL7EncZg yu00D00LfbrHarT2tcK1f6ksxpdPe3koW3YX5OqbgOY86n8Il323SX5+ypuqyhpQu0sz eGNC5X4WEifnD7CW0G1Qb2rjllWEzdkEvljd90TAMd2hGpbRR5GAXh/pITLP2tt/3NJe 7Z+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=UiENEwKTQdfdxju3cUhJU/iyx93F+GrHyY3nd7WNZPY=; b=MHnC0Jaa2WUW5foMQiO8KPHs1e45FFCnRNHxcy9Cqs4w98TUhBMKx0Ivfw3KT/b9bd SPSI5Wygda12eJEGkHYO/rlk9Q6LowfU0zeRyPyoe2JSYKxMd3laQ2Os+6a6PO7+6aso OQF3wa6VXFqDjtJJZnFGjE8OkQlXQuB+ocE4qhqerCS2pYQTKhBskh8AQcSXeVqeapmH IrbntMEYjsqfii2Wc5xaD0I4tHlHRL0R9HCEJ2bHc97MT8WvuDU+nPytEHykUEDFJ+tC Xye8LJJdVZJK5XfAxKMEjvVxmTsIf4EUHonQC3vBQ9XjVM5vr/L2Ut05iSABd5Nac36t zozQ== X-Gm-Message-State: AOAM533La/Wudcw1vopzXa5u63DznT9O8tS7aYZASCV/US86bg773jDX MjT1X75bVMImUZXCBIJyyzdpqg== X-Google-Smtp-Source: ABdhPJwbMTWVTodsZ7Tijwn+xoIE8r8b+A1+L0fvqYrQNQTOZyAPsLEHdpgwANeAijtKfdf5p+5hbw== X-Received: by 2002:a17:906:2962:: with SMTP id x2mr3520172ejd.188.1601663112062; Fri, 02 Oct 2020 11:25:12 -0700 (PDT) Received: from localhost (ip-86-49-245-76.net.upcbroadband.cz. [86.49.245.76]) by smtp.gmail.com with ESMTPSA id bk13sm1613175ejb.58.2020.10.02.11.25.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Oct 2020 11:25:11 -0700 (PDT) Date: Fri, 2 Oct 2020 20:25:08 +0200 From: Tomas Vondra To: James Coleman Cc: Jaime Casanova , Pg Hackers Subject: Re: enable_incremental_sort changes query behavior Message-ID: <20201002182508.cbux56rfoak2jzdf@development> References: <20201001220822.rwwxajwzobljgqwz@development> <20201002143207.qt7re34mhsfmfi6f@development> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On Fri, Oct 02, 2020 at 10:55:14AM -0400, James Coleman wrote: >On Fri, Oct 2, 2020 at 10:53 AM James Coleman wrote: >> >> On Fri, Oct 2, 2020 at 10:32 AM Tomas Vondra >> wrote: >> > >> > On Fri, Oct 02, 2020 at 09:19:44AM -0400, James Coleman wrote: >> > > >> > > ... >> > > >> > >I've been able to confirm that the problem goes away if we stop adding >> > >the gather merge paths in generate_useful_gather_paths(). >> > > >> > >I'm not sure yet what conclusion that leads us to. It seems to be that >> > >the biggest clue remains that all of this works correctly unless one >> > >of the selected columns (which happens to be a pathkey at this point >> > >because it's a DISTINCT query) contains a volatile expression. >> > > >> > >> > Yeah. It seems to me this is a bug in get_useful_pathkeys_for_relation, >> > which is calling find_em_expr_for_rel and is happy with anything it >> > returns. But this was copied from postgres_fdw, which however does a bit >> > more here: >> > >> > if (pathkey_ec->ec_has_volatile || >> > !(em_expr = find_em_expr_for_rel(pathkey_ec, rel)) || >> > !is_foreign_expr(root, rel, em_expr)) >> > >> > So not only does it explicitly check volatility of the pathkey, it also >> > calls is_foreign_expr which checks the expression for mutable functions. >> > >> > The attached patch seems to fix this, but it only adds the check for >> > mutable functions. Maybe it should check ec_has_volatile too ... >> >> We actually discussed the volatility check in that function back on >> the original thread [1], and we'd concluded that was specifically >> necessary for the fdw code because the function would execute on two >> different servers (and thus produce different results), but that in a >> local server only scenario it should be fine. >> >> My understanding (correct me if I'm wrong) is that the volatile >> function should only be executed once (at the scan level?) to build >> the tuple and from then on the datum isn't going to change, so I'm not >> sure why the volatility would matter here. >> >> James >> >> 1: https://www.postgresql.org/message-id/20200328025830.6v6ogkseohakc32q%40development > >Oh, hmm, could what I said all be true, but there still be some rule >that you shouldn't compare datums generated from volatile expressions >in different backends (i.e., parallel query)? > I'm not sure it's all that related to parallel query - it's more likely that when constructing the paths below the gather merge, this new code fails to do something important. I'm not 100% sure how the grouping and volatile functions work, so let me think aloud here ... The backtrace looks like this: #0 get_sortgroupref_tle #1 0x0000000000808ab9 in prepare_sort_from_pathkeys #2 0x000000000080926c in make_sort_from_pathkeys #3 0x0000000000801032 in create_sort_plan #4 0x00000000007fe7e0 in create_plan_recurse #5 0x0000000000800b2c in create_gather_merge_plan #6 0x00000000007fe94d in create_plan_recurse #7 0x0000000000805328 in create_nestloop_plan #8 0x00000000007ff3c5 in create_join_plan #9 0x00000000007fe5f8 in create_plan_recurse #10 0x0000000000800d68 in create_projection_plan #11 0x00000000007fe662 in create_plan_recurse #12 0x0000000000801252 in create_upper_unique_plan #13 0x00000000007fe760 in create_plan_recurse #14 0x00000000007fe4f2 in create_plan #15 0x000000000081082f in standard_planner and the create_sort_plan works with lefttree that is IndexScan, so the query we're constructing looks like this: Distinct -> Nestloop -> Gather Merge -> Sort -> Index Scan and it's the sort that expects to find the expression in the Index Scan target list. Which seems rather bogus, because clearly the index scan does not include the expression. (I wonder if it's somehow related that indexes can't be built on volatile expressions ...) Anyway, the index scan clearly does not include the expression the sort references, hence the failure. And the index can can't compute it, because we probably need to compute it on top of the join I think (otherwise we might get duplicate values for volatile functions etc.) Looking at this from a slightly different angle, the root cause here seems to be that generate_useful_gather_paths uses the pathkeys it gets from get_useful_pathkeys_for_relation, which means root->query_pathkeys. But all other create_gather_merge_calls use root->sort_pathkeys, so maybe this is the actual problem and get_useful_pathkeys_for_relation should use root->sort_pathkeys instead. That does fix the issue for me too (and it passes all regression tests). regards -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services