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 1rgy2m-008txe-CR for pgsql-hackers@arkaria.postgresql.org; Mon, 04 Mar 2024 02:27:08 +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 1rgy2j-003Lk5-7p for pgsql-hackers@arkaria.postgresql.org; Mon, 04 Mar 2024 02:27:05 +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 1rgy2i-003Ljw-Sl for pgsql-hackers@lists.postgresql.org; Mon, 04 Mar 2024 02:27:05 +0000 Received: from mail-vs1-xe29.google.com ([2607:f8b0:4864:20::e29]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1rgy2f-002dvO-TQ for pgsql-hackers@postgresql.org; Mon, 04 Mar 2024 02:27:04 +0000 Received: by mail-vs1-xe29.google.com with SMTP id ada2fe7eead31-47273838a21so2443912137.1 for ; Sun, 03 Mar 2024 18:27:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1709519220; x=1710124020; darn=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=WWdjU9Au50XHnEKTRBsWhR3t1pmaycs7k6yryxqcKKs=; b=ilXcuzj6kCm3n4XcmXhCHE7rh1jAsW11RX1zgiOVNYaF9+RjS4d7Zm0DfQ+zv7fYGe ojv2UosHUcIbau1JSWutblTTIK74v6p0rTQhvqTnMpX4Ama/raNUCEVS3ekslHeqtA4b F5JLpFJMn31bdyU/1MTwQHtAbnzd1AVi8B3rPi5aJtrKSlHgycaxlGG2uYFag9d84bBc yi9egRYJiCrwZlREZ/Cjn4JvIffyNmaF56+uKfzxtvolXa9/C0sXBMj/pOYCM0E6Y+o5 HtolTLxvWUzrWKoaiYgHB9uMHVZ0IQa0BJi7O240rAOoh/R0YQ50ws48nOOnpLDU0hxP 0mIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709519220; x=1710124020; 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=WWdjU9Au50XHnEKTRBsWhR3t1pmaycs7k6yryxqcKKs=; b=XRi4vUWeelpDTi4mS1Syhwgyxm0lE99OmSPcJmCO0QjOcWZ5YwkOvkur4yP2ctluyl bqIR+48Q3pe3MzmX5GW6E9fhJ0YMAj72EZyLMXFhfdLvu7bQrDIW4cA4P3pnbG1iVzQp v41bZBr2XzXuQJ48eCAZOzqa+i1z/n5zIxMLxHm6r/t4tq9YXaXnm25MefdJak8/Rnma C8Vucb8M2cz5qX+HWbvSC0GlOabDWPW/fy1fw7/1guFBNO4tUX6JxzsIOOyhtUgQcRHz JrBFQ7aBK4USvRCapPia3O00SqFQ/tKbldObEs9LUSXiCl2VJX/Hw4osMyoTr0mN17RM gFJg== X-Forwarded-Encrypted: i=1; AJvYcCWfuT/R85wZ2K4nQbckyKQXXt69E2Kgo5PG+cC3b2SMMKmQ6hMkGH5Y7uCHcNaCUU0rSRs3tROAesh60pgey1Q/szXnbAUDMQAie8L3 X-Gm-Message-State: AOJu0Yy+3nU78UYjaOay7Jc3ElqN1gjdHMqucMMBkl15+NdfuLLPNMyg wNQLA3wp0pnVS/5O8TbVfrmbycxjlWCyEEmCMgL4NJ+G/LewO6wdJchdDpuhSRUIe4wGgL/rEDB n/TBwcgI6jSzrl21gGBLiinjgz7M= X-Google-Smtp-Source: AGHT+IHRrUTSHqv9h/sFdCrWwQB20EtLKfiA2DFxIaNZOstRTno3/YAqCTq033llCUZPF4m1xrIM3t5v+TtMzOwjsZU= X-Received: by 2002:a05:6102:3239:b0:470:5cbc:4f4c with SMTP id x25-20020a056102323900b004705cbc4f4cmr6311323vsf.16.1709519219840; Sun, 03 Mar 2024 18:26:59 -0800 (PST) MIME-Version: 1.0 References: <567ED6CA.2040504@sigaev.ru> <1cf6b382-6e27-4268-9f2a-54ada66eb2eb@postgrespro.ru> <5f119769-ab11-4807-abcc-71d5dd914ea0@postgrespro.ru> <21088129-7cd3-424a-bcce-6a3427ba3276@postgrespro.ru> <11ee9c04-281f-43c8-a0ff-d481c1e01c09@postgrespro.ru> <54009ba5-4aea-4344-a30d-e3558a59e2a9@postgrespro.ru> <380e5683-cdfd-4220-ab9b-7cccb9d3e480@postgrespro.ru> In-Reply-To: <380e5683-cdfd-4220-ab9b-7cccb9d3e480@postgrespro.ru> From: jian he Date: Mon, 4 Mar 2024 10:26:48 +0800 Message-ID: Subject: Re: POC, WIP: OR-clause support for indexes To: Andrei Lepikhov Cc: Alena Rybakina , Alexander Korotkov , Robert Haas , pgsql-hackers@postgresql.org, Peter Geoghegan , "Finnerty, Jim" , Marcos Pegoraro , teodor@sigaev.ru, Tomas Vondra , Peter Eisentraut , Ranier Vilela Content-Type: multipart/mixed; boundary="000000000000d5f8470612cc755e" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000d5f8470612cc755e Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Thu, Feb 29, 2024 at 4:59=E2=80=AFPM Andrei Lepikhov wrote: > > On 28/2/2024 17:27, Alena Rybakina wrote: > > Maybe like that: > > > > It also considers the way to generate a path using BitmapScan indexes, > > converting the transformed expression into expressions separated by "OR= " > > operations, and if it turns out to be the best and finally selects the > > best one. > Thanks, > I spent some time describing the feature with documentation. > A condensed description of the GUC is in the runtime-config file. > Feature description has spread between TransformOrExprToANY and > generate_saop_pathlist routines. > Also, I've made tiny changes in the code to look more smoothly. > All modifications are integrated into the two new patches. > > Feel free to add, change or totally rewrite these changes. diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 93ded31ed9..7d3a1ca238 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -1026,6 +1026,17 @@ struct config_bool ConfigureNamesBool[] =3D true, NULL, NULL, NULL }, + { + {"enable_or_transformation", PGC_USERSET, QUERY_TUNING_OTHER, + gettext_noop("Transform a sequence of OR clauses to an IN expression."), + gettext_noop("The planner will replace clauses like 'x=3Dc1 OR x=3Dc2 .." + "to the clause 'x IN (c1,c2,...)'"), + GUC_EXPLAIN + }, + &enable_or_transformation, + true, + NULL, NULL, NULL + }, I think it should be something like: + gettext_noop("Transform a sequence of OR expressions to an array expression."), + gettext_noop("The planner will replace expression like 'x=3Dc1 OR x=3Dc2 = " + "to the expression 'x =3D ANY( ARRAY[c1,c2])''" +JumbleState * +JumbleExpr(Expr *expr, uint64 *queryId) +{ + JumbleState *jstate =3D NULL; + + Assert(queryId !=3D NULL); + + jstate =3D (JumbleState *) palloc(sizeof(JumbleState)); + + /* Set up workspace for query jumbling */ + jstate->jumble =3D (unsigned char *) palloc(JUMBLE_SIZE); + jstate->jumble_len =3D 0; + jstate->clocations_buf_size =3D 32; + jstate->clocations =3D (LocationLen *) + palloc(jstate->clocations_buf_size * sizeof(LocationLen)); + jstate->clocations_count =3D 0; + jstate->highest_extern_param_id =3D 0; + + /* Compute query ID */ + _jumbleNode(jstate, (Node *) expr); + *queryId =3D DatumGetUInt64(hash_any_extended(jstate->jumble, + jstate->jumble_len, + 0)); + + return jstate; +} queryId may not be a good variable name here? comment `/* Compute query ID */` seems not correct, here we are just hashing the expression? +/* + * Dynahash match function to use in guc_hashtab + */ +static int +orclause_match(const void *data1, const void *data2, Size keysize) +{ + OrClauseGroupKey *key1 =3D (OrClauseGroupKey *) data1; + OrClauseGroupKey *key2 =3D (OrClauseGroupKey *) data2; + + Assert(sizeof(OrClauseGroupKey) =3D=3D keysize); + + if (key1->opno =3D=3D key2->opno && key1->exprtype =3D=3D key2->exprtype = && + equal(key1->expr, key2->expr)) + return 0; + + return 1; +} the above comments seem not correct? Enables or disables the query planner's ability to lookup and group multiple similar OR expressions to ANY () expressions. The grouping technique of this transformation is based on the similarity of variable sides. It applies to equality expressions only. One side of such an expres= sion must be a constant clause, and the other must contain a variable cl= ause. The default is on. Also, during BitmapScan paths generation it enables analysis of ele= ments of IN or ANY constant arrays to cover such clause with BitmapOr set= of partial index scans. ` It applies to equality expressions only.` seems not correct? `select * from tenk1 where unique1 < 1 or unique1 < 2; ` can also do the transformation. `similarity of variable sides.` seems not correct, should it be 'sameness of the variable sides`? in [1], we can get: expression IN (value [, ...]) is equivalent to expression =3D value1 OR expression =3D value2 OR in [2], we can get: SOME is a synonym for ANY. IN is equivalent to =3D ANY. but still transforming OR to ANY is not intuitive. a normal user may not know what is "transforming OR to ANY". so maybe adding a simple example at would be great. which, I did at previous thread. I also did some refactoring based on v18, attached. [1] https://www.postgresql.org/docs/current/functions-comparisons.html#FUNC= TIONS-COMPARISONS-IN-SCALAR [2] https://www.postgresql.org/docs/current/functions-subquery.html#FUNCTIO= NS-SUBQUERY-ANY-SOME --000000000000d5f8470612cc755e Content-Type: application/octet-stream; name="v18-0001-Minor-miscellaneous-refactor-based-on-v18.no-cfbot" Content-Disposition: attachment; filename="v18-0001-Minor-miscellaneous-refactor-based-on-v18.no-cfbot" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_ltcbbvkb0 RnJvbSBiNTdiMTcwMWFiOGZlM2UzMTliYTVhN2NkMTkwZmUwNGNhMjY5NmUwIE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBqaWFuIGhlIDxqaWFuLnVuaXZlcnNhbGl0eUBnbWFpbC5jb20+ CkRhdGU6IE1vbiwgNCBNYXIgMjAyNCAxMDoxODoxMiArMDgwMApTdWJqZWN0OiBbUEFUQ0ggdjE4 IDEvMV0gTWlub3IgbWlzY2VsbGFuZW91cyByZWZhY3RvciBiYXNlZCBvbiB2MTguCgotLS0KIHNy Yy9iYWNrZW5kL29wdGltaXplci9wYXRoL2luZHhwYXRoLmMgfCAxMSArKysrLS0tLQogc3JjL2Jh Y2tlbmQvcGFyc2VyL3BhcnNlX2V4cHIuYyAgICAgICB8IDQwICsrKysrKysrKysrKysrKy0tLS0t LS0tLS0tLQogMiBmaWxlcyBjaGFuZ2VkLCAyNyBpbnNlcnRpb25zKCspLCAyNCBkZWxldGlvbnMo LSkKCmRpZmYgLS1naXQgYS9zcmMvYmFja2VuZC9vcHRpbWl6ZXIvcGF0aC9pbmR4cGF0aC5jIGIv c3JjL2JhY2tlbmQvb3B0aW1pemVyL3BhdGgvaW5keHBhdGguYwppbmRleCA0N2JmNTM4Mi4uYTc3 NThkZjYgMTAwNjQ0Ci0tLSBhL3NyYy9iYWNrZW5kL29wdGltaXplci9wYXRoL2luZHhwYXRoLmMK KysrIGIvc3JjL2JhY2tlbmQvb3B0aW1pemVyL3BhdGgvaW5keHBhdGguYwpAQCAtMTI4NCw3ICsx Mjg0LDcgQEAgYnVpbGRfcGF0aHNfZm9yX1NBT1AoUGxhbm5lckluZm8gKnJvb3QsIFJlbE9wdElu Zm8gKnJlbCwgUmVzdHJpY3RJbmZvICpyaW5mbywKIAkJQXJyYXlUeXBlCQkgICAqYXJyYXl2YWwg PSBOVUxMOwogCQlBcnJheUV4cHIJCSAgICphcnIgPSBOVUxMOwogCQlDb25zdAkJCSAgICphcnJh eWNvbnN0OwotCQlTY2FsYXJBcnJheU9wRXhwcglkZXN0OworCQlTY2FsYXJBcnJheU9wRXhwciAg KmRlc3QgPSBOVUxMOwogCiAJCXBkID0gKFByZWRpY2F0ZXNEYXRhICopIGxmaXJzdChsYyk7CiAJ CWlmIChwZC0+ZWxlbXMgPT0gTklMKQpAQCAtMTI5NSw2ICsxMjk1LDcgQEAgYnVpbGRfcGF0aHNf Zm9yX1NBT1AoUGxhbm5lckluZm8gKnJvb3QsIFJlbE9wdEluZm8gKnJlbCwgUmVzdHJpY3RJbmZv ICpyaW5mbywKIAkJYXJyYXljb25zdCA9IGxzZWNvbmRfbm9kZShDb25zdCwgc2FvcC0+YXJncyk7 CiAJCWFycmF5dmFsID0gRGF0dW1HZXRBcnJheVR5cGVQKGFycmF5Y29uc3QtPmNvbnN0dmFsdWUp OwogCQlhcnIgPSBtYWtlTm9kZShBcnJheUV4cHIpOworCQlkZXN0ID0gbWFrZU5vZGUoU2NhbGFy QXJyYXlPcEV4cHIpOwogCQlhcnItPmFycmF5X2NvbGxpZCA9IGFycmF5Y29uc3QtPmNvbnN0Y29s bGlkOwogCQlhcnItPmFycmF5X3R5cGVpZCA9IGFycmF5Y29uc3QtPmNvbnN0dHlwZTsKIAkJYXJy LT5lbGVtZW50X3R5cGVpZCA9IGFycmF5dmFsLT5lbGVtdHlwZTsKQEAgLTEzMDMsMTAgKzEzMDQs MTAgQEAgYnVpbGRfcGF0aHNfZm9yX1NBT1AoUGxhbm5lckluZm8gKnJvb3QsIFJlbE9wdEluZm8g KnJlbCwgUmVzdHJpY3RJbmZvICpyaW5mbywKIAkJYXJyLT5tdWx0aWRpbXMgPSBmYWxzZTsKIAog CQkvKiBDb21wb3NlIG5ldyBTQU9QLCBwYXJ0aWFsbHkgY292ZXJpbmcgdGhlIHNvdXJjZSBvbmUg Ki8KLQkJbWVtY3B5KCZkZXN0LCBzYW9wLCBzaXplb2YoU2NhbGFyQXJyYXlPcEV4cHIpKTsKLQkJ ZGVzdC5hcmdzID0gbGlzdF9tYWtlMihsaW5pdGlhbChzYW9wLT5hcmdzKSwgYXJyKTsKKwkJbWVt Y3B5KGRlc3QsIHNhb3AsIHNpemVvZihTY2FsYXJBcnJheU9wRXhwcikpOworCQlkZXN0LT5hcmdz ID0gbGlzdF9tYWtlMihsaW5pdGlhbChzYW9wLT5hcmdzKSwgYXJyKTsKIAotCQljbGF1c2UgPSAo RXhwciAqKSBlc3RpbWF0ZV9leHByZXNzaW9uX3ZhbHVlKHJvb3QsIChOb2RlICopICZkZXN0KTsK KwkJY2xhdXNlID0gKEV4cHIgKikgZXN0aW1hdGVfZXhwcmVzc2lvbl92YWx1ZShyb290LCAoTm9k ZSAqKSBkZXN0KTsKIAogCQkvKgogCQkgKiBDcmVhdGUgbmV3IFJlc3RyaWN0SW5mby4gSXQgbWF5 YmUgbW9yZSBoZWF2eSB0aGFuIGp1c3QgY29weSBub2RlLApAQCAtMTMzMCwxMyArMTMzMSwxMSBA QCBidWlsZF9wYXRoc19mb3JfU0FPUChQbGFubmVySW5mbyAqcm9vdCwgUmVsT3B0SW5mbyAqcmVs LCBSZXN0cmljdEluZm8gKnJpbmZvLAogCQlBc3NlcnQoIXByZWRpY2F0ZV9pbXBsaWVkX2J5KGlu ZGV4LT5pbmRwcmVkLCBvdGhlcl9jbGF1c2VzLCBmYWxzZSkpOwogCiAJCS8qIFRpbWUgdG8gZ2Vu ZXJhdGUgaW5kZXggcGF0aHMgKi8KLQogCQlNZW1TZXQoJmNsYXVzZXNldCwgMCwgc2l6ZW9mKGNs YXVzZXNldCkpOwogCQltYXRjaF9jbGF1c2VzX3RvX2luZGV4KHJvb3QsIGxpc3RfbWFrZTEocmlu Zm8xKSwgaW5kZXgsICZjbGF1c2VzZXQpOwogCQltYXRjaF9jbGF1c2VzX3RvX2luZGV4KHJvb3Qs IG90aGVyX2NsYXVzZXMsIGluZGV4LCAmY2xhdXNlc2V0KTsKIAogCQkvKiBQcmVkaWNhdGUgaGFz IGZvdW5kIGFscmVhZHkuIFNvLCBpdCBpcyBvayBmb3IgdGhlIGVtcHR5IG1hdGNoICovCi0KIAkJ aW5kZXhwYXRocyA9IGJ1aWxkX2luZGV4X3BhdGhzKHJvb3QsIHJlbCwKIAkJCQkJCQkJCSAgIGlu ZGV4LCAmY2xhdXNlc2V0LAogCQkJCQkJCQkJICAgdHJ1ZSwKZGlmZiAtLWdpdCBhL3NyYy9iYWNr ZW5kL3BhcnNlci9wYXJzZV9leHByLmMgYi9zcmMvYmFja2VuZC9wYXJzZXIvcGFyc2VfZXhwci5j CmluZGV4IDEwY2VjY2M4Li44YTc0MzJhNCAxMDA2NDQKLS0tIGEvc3JjL2JhY2tlbmQvcGFyc2Vy L3BhcnNlX2V4cHIuYworKysgYi9zcmMvYmFja2VuZC9wYXJzZXIvcGFyc2VfZXhwci5jCkBAIC0x NjksMjMgKzE2OSwyOSBAQCBvcmNsYXVzZV9tYXRjaChjb25zdCB2b2lkICpkYXRhMSwgY29uc3Qg dm9pZCAqZGF0YTIsIFNpemUga2V5c2l6ZSkKIH0KIAogLyoKLSAqIFRyYW5zZm9ybU9yRXhwclRv QU5ZIC0KLSAqCSAgRGlzY292ZXIgdGhlIGFyZ3Mgb2YgYW4gT1IgZXhwcmVzc2lvbiBhbmQgdHJ5 IHRvIGdyb3VwIHNpbWlsYXIgT1IKLSAqCSAgZXhwcmVzc2lvbnMgdG8gYW4gQU5ZIG9wZXJhdGlv bi4KLSAqCSAgVHJhbnNmb3JtYXRpb24gbXVzdCBiZSBhbHJlYWR5IGRvbmUgb24gaW5wdXQgYXJn cyBsaXN0IGJlZm9yZSB0aGUgY2FsbC4KLSAqCSAgVHJhbnNmb3JtYXRpb24gZ3JvdXBzIHR3by1z aWRlZCBlcXVhbGl0eSBvcGVyYXRpb25zLiBPbmUgc2lkZSBvZiBzdWNoIGFuCi0gKgkgIG9wZXJh dGlvbiBtdXN0IGJlIHBsYWluIGNvbnN0YW50IG9yIGNvbnN0YW50IGV4cHJlc3Npb24uIFRoZSBv dGhlciBzaWRlIG9mCi0gKgkgIHRoZSBjbGF1c2UgbXVzdCBiZSBhIHZhcmlhYmxlIGV4cHJlc3Np b24gd2l0aG91dCB2b2xhdGlsZSBmdW5jdGlvbnMuCi0gKgkgIFRoZSBncm91cGluZyB0ZWNobmlx dWUgaXMgYmFzZWQgb24gdGhlIHNpbWlsYXJpdHkgb2YgdmFyaWFibGUgc2lkZXMgb2YgdGhlCi0g KgkgIGV4cHJlc3Npb246IHVzaW5nIHF1ZXJ5SWQgYW5kIGVxdWFsKCkgcm91dGluZSwgaXQgZ3Jv dXBzIGNvbnN0YW50IHNpZGVzIG9mCi0gKgkgIHNpbWlsYXIgY2xhdXNlcyBpbnRvIGFuIGFycmF5 LiBBZnRlciB0aGUgZ3JvdXBpbmcgcHJvY2VkdXJlLCBlYWNoIGNvdXBsZQotICoJICAoJ3Zhcmlh YmxlIGV4cHJlc3Npb24nIGFuZCAnY29uc3RhbnQgYXJyYXknKSBmb3JtIGEgbmV3IFNBT1Agb3Bl cmF0aW9uLAotICoJICB3aGljaCBpcyBhZGRlZCB0byB0aGUgYXJncyBsaXN0IG9mIHRoZSByZXR1 cm5pbmcgZXhwcmVzc2lvbi4KKyAqIFRyYW5zZm9ybU9yRXhwclRvQU5ZCisgKiBEaXNjb3ZlciB0 aGUgYXJncyBvZiBhbiBPUiBleHByZXNzaW9uIGFuZCB0cnkgdG8gZ3JvdXAgc2ltaWxhciBPUgor ICogZXhwcmVzc2lvbnMgdG8gYW4gQU5ZIG9wZXJhdGlvbi4KICAqCi0gKgkgIE5PVEU6IGZ1bmN0 aW9uIHJldHVybnMgT1IgQm9vbEV4cHIgaWYgbW9yZSB0aGFuIG9uZSBjbGF1c2UgYXJlIGRldGVj dGVkIGluCi0gKgkgIHRoZSBmaW5hbCBhcmdzIGxpc3QsIG9yIFNjYWxhckFycmF5T3BFeHByIGlm IGFsbCBhcmdzIHdlcmUgZ3JvdXBlZCBpbnRvCi0gKgkgIHRoZSBzaW5nbGUgU0FPUCBleHByZXNz aW9uLgotICovCisgKiBUcmFuc2Zvcm1hdGlvbiBtdXN0IGJlIGFscmVhZHkgZG9uZSBvbiBpbnB1 dCBhcmdzIGxpc3QgYmVmb3JlIHRoZSBjYWxsLgorICogVHJhbnNmb3JtYXRpb24gZ3JvdXBzIG11 bGl0cGxlIE9SIGV4cHJlc3Npb25zCisgKiAoaS5lLiBFeHByZXNzaW9uQSBPUiBFeHByZXNzaW9u QikgaW50byBhIFNBT1AgZXhwcmVzc2lvbi4gRm9yIGVhY2ggc2luZ2xlCisgKiBleHByZXNzaW9u LCBvbmUgc2lkZSBvZiBzdWNoIGFuIGV4cHJlc3Npb24gbXVzdCBiZSBhIHBsYWluIGNvbnN0YW50 IG9yCisgKiBjb25zdGFudCBleHByZXNzaW9uLiBUaGUgb3RoZXIgc2lkZSBvZiB0aGUgZXhwcmVz c2lvbiBtdXN0IGJlIGEgdmFyaWFibGUKKyAqIGV4cHJlc3Npb24gd2l0aG91dCB2b2xhdGlsZSBm dW5jdGlvbnMuCisgKgorICogVGhlIGdyb3VwaW5nIHRlY2huaXF1ZSBpcyBiYXNlZCBvbiB0aGUg c2FtZW5lc3Mgb2YgdGhlIGV4cHJlc3Npb24ncyB2YXJpYWJsZQorICogc2lkZS4gV2UgdXNlIHZh cmlhYmxlIHNpZGVzIGV4cHJlc3Npb24ncyBoYXNoIGtleSBjb21wYXJpc29uIGZ1bmN0aW9uIGFu ZAorICogaGFzaCByb3V0aW5lIHRvIGV2YXVsYXRlIHRoZSBzYW1lbmVzcy4gSWZmIHRoZSB2YXJp YWJsZSBzaWRlIGlzIHRoZSBzYW1lLAorICogdGhlbiB3ZSBncm91cHMgbXVsdGlwbGUgZXhwcmVz c2lvbidzIGNvbnN0YW50IGludG8gYW4gYXJyYXkuCisgKiBBZnRlciB0aGUgZ3JvdXBpbmcgcHJv Y2VkdXJlLCBlYWNoIGNvdXBsZQorICogKCd2YXJpYWJsZSBleHByZXNzaW9uJyBhbmQgJ2NvbnN0 YW50IGFycmF5JykgZm9ybSBhIG5ldyBTQU9QIGV4cHJlc3Npb24sCisgKiB3aGljaCBpcyBhZGRl ZCB0byB0aGUgYXJncyBsaXN0IG9mIHRoZSByZXR1cm5pbmcgZXhwcmVzc2lvbi4KKyAqCisgKiBO T1RFOiBmdW5jdGlvbiByZXR1cm5zIE9SIEJvb2xFeHByIGlmIG1vcmUgdGhhbiBvbmUgY2xhdXNl IGFyZSBkZXRlY3RlZCBpbgorICogdGhlIGZpbmFsIGFyZ3MgbGlzdCwgb3IgU2NhbGFyQXJyYXlP cEV4cHIgaWYgYWxsIGFyZ3Mgd2VyZSBncm91cGVkIGludG8KKyAqIHRoZSBzaW5nbGUgU0FPUCBl eHByZXNzaW9uLgorKi8KIHN0YXRpYyBOb2RlICoKIFRyYW5zZm9ybU9yRXhwclRvQU5ZKFBhcnNl U3RhdGUgKnBzdGF0ZSwgTGlzdCAqYXJncywgaW50IGxvY2F0aW9uKQogewpAQCAtMzI4LDcgKzMz NCw2IEBAIFRyYW5zZm9ybU9yRXhwclRvQU5ZKFBhcnNlU3RhdGUgKnBzdGF0ZSwgTGlzdCAqYXJn cywgaW50IGxvY2F0aW9uKQogCSAqIEdvIHRocm91Z2ggdGhlIGxpc3Qgb2YgZ3JvdXBzIGFuZCBj b252ZXJ0IGVhY2gsIHdoZXJlIG51bWJlciBvZgogCSAqIGNvbnN0cyBtb3JlIHRoYW4gMS4gdHJp dmlhbCBncm91cHMgbW92ZSB0byBPUi1saXN0IGFnYWluCiAJICovCi0KIAlmb3JlYWNoIChsYywg ZW50cmllcykKIAl7CiAJCU9pZAkJCQkgICAgc2NhbGFyX3R5cGU7CkBAIC0zNTMsNyArMzU4LDYg QEAgVHJhbnNmb3JtT3JFeHByVG9BTlkoUGFyc2VTdGF0ZSAqcHN0YXRlLCBMaXN0ICphcmdzLCBp bnQgbG9jYXRpb24pCiAJCS8qCiAJCSAqIERvIHRoZSB0cmFuc2Zvcm1hdGlvbi4KIAkJICovCi0K IAkJc2NhbGFyX3R5cGUgPSBlbnRyeS0+a2V5LmV4cHJ0eXBlOwogCQlhcnJheV90eXBlID0gT2lk SXNWYWxpZChzY2FsYXJfdHlwZSkgPyBnZXRfYXJyYXlfdHlwZShzY2FsYXJfdHlwZSkgOgogCQkJ CQkJCQkJCQkgICBJbnZhbGlkT2lkOwotLSAKMi4zNC4xCgo= --000000000000d5f8470612cc755e--