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 1pQ32f-0006TF-HJ for pgsql-hackers@arkaria.postgresql.org; Thu, 09 Feb 2023 09:16: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 1pQ32e-0004Xz-Dh for pgsql-hackers@arkaria.postgresql.org; Thu, 09 Feb 2023 09:16:32 +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 1pQ32e-0004WW-2l for pgsql-hackers@lists.postgresql.org; Thu, 09 Feb 2023 09:16:32 +0000 Received: from mail-yw1-x1133.google.com ([2607:f8b0:4864:20::1133]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1pQ32c-0001UC-NW for pgsql-hackers@postgresql.org; Thu, 09 Feb 2023 09:16:31 +0000 Received: by mail-yw1-x1133.google.com with SMTP id 00721157ae682-520dad0a7d2so17021247b3.5 for ; Thu, 09 Feb 2023 01:16:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=C3/bYkurrDz3w4MQV2NEvw9RPfDEP2IJA6O517mQeFU=; b=EpRT2tremKVaj3tVm7ocgGQkeIJw07boIIvmVtXrR9Jjp9yT2aBVstK7e4t2zu8Na/ 7n2tJQMkgLYyuTQj8w9RemSVhnlWsllCqhMaykuYf3kBsiEFJ5YqUFMYFw398CmLQSXu NkQokWPceOi8lUeD+ZNSq4mcfoLu+TAOCyvgoriRa7dpDWvYf3CNBnNIFo+Tvmm/47pB 4aksgQtc3e2p5J26264sjxhCtsBvjDfapvrAWc2qhPD7OtHDXo0swKfX/x3Iw+18i2X7 e0kfxj15x++Xkgqq6a1V2mt8Eqwv8M9ktLIaVVeO5QBcnlpl1qe234u0Ik7/qCv5q6/I qUWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=C3/bYkurrDz3w4MQV2NEvw9RPfDEP2IJA6O517mQeFU=; b=4DWjWQaJeHug/My9KLlLmYfZBc+f7xC1p5P4hTZ+vPxPTrnRsGDvHFipEM09JUr4aN 5i8o1U4MsrAG1N0t6hpWvdm5gQv1Y45fFrsQZQ9SuvRXMNAzOpBvt3/etKT9Ggmy+k4o 7e8TU34KAEeP+k5IITo2vn5RExz2QX3rI8hemLpKLgXZVpq2idAQFedi3Gjh4Ahgf71k dDn+3JAQWbl+8tKehGKKY+hst2I/qbXFKH0ZAeNtqmmVDsQMNWxKXNSrUopzQFCBs1fd ctA+ZNZjPDw239rmSsPWEPbaaF+4k3oOxrudtbaBjp6X67issdDfdx7Y7j7CEOAq576q yY3w== X-Gm-Message-State: AO0yUKXBaK/wxKczR+MAIVBSQJuhX1JhJaRZ9gQW5QySbEN8MxTLUw5r 8xinwDR26+5YTFHGSF1BgGHTXSzb6rQ5KHTOh89x2JGuTm8= X-Google-Smtp-Source: AK7set+19O8jlZDLJ80jkF/+pnZTCi1fpTgpI+PX4C1MVzqVyI5XUBltb15uvM5/5z2wk+776vPj3T9TJdcbLNeVnvc= X-Received: by 2002:a0d:ea41:0:b0:52b:e35a:6167 with SMTP id t62-20020a0dea41000000b0052be35a6167mr655349ywe.347.1675934188815; Thu, 09 Feb 2023 01:16:28 -0800 (PST) MIME-Version: 1.0 From: Richard Guo Date: Thu, 9 Feb 2023 17:16:15 +0800 Message-ID: Subject: Inconsistent nullingrels due to oversight in deconstruct_distribute_oj_quals To: PostgreSQL-development Content-Type: multipart/alternative; boundary="000000000000fdcb3505f440d570" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000fdcb3505f440d570 Content-Type: text/plain; charset="UTF-8" When we try to generate qual variants with different nullingrels in deconstruct_distribute_oj_quals, we traverse all the JoinTreeItems and adjust qual nulling bits as we crawl up the join tree. For a SpecialJoinInfo which commutes with current sjinfo from below left, in the next level up it would null all the relids in its righthand. So we adjust qual nulling bits as below. /* * Adjust qual nulling bits for next level up, if needed. We * don't want to put sjinfo's own bit in at all, and if we're * above sjinfo then we did it already. */ if (below_sjinfo) quals = (List *) add_nulling_relids((Node *) quals, othersj->min_righthand, bms_make_singleton(othersj->ojrelid)); It seems to me there is oversight here. Actually in next level up this othersj would null all the relids in its syn_righthand, not only the relids in its min_righthand. If the quals happen to contain references to relids which are in othersj->syn_righthand but not in othersj->min_righthand, these relids would not get updated with othersj->ojrelid added. And this would cause qual nulling bits not consistent. I've managed to devise a query that can show this problem. create table t1(a int, b int); create table t2(a int, b int); create table t3(a int, b int); create table t4(a int, b int); insert into t1 select i, i from generate_series(1,10)i; insert into t2 select i, i from generate_series(1,10)i; insert into t3 select i, i from generate_series(1,1000)i; insert into t4 select i, i from generate_series(1,1000)i; analyze; select * from t1 left join (t2 left join t3 on t2.a > t3.a) on t1.b = t2.b left join t4 on t2.b = t3.b; This query would trigger the Assert() in search_indexed_tlist_for_var. So I wonder that we should use othersj->syn_righthand here. --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -2046,7 +2046,7 @@ deconstruct_distribute_oj_quals(PlannerInfo *root, if (below_sjinfo) quals = (List *) add_nulling_relids((Node *) quals, - othersj->min_righthand, + othersj->syn_righthand, bms_make_singleton(othersj->ojrelid)); Thanks Richard --000000000000fdcb3505f440d570 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
When we try to generate qual variants with different nulli= ngrels in
deconstruct_distribute_oj_quals, we traverse all the JoinTreeI= tems and
adjust qual nulling bits as we crawl up the join tree.=C2=A0 Fo= r a
SpecialJoinInfo which commutes with current sjinfo from below left, = in
the next level up it would null all the relids in its righthand.=C2= =A0 So we
adjust qual nulling bits as below.

=C2=A0 =C2=A0 =C2=A0= /*
=C2=A0 =C2=A0 =C2=A0 * Adjust qual nulling bits for next level up, if= needed.=C2=A0 We
=C2=A0 =C2=A0 =C2=A0 * don't want to put sjinfo= 9;s own bit in at all, and if we're
=C2=A0 =C2=A0 =C2=A0 * above sji= nfo then we did it already.
=C2=A0 =C2=A0 =C2=A0 */
=C2=A0 =C2=A0 =C2= =A0if (below_sjinfo)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0quals =3D (List *= )
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0add_nulling_relids((No= de *) quals,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 othersj->min_righth= and,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 bms_make_singleton(othersj-&g= t;ojrelid));

It seems to me there is oversight here.=C2=A0 Actually = in next level up this
othersj would null all the relids in its syn_right= hand, not only the
relids in its min_righthand. =C2=A0 If the quals happ= en to contain references
to relids which are in othersj->syn_righthan= d but not in
othersj->min_righthand, these relids would not get updat= ed with
othersj->ojrelid added.=C2=A0 And this would cause qual nulli= ng bits not
consistent.

I've managed to devise a query that c= an show this problem.

create table t1(a int, b int);
create table= t2(a int, b int);
create table t3(a int, b int);
create table t4(a i= nt, b int);

insert into t1 select i, i from generate_series(1,10)i;<= br>insert into t2 select i, i from generate_series(1,10)i;
insert into t= 3 select i, i from generate_series(1,1000)i;
insert into t4 select i, i = from generate_series(1,1000)i;
analyze;

select * from t1 left joi= n (t2 left join t3 on t2.a > t3.a) on t1.b =3D t2.b left join t4 on t2.b= =3D t3.b;

This query would trigger the Assert() in search_indexed_t= list_for_var.
So I wonder that we should use othersj->syn_righth= and here.

--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/= backend/optimizer/plan/initsplan.c
@@ -2046,7 +2046,7 @@ deconstruct_dis= tribute_oj_quals(PlannerInfo *root,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (belo= w_sjinfo)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 quals =3D (List *)=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 add_nulling_relid= s((Node *) quals,
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0othersj-&= gt;min_righthand,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0othersj-&= gt;syn_righthand,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0bm= s_make_singleton(othersj->ojrelid));

Thanks
Richard
<= /div> --000000000000fdcb3505f440d570--