Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vWEBn-00FYme-24 for pgsql-hackers@arkaria.postgresql.org; Thu, 18 Dec 2025 13:37:08 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vWEBm-002MYD-1W for pgsql-hackers@arkaria.postgresql.org; Thu, 18 Dec 2025 13:37:07 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vWEBm-002MY5-08 for pgsql-hackers@lists.postgresql.org; Thu, 18 Dec 2025 13:37:06 +0000 Received: from mail-ej1-x62a.google.com ([2a00:1450:4864:20::62a]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vWEBf-001Kwl-38 for pgsql-hackers@lists.postgresql.org; Thu, 18 Dec 2025 13:37:00 +0000 Received: by mail-ej1-x62a.google.com with SMTP id a640c23a62f3a-b73161849e1so151778666b.2 for ; Thu, 18 Dec 2025 05:36:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1766065018; x=1766669818; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=s/Kr5eBRbpGlm+iU6LNcfRB3XaT6ZPpSW5VfYg8ZZXU=; b=kZe5Pfy8wPZD9XjW9pEcKuPozFlDamfcO8MyG4JjGim9NIeswjcSEushJqKRtTJn+Z V/d4MFY8UPSyFqbkGNeH6BbWnT+4KeZvqJPKMQEppBiqLd/n1S4WsGIwljlQ2jqe2SP0 BOmKVfu+af6fRY79lvlB3SrwnsKlTHdgCu+d1Kvk3h/kY8LcElMVeYiWt8W0MfKbObyL 7bjdbRdTJgjzX/0IiJctXzuHDjZ2owewOY1e8wehre8e0EgQxtMHuM7yoXHEVbmX80eM BK+C93R0VRvc709RVQY1uI+kRqg3yymkcUt2pBOBRHTXn4RL67j3Q+PI+Ux66DGbR2wX 1WSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766065018; x=1766669818; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=s/Kr5eBRbpGlm+iU6LNcfRB3XaT6ZPpSW5VfYg8ZZXU=; b=v17BpreD0cNhpmn+M/rA0x2dydIbtAe+cHEOQcaUGpF+r/FDNv6ih/obXMY4cV2yAh 3wEntYESk+oR63fkBDJWuZlYVLZD2dhHU2HTZMtfDZx5vYTc/JpTai78CxSSvpiecBcR Q0ozPC0F8W7kaISK36xHE4pToVDbDRCU/nuc7ymOe3vnhGFW90le5uRjvzmPWMU3yPhM olrghPxiWXu7LzLDRK6kn+vJp38goNc905qKFAe+9TlXbB1V8srtfoUBC1nVU/H/Bs6f IqSekE5oRwg8Lb66CA+2j9YoAAb/ON21tgBZirhjrcxNeZ71qDmNMYfY0zfwuGCngFL4 /M7g== X-Forwarded-Encrypted: i=1; AJvYcCU5zWEcGc2ObHI3rsea6FOVtK6JxtHN0ec13sVGYtA3D3ddfmrM63JKcfbvE7xrq1/KIcXbzI4e7O9aKbYo@lists.postgresql.org X-Gm-Message-State: AOJu0Yyww4OnDLOvQie3ELqRJMf2q2B/wso4A7NOKIUMLTyPFEK6lH3n Vvp7iWYP/lOpnH8CrSoHZmQ6tkiwPuhd3/JZFYvF7vLcSseO7ykfcAPmj87hHYPuKJWlCIGpHEv 2F8vRk4sBuB5QUv6TQPIo8FeC/fcyKM0= X-Gm-Gg: AY/fxX7lWCEx0VKr+p/nwRlhzzvaOfXQKH7qGtMKKOu5cw4x+xigdvTh1yB2cHxil6u lgOULUqpwsvqu389oCCJQ4EMWPmIAJ54sc0BBgU48+NyTRIcCo4zYX7oqb3sVniqZ0Uak3hfON5 TOUzhIaedsKGT2K42mj8bAMCnDc+w3i1U2LC2S/uB4Exn+JwJKxLNzMscD40COtMrq662pVUa7q 5sCBQ928R4hnQ7LZNkG93kRw0omFm07z2c3sokQWSJ0q2tMeZT/qpD9nGRZ2m1iA8/g8WeGXvxv kWJgx9kbKe76nAvS8Z0aXBxQQTOdYg== X-Google-Smtp-Source: AGHT+IG9OHhNLiHpuMjvZDMOovQPbBoylw6cyH2oJUGs8arzwmGkX6VZefRSTG6tKsMvmi/lvn/t/WhFo7OX7AV/EgA= X-Received: by 2002:a17:907:3da0:b0:b73:57eb:688 with SMTP id a640c23a62f3a-b7d23a62e9cmr2207970066b.53.1766065017567; Thu, 18 Dec 2025 05:36:57 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Robert Haas Date: Thu, 18 Dec 2025 08:36:44 -0500 X-Gm-Features: AQt7F2rR5QB1Q9BG6jRsfdMU8BobE7zYAArmntY2z3MOQSg94UWZ0-5hYv_yscM Message-ID: Subject: Re: pg_plan_advice To: Jakub Wartak Cc: Jacob Champion , Dian Fay , Matheus Alcantara , PostgreSQL Hackers Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Wed, Dec 17, 2025 at 5:12=E2=80=AFAM Jakub Wartak wrote: > Sort (cost=3D1010985030.44..1010985030.59 rows=3D61 width=3D51) > Sort Key: supplier.s_name > -> Nested Loop (cost=3D0.42..1010985028.63 rows=3D61 width=3D51) > Join Filter: (nation.n_nationkey =3D supplier.s_nationkey) > -> Seq Scan on nation (cost=3D0.00..1.31 rows=3D1 width=3D4) > Filter: (n_name =3D 'CANADA'::bpchar) > -> Nested Loop Semi Join (cost=3D0.42..1010985008.29 > rows=3D1522 width=3D55) > Join Filter: (partsupp.ps_suppkey =3D supplier.s_suppkey) > -> Seq Scan on supplier (cost=3D0.00..249.30 rows=3D7730= width=3D59) > -> Materialize (cost=3D0.42..1010755994.57 rows=3D1973 w= idth=3D4) > -> Nested Loop (cost=3D0.42..1010755984.71 > rows=3D1973 width=3D4) > -> Seq Scan on part (cost=3D0.00..4842.25 > rows=3D1469 width=3D4) > Filter: ((p_name)::text ~~ 'forest%'::te= xt) > -> Index Scan using pk_partsupp on > partsupp (cost=3D0.42..688053.87 rows=3D1 width=3D8) > Index Cond: (ps_partkey =3D part.p_partk= ey) > Filter: ((ps_availqty)::numeric > > (SubPlan expr_1)) > SubPlan expr_1 > -> Aggregate > (cost=3D172009.42..172009.44 rows=3D1 width=3D32) > -> Seq Scan on lineitem > (cost=3D0.00..172009.42 rows=3D1 width=3D5) > Filter: ((l_shipdate >=3D > '1994-01-01'::date) AND (l_shipdate < '1995-01-01 00:00:00'::timestamp > without time zone) AND (l_partkey =3D partsupp.ps_partkey) AND > (l_suppkey =3D partsupp.ps_suppkey)) > > > Generated Plan Advice: > JOIN_ORDER(nation (supplier (part partsupp))) > NESTED_LOOP_PLAIN(partsupp partsupp) <--- [X] > NESTED_LOOP_MATERIALIZE(partsupp) > SEQ_SCAN(nation supplier part lineitem@expr_1) > INDEX_SCAN(partsupp public.pk_partsupp) > SEMIJOIN_NON_UNIQUE((partsupp part)) > NO_GATHER(supplier nation partsupp part lineitem@expr_1) Yeah, that's not right. There are three nested loops here, so we should have three pieces of nested loop advice. NESTED_LOOP_MATERIALIZE(partsupp) covers the innermost nested loop. The other two are NESTED_LOOP_PLAIN, but the advice should cover all the tables on the inner side of the join. I think it should read: NESTED_LOOP_PLAIN((part partsupp) (supplier part partsupp)) Ordering isn't significant here, so NESTED_LOOP_PLAIN((part supplier partsupp) (partsupp part)) would be logically equivalent. Doesn't matter exactly what we output here, but it shouldn't be just partsupp. > and apparently proper advice like below which has better yield: > set pg_plan_advice.advice =3D '[..] NESTED_LOOP_PLAIN(part partsupp) This isn't quite what you want, because this says that part should be on the outer side of a NESTED_LOOP_PLAIN by itself and partsupp should also be on the outer side of a NESTED_LOOP_PLAIN by itself. You need the extra set of parentheses to indicate that the join product of those two tables should be on the outer side of a NESTED_LOOP_PLAIN, rather than each table individually. What must be happening here is that either pgpa_join.c (maybe with complicity from pgpa_walker.c) is not populating the pgpa_plan_walker_context's join_strategies[JSTRAT_NESTED_LOOP_PLAIN] member correctly, or else pgpa_output.c is not serializing it to text correctly. I suspect the former is a more likely but I'm not sure exactly what's happening. --=20 Robert Haas EDB: http://www.enterprisedb.com