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.94.2) (envelope-from ) id 1vEluo-0007QI-FU for pgsql-hackers@arkaria.postgresql.org; Fri, 31 Oct 2025 09:59:26 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1vElun-00Dlx4-Ap for pgsql-hackers@arkaria.postgresql.org; Fri, 31 Oct 2025 09:59:24 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1vElum-00Dlwu-UU for pgsql-hackers@lists.postgresql.org; Fri, 31 Oct 2025 09:59:24 +0000 Received: from mail-lf1-x135.google.com ([2a00:1450:4864:20::135]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vElug-005EBX-22 for pgsql-hackers@lists.postgresql.org; Fri, 31 Oct 2025 09:59:22 +0000 Received: by mail-lf1-x135.google.com with SMTP id 2adb3069b0e04-592fdbeb7b2so2730134e87.0 for ; Fri, 31 Oct 2025 02:59:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; t=1761904752; x=1762509552; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=Dfy0OI8B8sXvmvK3q6XhHOlGEjKYcO3vC11khx8mYlg=; b=Q+W2HltbftaMe34RrWwVkZjZ4ZkHRKQw2ebHkrRV0XINBcjjZDbf4ZafxhRYE3tdNe vJjwWfjyytx3wwET8bDKeo6VyDrh/q/alCp0G6cGx8J/0gNTXOUoRn15WrBegOMGvSk2 7W4Xx9+Tmv+uVePSoNNluKSb9x5FKMDQiZAfIQzdOS1s9hINLQJa9EpNCHBGoLSGAkqQ k5fmPR10OLvC6D1W6Zvl/MNS49yjFaQeCx6moXU2drebtQHkeE1e2jsr9HsT2K4lc6b7 o0XhmsM4NQxQUqAViJZme1FZNsaeSByloPXsvVwdnaZOKDxGFyqcMNEDKPLE06RtOYK/ EyLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761904752; x=1762509552; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Dfy0OI8B8sXvmvK3q6XhHOlGEjKYcO3vC11khx8mYlg=; b=KxHMOkKkaT9Yhn56Arfphk4oHGokY06EIXNTbvAXM+4KHNYn6WMQFQ8vrno22+J+u5 90lGDTW4B2TtW2+nTrV2t4cfNAEJ7YKVYCQ5XDneIbovm7Qe7iY29j5lAbxu1eGY8aod riObka0Ih2QqyhPGMMF29hwFUF3shArn5+f8lhBGTzqfFDMOV6DZd6RErKz64vFaaXmK gu4rVIbB2PwioX1zQ0ObX6ovJKv1c96oVeAYZysRCWQnKCfprTas9+RFA7u+GV0Qh58J zn73OwRrz6II11luAtg7kpy3yYOgVajbapLADfCJ3hD8W9yZmOtf619BhEj2ltFhQdEU MnFw== X-Gm-Message-State: AOJu0Yw859SYsa53lP3pXDjaQJuukCmnnwzj7GF2Uyfs4YeQCX4XriVd w4zovQRcWtwzbjZWsKRL2EeaXDZZzbCh9IEx2q/kDO9VCxjCwRsahwSy3JQ8JVontgFIeBBeatp ns0Q+mq1VPDDcTl7u5gUmgfNyK0B3ojdNe0KX+cD2p6rfBqtN25E= X-Gm-Gg: ASbGncu3g0H0v/wYkSaXkqIxnjpif8kSOEk3OzjqjWqGP65WCL4wsfudqZm0rwrw4FK LdwYbg1pZNVglH8cHvUtsysoSdJJft1KCrjlnTUsLKpRw2VqdOqlykZbdZEgDknDu19jtYffdMy lum8rb/TculsuPlG8vL5W2g1iv+Lu96xU7jUQ2KLAdKbYz9jSMsotJBbNs3FA4B6n52WV/93p4m dimQnu/eh1wMOdTkHzX9b0cK/CuwHm8zDMjon3rzRVuTYYz8AhekZRMb8/zLFf9mmmaSg== X-Google-Smtp-Source: AGHT+IHqOUZY0CNvGUHfRgr6ZGRoIZ945wdefe32Ok3P17YEG/n1SWWu4VahlpBtEXZf7rloQ2Pbyg0cDGQnI4/4eoU= X-Received: by 2002:a05:6512:15a0:b0:592:f3ef:19ad with SMTP id 2adb3069b0e04-5941d53eeabmr1025412e87.34.1761904751613; Fri, 31 Oct 2025 02:59:11 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Jakub Wartak Date: Fri, 31 Oct 2025 10:58:59 +0100 X-Gm-Features: AWmQ_bmBDgJK3gGdCgeuDMcZwpVbRu7NDRhRWAiYUa_tL7zSE62F6uLwVqP_h4I Message-ID: Subject: Re: pg_plan_advice To: Robert Haas Cc: PostgreSQL Hackers Content-Type: multipart/mixed; boundary="000000000000d94c8e0642716ada" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000d94c8e0642716ada Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Thu, Oct 30, 2025 at 3:00=E2=80=AFPM Robert Haas = wrote: [..over 400kB of attachments, yay] Thank You for working on this! My gcc-13 was nitpicking a little bit (see compilation_warnings_v1.txt), so attached is just a tiny diff to fix some of those issues. After that, clang-20 run was clean too. > First, any form of user control over the planner tends to be a lightning = rod for criticism around here. I do not know where this is coming from, but everybody I've talked to was saying this is needed to handle real enterprise databases and applications. I just really love it, how one could precisely adjust the plan with this even with the presence of heavy aliasing: postgres=3D# explain (plan_advice, costs off) SELECT * FROM (select * from t1 a join t2 b using (id)) a, t2 b, t3 c WHERE a.id =3D b.id and b.id =3D c.id; QUERY PLAN ----------------------------------------------------- Merge Join Merge Cond: (a.id =3D c.id) -> Merge Join Merge Cond: (a.id =3D b.id) -> Index Scan using t1_pkey on t1 a -> Index Scan using t2_pkey on t2 b -> Sort Sort Key: c.id -> Seq Scan on t3 c Supplied Plan Advice: SEQ_SCAN(ble5) /* not matched */ Generated Plan Advice: JOIN_ORDER(a#2 b#2 c) MERGE_JOIN_PLAIN(b#2 c) SEQ_SCAN(c) INDEX_SCAN(a#2 public.t1_pkey ) NO_GATHER(c a#2 b#2) (17 rows) postgres=3D# set pg_plan_advice.advice =3D 'SEQ_SCAN(b#2)'; SET postgres=3D# explain (plan_advice, costs off) SELECT * FROM (select * from t1 a join t2 b using (id)) a, t2 b, t3 c WHERE a.id =3D b.id and b.id =3D c.id; QUERY PLAN ---------------------------------------------------- Hash Join Hash Cond: (b.id =3D a.id) -> Seq Scan on t2 b -> Hash -> Merge Join Merge Cond: (a.id =3D c.id) -> Index Scan using t1_pkey on t1 a -> Sort Sort Key: c.id -> Seq Scan on t3 c Supplied Plan Advice: SEQ_SCAN(b#2) /* matched */ Generated Plan Advice: JOIN_ORDER(b#2 (a#2 c)) MERGE_JOIN_PLAIN(c) HASH_JOIN(c) SEQ_SCAN(b#2 c) INDEX_SCAN(a#2 public.t1_pkey) NO_GATHER(c a#2 b#2) To attract a little attention to the $thread, the only bigger design (usability) question that keeps ringing in my head is how we are going to bind it to specific queries without even issuing any SETs(or ALTER USER) in the far future in the grand scheme of things. The discussed query id (hash), full query text comparison, maybe even strstr(query , "partial hit") or regex all seem to be kind too limited in terms of what crazy ORMs can come up with (each query will be potentially slightly different, but if optimizer reference points are stable that should nail it good enough, but just enabling it for the very specific set of queries and not the others [with same aliases] is some major challenge). Due to this, at some point I was even thinking about some hashes for every plan node (including hashes of subplans), e.g.: Merge Join // hash(MERGE_JOIN_PLAIN(b#2) + ';' somehashval1 + ';'+ somehahsval2 ) =3D> somehashval3 Merge Cond: (a.id =3D c.id) -> Merge Join Merge Cond: (a.id =3D b.id) -> Index Scan using t1_pkey on t1 a // hash(INDEX_SCAN(a#2 public.t1_pkey)) =3D> somehashval1 -> Index Scan using t2_pkey on t2 b // hash(INDEX_SCAN(b#2 public.t2_pkey)) =3D> somehashval2 and then having a way to use `somehashval3` (let's say it's SHA1) as a way to activate the necessary advice. Something like having a way to express it using plan_advice.on_subplanhashes_plan_advice =3D 'somehashval3: SEQ_SCAN(b#2)'. This would have the benefit of being able to override multiple similiar SQL queries in one go rather than collecting all possible query_ids, but probably it's stupid, heavyweight, but that would be my dream ;) -J. --000000000000d94c8e0642716ada Content-Type: text/plain; charset="US-ASCII"; name="0001-fixup-supress-some-gcc-warnings.txt" Content-Disposition: attachment; filename="0001-fixup-supress-some-gcc-warnings.txt" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mheoir2s0 RnJvbSAwNjAzOGUyMzc0MjBiNzA1NDkxMjExODA3NmU4Yjk4MWRlZjRmNTQ1IE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBKYWt1YiBXYXJ0YWsgPGpha3ViLndhcnRha0BlbnRlcnByaXNl ZGIuY29tPgpEYXRlOiBGcmksIDMxIE9jdCAyMDI1IDA5OjM1OjU5ICswMTAwClN1YmplY3Q6IFtQ QVRDSF0gZml4dXA6IHN1cHJlc3Mgc29tZSBnY2Mgd2FybmluZ3MKCi0tLQogY29udHJpYi9wZ19w bGFuX2FkdmljZS9wZ3BhX2FzdC5jICAgIHwgIDMgKystCiBjb250cmliL3BnX3BsYW5fYWR2aWNl L3BncGFfb3V0cHV0LmMgfCAxMiArKysrKysrKy0tLS0KIGNvbnRyaWIvcGdfcGxhbl9hZHZpY2Uv cGdwYV93YWxrZXIuYyB8ICA0ICsrKy0KIDMgZmlsZXMgY2hhbmdlZCwgMTMgaW5zZXJ0aW9ucygr KSwgNiBkZWxldGlvbnMoLSkKCmRpZmYgLS1naXQgYS9jb250cmliL3BnX3BsYW5fYWR2aWNlL3Bn cGFfYXN0LmMgYi9jb250cmliL3BnX3BsYW5fYWR2aWNlL3BncGFfYXN0LmMKaW5kZXggZWQxODk1 MGFmMTguLmJlNTk4ODc0YzQ4IDEwMDY0NAotLS0gYS9jb250cmliL3BnX3BsYW5fYWR2aWNlL3Bn cGFfYXN0LmMKKysrIGIvY29udHJpYi9wZ19wbGFuX2FkdmljZS9wZ3BhX2FzdC5jCkBAIC0xMzgs NyArMTM4LDggQEAgcGdwYV9jc3RyaW5nX2FkdmljZV90YWcocGdwYV9hZHZpY2VfdGFnX3R5cGUg YWR2aWNlX3RhZykKIAkJCXJldHVybiAiVElEX1NDQU4iOwogCX0KIAotCUFzc2VydChmYWxzZSk7 CisJZWxvZyhFUlJPUiwgInVucmVjb2duaXplZCBhZHZpY2UgdHlwZTogJWQiLCBhZHZpY2VfdGFn KTsKKwlwZ191bnJlYWNoYWJsZSgpOwogfQogCiAvKgpkaWZmIC0tZ2l0IGEvY29udHJpYi9wZ19w bGFuX2FkdmljZS9wZ3BhX291dHB1dC5jIGIvY29udHJpYi9wZ19wbGFuX2FkdmljZS9wZ3BhX291 dHB1dC5jCmluZGV4IDIxNzUyNzhiNTgwLi41YWFlNTA3MTk5MCAxMDA2NDQKLS0tIGEvY29udHJp Yi9wZ19wbGFuX2FkdmljZS9wZ3BhX291dHB1dC5jCisrKyBiL2NvbnRyaWIvcGdfcGxhbl9hZHZp Y2UvcGdwYV9vdXRwdXQuYwpAQCAtMTAsNiArMTAsNyBAQAogICotLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAg Ki8KIAorI2luY2x1ZGUgImMuaCIKICNpbmNsdWRlICJwb3N0Z3Jlcy5oIgogCiAjaW5jbHVkZSAi cGdwYV9vdXRwdXQuaCIKQEAgLTUwNyw3ICs1MDgsOCBAQCBwZ3BhX2NzdHJpbmdfam9pbl9zdHJh dGVneShwZ3BhX2pvaW5fc3RyYXRlZ3kgc3RyYXRlZ3kpCiAJCQlyZXR1cm4gIkhBU0hfSk9JTiI7 CiAJfQogCi0JQXNzZXJ0KGZhbHNlKTsKKwllbG9nKEVSUk9SLCAidW5yZWNvZ25pemVkIGpvaW4g c3RyYXRlZ3k6ICVkIiwgc3RyYXRlZ3kpOworCXBnX3VucmVhY2hhYmxlKCk7CiB9CiAKIC8qCkBA IC01MzYsMTEgKzUzOCwxMiBAQCBwZ3BhX2NzdHJpbmdfc2Nhbl9zdHJhdGVneShwZ3BhX3NjYW5f c3RyYXRlZ3kgc3RyYXRlZ3kpCiAJCQlyZXR1cm4gIlRJRF9TQ0FOIjsKIAl9CiAKLQlBc3NlcnQo ZmFsc2UpOworCWVsb2coRVJST1IsICJ1bnJlY29nbml6ZWQgc2NhbiBzdHJhdGVneTogJWQiLCBz dHJhdGVneSk7CisJcGdfdW5yZWFjaGFibGUoKTsKIH0KIAogLyoKLSAqIEdldCBhIEMgc3RyaW5n IHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIHNwZWNpZmllZCBzY2FuIHN0cmF0ZWd5LgorICogR2V0 IGEgQyBzdHJpbmcgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgc3BlY2lmaWVkIHF1ZXJ5IGZlYXR1 cmUgdHlwZS4KICAqLwogc3RhdGljIGNoYXIgKgogcGdwYV9jc3RyaW5nX3F1ZXJ5X2ZlYXR1cmVf dHlwZShwZ3BhX3FmX3R5cGUgdHlwZSkKQEAgLTU1Nyw3ICs1NjAsOCBAQCBwZ3BhX2NzdHJpbmdf cXVlcnlfZmVhdHVyZV90eXBlKHBncGFfcWZfdHlwZSB0eXBlKQogCQkJcmV0dXJuICJTRU1JSk9J Tl9VTklRVUUiOwogCX0KIAotCUFzc2VydChmYWxzZSk7CisJZWxvZyhFUlJPUiwgInVucmVjb2du aXplZCBxdWVyeSBmZWF0dXJlIHR5cGU6ICVkIiwgdHlwZSk7CisJcGdfdW5yZWFjaGFibGUoKTsK IH0KIAogLyoKZGlmZiAtLWdpdCBhL2NvbnRyaWIvcGdfcGxhbl9hZHZpY2UvcGdwYV93YWxrZXIu YyBiL2NvbnRyaWIvcGdfcGxhbl9hZHZpY2UvcGdwYV93YWxrZXIuYwppbmRleCBkMjJhYzExYmY5 MS4uNDRhZGViNDUxMWIgMTAwNjQ0Ci0tLSBhL2NvbnRyaWIvcGdfcGxhbl9hZHZpY2UvcGdwYV93 YWxrZXIuYworKysgYi9jb250cmliL3BnX3BsYW5fYWR2aWNlL3BncGFfd2Fsa2VyLmMKQEAgLTM1 OSw3ICszNTksNyBAQCBwZ3BhX3dhbGtfcmVjdXJzaXZlbHkocGdwYV9wbGFuX3dhbGtlcl9jb250 ZXh0ICp3YWxrZXIsIFBsYW4gKnBsYW4sCiAJewogCQlpbnQJCQludW1fYXFmID0gbGlzdF9sZW5n dGgoYWN0aXZlX3F1ZXJ5X2ZlYXR1cmVzKTsKIAotCQkodm9pZCkgbGlzdF90cnVuY2F0ZShhY3Rp dmVfcXVlcnlfZmVhdHVyZXMsIG51bV9hcWYgLSAxKTsKKwkJYWN0aXZlX3F1ZXJ5X2ZlYXR1cmVz ID0gbGlzdF90cnVuY2F0ZShhY3RpdmVfcXVlcnlfZmVhdHVyZXMsIG51bV9hcWYgLSAxKTsKIAl9 CiB9CiAKQEAgLTc2OCw2ICs3NjgsNyBAQCBwZ3BhX3dhbGtlcl9qb2luX29yZGVyX21hdGNoZXNf bWVtYmVyKHBncGFfam9pbl9tZW1iZXIgKm1lbWJlciwKIAkJCQkJcmVsaWRzID0gYm1zX2FkZF9t ZW1iZXIocmVsaWRzLCBydGkpOwogCQkJCX0KIAkJCX0KKwkJCWJyZWFrOwogCiAJCWNhc2UgUEdQ QV9UQVJHRVRfSURFTlRJRklFUjoKIAkJCXsKQEAgLTc3Nyw2ICs3NzgsNyBAQCBwZ3BhX3dhbGtl cl9qb2luX29yZGVyX21hdGNoZXNfbWVtYmVyKHBncGFfam9pbl9tZW1iZXIgKm1lbWJlciwKIAkJ CQkJCQkJCQkgICZ0YXJnZXQtPnJpZCk7CiAJCQkJcmVsaWRzID0gYm1zX21ha2Vfc2luZ2xldG9u KHJ0aSk7CiAJCQl9CisJCQlicmVhazsKIAl9CiAKIAlyZXR1cm4gYm1zX2VxdWFsKG1lbWJlci0+ c2Nhbi0+cmVsaWRzLCByZWxpZHMpOwotLSAKMi40My4wCgo= --000000000000d94c8e0642716ada Content-Type: text/plain; charset="US-ASCII"; name="0001-fixup-not-sure.txt" Content-Disposition: attachment; filename="0001-fixup-not-sure.txt" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mheoitu41 RnJvbSA0ZmRiNWQ2YjA0N2ZjN2ZkMTg4YmUyM2M2NGFlN2YzNTJiMDE0ZjIxIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBKYWt1YiBXYXJ0YWsgPGpha3ViLndhcnRha0BlbnRlcnByaXNl ZGIuY29tPgpEYXRlOiBGcmksIDMxIE9jdCAyMDI1IDA5OjM0OjU4ICswMTAwClN1YmplY3Q6IFtQ QVRDSCAxLzJdIGZpeHVwOiBub3Qgc3VyZQoKLS0tCiBjb250cmliL3BnX3BsYW5fYWR2aWNlL3Bn cGFfcGxhbm5lci5jIHwgMiArLQogMSBmaWxlIGNoYW5nZWQsIDEgaW5zZXJ0aW9uKCspLCAxIGRl bGV0aW9uKC0pCgpkaWZmIC0tZ2l0IGEvY29udHJpYi9wZ19wbGFuX2FkdmljZS9wZ3BhX3BsYW5u ZXIuYyBiL2NvbnRyaWIvcGdfcGxhbl9hZHZpY2UvcGdwYV9wbGFubmVyLmMKaW5kZXggYzQ4NTlj MjMwMjAuLjViN2QyY2JkOWY0IDEwMDY0NAotLS0gYS9jb250cmliL3BnX3BsYW5fYWR2aWNlL3Bn cGFfcGxhbm5lci5jCisrKyBiL2NvbnRyaWIvcGdfcGxhbl9hZHZpY2UvcGdwYV9wbGFubmVyLmMK QEAgLTE0MTEsNyArMTQxMSw3IEBAIHBncGFfcGxhbm5lcl9hcHBseV9zY2FuX2FkdmljZShSZWxP cHRJbmZvICpyZWwsCiAJCSAqIE5vdGUgdGhhdCBzZXR0aW5nIFBHU19DT05TSURFUl9OT05QQVJU SUFMIGluIG15X2dhdGhlcl9tYXNrIGlzCiAJCSAqIGVxdWl2YWxlbnQgdG8gYWxsb3dpbmcgdGhl IG5vbi11c2Ugb2YgZWl0aGVyIGZvcm0gb2YgR2F0aGVyIGhlcmUuCiAJCSAqLwotCQlpZiAobXlf ZW50cnktPnRhZyA9PSBQR1BBX1RBR19HQVRIRVIgfAorCQlpZiAobXlfZW50cnktPnRhZyA9PSBQ R1BBX1RBR19HQVRIRVIgfHwKIAkJCW15X2VudHJ5LT50YWcgPT0gUEdQQV9UQUdfR0FUSEVSX01F UkdFKQogCQl7CiAJCQlpZiAoIWp1c3Rfb25lX3JlbCkKLS0gCjIuNDMuMAoK --000000000000d94c8e0642716ada Content-Type: text/plain; charset="UTF-8"; name="compile_errors_v1.txt" Content-Disposition: attachment; filename="compile_errors_v1.txt" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mheoizxn2 Li4vY29udHJpYi9wZ19wbGFuX2FkdmljZS9wZ3BhX2FzdC5jOiBJbiBmdW5jdGlvbiDigJhwZ3Bh X2NzdHJpbmdfYWR2aWNlX3RhZ+KAmToKLi4vY29udHJpYi9wZ19wbGFuX2FkdmljZS9wZ3BhX2Fz dC5jOjE0MjoxOiB3YXJuaW5nOiBjb250cm9sIHJlYWNoZXMgZW5kIG9mIG5vbi12b2lkIGZ1bmN0 aW9uIFstV3JldHVybi10eXBlXQogIDE0MiB8IH0KICAgICAgfCBeCi4uL2NvbnRyaWIvcGdfcGxh bl9hZHZpY2UvcGdwYV9vdXRwdXQuYzogSW4gZnVuY3Rpb24g4oCYcGdwYV9jc3RyaW5nX2pvaW5f c3RyYXRlZ3nigJk6Ci4uL2NvbnRyaWIvcGdfcGxhbl9hZHZpY2UvcGdwYV9vdXRwdXQuYzo1MTE6 MTogd2FybmluZzogY29udHJvbCByZWFjaGVzIGVuZCBvZiBub24tdm9pZCBmdW5jdGlvbiBbLVdy ZXR1cm4tdHlwZV0KICA1MTEgfCB9CiAgICAgIHwgXgouLi9jb250cmliL3BnX3BsYW5fYWR2aWNl L3BncGFfb3V0cHV0LmM6IEluIGZ1bmN0aW9uIOKAmHBncGFfY3N0cmluZ19zY2FuX3N0cmF0ZWd5 4oCZOgouLi9jb250cmliL3BnX3BsYW5fYWR2aWNlL3BncGFfb3V0cHV0LmM6NTQwOjE6IHdhcm5p bmc6IGNvbnRyb2wgcmVhY2hlcyBlbmQgb2Ygbm9uLXZvaWQgZnVuY3Rpb24gWy1XcmV0dXJuLXR5 cGVdCiAgNTQwIHwgfQogICAgICB8IF4KLi4vY29udHJpYi9wZ19wbGFuX2FkdmljZS9wZ3BhX291 dHB1dC5jOiBJbiBmdW5jdGlvbiDigJhwZ3BhX2NzdHJpbmdfcXVlcnlfZmVhdHVyZV90eXBl4oCZ OgouLi9jb250cmliL3BnX3BsYW5fYWR2aWNlL3BncGFfb3V0cHV0LmM6NTYxOjE6IHdhcm5pbmc6 IGNvbnRyb2wgcmVhY2hlcyBlbmQgb2Ygbm9uLXZvaWQgZnVuY3Rpb24gWy1XcmV0dXJuLXR5cGVd CiAgNTYxIHwgfQogICAgICB8IF4KLi4vY29udHJpYi9wZ19wbGFuX2FkdmljZS9wZ3BhX3dhbGtl ci5jOiBJbiBmdW5jdGlvbiDigJhwZ3BhX3dhbGtfcmVjdXJzaXZlbHnigJk6Ci4uL2NvbnRyaWIv cGdfcGxhbl9hZHZpY2UvcGdwYV93YWxrZXIuYzozNjI6MjQ6IHdhcm5pbmc6IGlnbm9yaW5nIHJl dHVybiB2YWx1ZSBvZiDigJhsaXN0X3RydW5jYXRl4oCZIGRlY2xhcmVkIHdpdGggYXR0cmlidXRl IOKAmHdhcm5fdW51c2VkX3Jlc3VsdOKAmSBbLVd1bnVzZWQtcmVzdWx0XQogIDM2MiB8ICAgICAg ICAgICAgICAgICAodm9pZCkgbGlzdF90cnVuY2F0ZShhY3RpdmVfcXVlcnlfZmVhdHVyZXMsIG51 bV9hcWYgLSAxKTsKICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgIF5+fn5+fn5+fn5+fn5+ fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn4KSW4gZmlsZSBpbmNsdWRlZCBmcm9t IC4uL3NyYy9pbmNsdWRlL25vZGVzL3ByaW1ub2Rlcy5oOjIzLAogICAgICAgICAgICAgICAgIGZy b20gLi4vc3JjL2luY2x1ZGUvbm9kZXMvcGxhbm5vZGVzLmg6MjMsCiAgICAgICAgICAgICAgICAg ZnJvbSAuLi9jb250cmliL3BnX3BsYW5fYWR2aWNlL3BncGFfam9pbi5oOjE1LAogICAgICAgICAg ICAgICAgIGZyb20gLi4vY29udHJpYi9wZ19wbGFuX2FkdmljZS9wZ3BhX3dhbGtlci5jOjE0Ogou Li9jb250cmliL3BnX3BsYW5fYWR2aWNlL3BncGFfd2Fsa2VyLmM6IEluIGZ1bmN0aW9uIOKAmHBn cGFfd2Fsa2VyX2pvaW5fb3JkZXJfbWF0Y2hlc19tZW1iZXLigJk6Ci4uL3NyYy9pbmNsdWRlL25v ZGVzL3BnX2xpc3QuaDo0ODI6OTogd2FybmluZzogdGhpcyBzdGF0ZW1lbnQgbWF5IGZhbGwgdGhy b3VnaCBbLVdpbXBsaWNpdC1mYWxsdGhyb3VnaD1dCiAgNDgyIHwgICAgICAgICBmb3IgKHR5cGUg cG9pbnRlciB2YXIgPSAwLCBwb2ludGVyIHZhciMjX19vdXRlcmxvb3AgPSAodHlwZSBwb2ludGVy KSAxOyBcCiAgICAgIHwgICAgICAgICBefn4KLi4vc3JjL2luY2x1ZGUvbm9kZXMvcGdfbGlzdC5o OjQ2OTozNzogbm90ZTogaW4gZXhwYW5zaW9uIG9mIG1hY3JvIOKAmGZvcmVhY2hfaW50ZXJuYWzi gJkKICA0NjkgfCAjZGVmaW5lIGZvcmVhY2hfcHRyKHR5cGUsIHZhciwgbHN0KSBmb3JlYWNoX2lu dGVybmFsKHR5cGUsICosIHZhciwgbHN0LCBsZmlyc3QpCiAgICAgIHwgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgXn5+fn5+fn5+fn5+fn5+fgouLi9jb250cmliL3BnX3BsYW5f YWR2aWNlL3BncGFfd2Fsa2VyLmM6NzYyOjMzOiBub3RlOiBpbiBleHBhbnNpb24gb2YgbWFjcm8g 4oCYZm9yZWFjaF9wdHLigJkKICA3NjIgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IGZvcmVhY2hfcHRyKHBncGFfYWR2aWNlX3RhcmdldCwgY2hpbGRfdGFyZ2V0LCB0YXJnZXQtPmNo aWxkcmVuKQogICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXn5+fn5+fn5+ fn4KLi4vY29udHJpYi9wZ19wbGFuX2FkdmljZS9wZ3BhX3dhbGtlci5jOjc3MjoxNzogbm90ZTog aGVyZQogIDc3MiB8ICAgICAgICAgICAgICAgICBjYXNlIFBHUEFfVEFSR0VUX0lERU5USUZJRVI6 CiAgICAgIHwgICAgICAgICAgICAgICAgIF5+fn4KLi4vY29udHJpYi9wZ19wbGFuX2FkdmljZS9w Z3BhX3BsYW5uZXIuYzogSW4gZnVuY3Rpb24g4oCYcGdwYV9wbGFubmVyX2FwcGx5X3NjYW5fYWR2 aWNl4oCZOgouLi9jb250cmliL3BnX3BsYW5fYWR2aWNlL3BncGFfcGxhbm5lci5jOjE0MTQ6MzU6 IHdhcm5pbmc6IHN1Z2dlc3QgcGFyZW50aGVzZXMgYXJvdW5kIGNvbXBhcmlzb24gaW4gb3BlcmFu ZCBvZiDigJh84oCZIFstV3BhcmVudGhlc2VzXQogMTQxNCB8ICAgICAgICAgICAgICAgICBpZiAo bXlfZW50cnktPnRhZyA9PSBQR1BBX1RBR19HQVRIRVIgfAogICAgICB8ICAgICAgICAgICAgICAg ICAgICAgfn5+fn5+fn5+fn5+fn5efn5+fn5+fn5+fn5+fn5+fn4K --000000000000d94c8e0642716ada--