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 1o8MV7-0007mG-4L for pgsql-hackers@arkaria.postgresql.org; Mon, 04 Jul 2022 13:52:33 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1o8MV5-0005RL-FI for pgsql-hackers@arkaria.postgresql.org; Mon, 04 Jul 2022 13:52:31 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1o8MV5-0005RA-4W for pgsql-hackers@lists.postgresql.org; Mon, 04 Jul 2022 13:52:31 +0000 Received: from mail-wr1-x434.google.com ([2a00:1450:4864:20::434]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1o8MV2-000456-F9 for pgsql-hackers@lists.postgresql.org; Mon, 04 Jul 2022 13:52:30 +0000 Received: by mail-wr1-x434.google.com with SMTP id cl1so13617138wrb.4 for ; Mon, 04 Jul 2022 06:52:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aiven.io; s=google; h=from:to:cc:subject:date:message-id:organization:in-reply-to :references:mime-version:content-transfer-encoding; bh=JgmeM2qUMdz/MWqyVvfJDwMBWfiqAD928FkIHm5hcak=; b=nXnXlt1+TXThWtIMSCqE3mhfI/E//EXK4O4aHzUp5v/pj4diE7Il/LhntDuOkhANcB pRvNuKfECR1Zr8z1VwKxYhmMgZ8ovlLevrrTjYQUVq4d5YLb4sk3CS/VhJPnhIz1IlOg 6JOCCV8cQ+9nF9NiQX/amt2S0Tugx+o82PfMQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:organization :in-reply-to:references:mime-version:content-transfer-encoding; bh=JgmeM2qUMdz/MWqyVvfJDwMBWfiqAD928FkIHm5hcak=; b=jejtPHLr5GbgTT7yHvufKbseolvyqtSeV4pGxKK26zRQXryv2zWnndz9Hs/qWX7rvu dj5SW/CVda+5bVU3k/NN9b/zx5kLrUBSqxtzJEfuDQs87XXz9OCUIGAhIhPCZD3ucDmh LoMadHEXT8tIHtd7lFeG0rwcAQfFTtVBYJXba8mUuATqXNnb0hineCmHltInAO1pKCpH 8BG7o/JOuxERyQusZZ/2Jtl4hN3+ltRXvWTYFi/6U7iq+i3QfMMOu+UgI/BuTs2a+5VV rr/7ZDsnf0ihnhN5QM+kib7xLwr0S2UTJlNLW5gKbb7tTOj2RCtbwcsFhecFRnu+N+kZ hn0g== X-Gm-Message-State: AJIora+PgTSPVe24g/bqZBAdXdhOnQ3PNRnhPNkqd+m0QIuWnCe/wcV3 tXDlp3tjqhGonw58HZ07j0AN7w== X-Google-Smtp-Source: AGRyM1snQXMbBZOPvmHftNkkI7vgeVJ7PlsT+6qhAvOBOk8XRWL0scf9qC0eEksmy0zK4DcFXzNq/A== X-Received: by 2002:adf:c64c:0:b0:21a:7a3:54a4 with SMTP id u12-20020adfc64c000000b0021a07a354a4mr27482077wrg.163.1656942746128; Mon, 04 Jul 2022 06:52:26 -0700 (PDT) Received: from aivenronan.localnet ([45.13.105.93]) by smtp.gmail.com with ESMTPSA id ay26-20020a5d6f1a000000b0021baf5e590dsm30312968wrb.71.2022.07.04.06.52.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Jul 2022 06:52:25 -0700 (PDT) From: Ronan Dunklau To: Greg Stark , Andrey Lepikhov Cc: Andres Freund , Laurenz Albe , Hywel Carver , PostgreSQL Hackers Subject: Re: Removing unneeded self joins Date: Mon, 04 Jul 2022 15:49:59 +0200 Message-ID: <2375492.jE0xQCEvom@aivenronan> Organization: aiven In-Reply-To: References: <64486b0b-0404-e39e-322d-0801154901f3@postgrespro.ru> <13021914.uLZWGnKmhe@aivenronan> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="iso-8859-1" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Le jeudi 30 juin 2022, 16:11:51 CEST Andrey Lepikhov a =E9crit : > On 19/5/2022 16:47, Ronan Dunklau wrote: > > I'll take a look at that one. >=20 > New version of the patch, rebased on current master: > 1. pgindent over the patch have passed. > 2. number of changed files is reduced. > 3. Some documentation and comments is added. Hello Andrey, Thanks for the updates.=20 The general approach seems sensible to me, so I'm going to focus on some de= tails.=20 In a very recent thread [1], Tom Lane is proposing to add infrastructure to= make Var aware of their nullability by outer joins. I wonder if that would= help with avoiding the need for adding is not null clauses when the column= is known not null ? If we have a precedent for adding a BitmapSet to the Var itself, maybe the = whole discussion regarding keeping track of nullability can be extended to = the original column nullability ? Also, I saw it was mentioned earlier in the thread but how difficult would = it be to process the transformed quals through the EquivalenceClass machine= ry and the qual simplification ?=20 =46or example, if the target audience of this patch is ORM, or inlined view= s, it wouldn't surprise me to see queries of this kind in the wild, which c= ould be avoided altogether: postgres=3D# explain (costs off) select * from sj s1 join sj s2 on s1.a =3D= s2.a where s1.b =3D 2 and s2.b =3D3; QUERY PLAN =20 =2D---------------------------------------------------- Seq Scan on sj s2 Filter: ((a IS NOT NULL) AND (b =3D 3) AND (b =3D 2)) (2 lignes) + for (counter =3D 0; counter < list_length(*sources);) + { + ListCell *cell =3D list_nth_cell(*sources, counter); + RestrictInfo *rinfo =3D castNode(RestrictInfo, lfirst(cell)= ); + int counter1; + =2E... + ec->ec_members =3D list_delete_cell(ec->ec_members, cell); Why don't you use foreach() and foreach_delete_current macros for iterating= and removing items in the lists, both in update_ec_members and update_ec_s= ources ? + if ((bms_is_member(k, info->syn_lefthand) ^ + bms_is_member(r, info->syn_lefthan= d)) || + (bms_is_member(k, info->syn_rightha= nd) ^ + bms_is_member(r, info->syn_rightha= nd))) I think this is more compact and easier to follow than the previous version= , but I'm not sure how common it is in postgres source code to use that kin= d of construction ? Some review about the comments: I see you keep using the terms "the keeping relation" and "the removing rel= ation" in reference to the relation that is kept and the one that is remove= d. Aside from the grammar (the kept relation or the removed relation), maybe i= t would make it clearer to call them something else. In other parts of the = code, you used "the remaining relation / the removed relation" which makes = sense. /* * Remove the target relid from the planner's data structures, having =2D * determined that there is no need to include it in the query. + * determined that there is no need to include it in the query. Or replace + * with another relid. + * To reusability, this routine can work in two modes: delete relid from a= plan + * or replace it. It is used in replace mode in a self-join removing proce= ss. This could be rephrased: ", optionally replacing it with another relid. The= latter is used by the self-join removing process." [1] https://www.postgresql.org/message-id/flat/830269.1656693747%40sss.pgh.= pa.us =2D-=20 Ronan Dunklau