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 1rUotq-00DCio-Ru for pgsql-hackers@arkaria.postgresql.org; Tue, 30 Jan 2024 14:15:43 +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 1rUotn-006WTa-Ds for pgsql-hackers@arkaria.postgresql.org; Tue, 30 Jan 2024 14:15:39 +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.94.2) (envelope-from ) id 1rUotn-006WSP-43 for pgsql-hackers@lists.postgresql.org; Tue, 30 Jan 2024 14:15:39 +0000 Received: from mail-oi1-x230.google.com ([2607:f8b0:4864:20::230]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1rUotg-0049xR-48 for pgsql-hackers@postgresql.org; Tue, 30 Jan 2024 14:15:37 +0000 Received: by mail-oi1-x230.google.com with SMTP id 5614622812f47-3be7c2ed375so780698b6e.0 for ; Tue, 30 Jan 2024 06:15:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1706624131; x=1707228931; darn=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=vozBgLmJv/rdOMEkPKdl09xML/Bps5vdYqJJE1TpBcM=; b=ZKx28Hz9Pbd7i/amFyT9m8rZWz3zOu9JDPHqHIxS39Tuhk8SlbMe0cAIopWgrtPlQg 5dE2Zj4DJZsuzcvOSLI2NRT7uuvQKBKba19kp6TaeOkmWhPVKKmI7MP5uIgpJbru7NVX QD/aGjuXH0CA9aF21A7XVQlN6tCO5ggDC7qShAmHS3+gsWuZCRLqVpMbZ04XiJSEUzn0 aNmICcX2wRF5ApTgdnlVxsyDAw8TpuS1KnINkwXLsyEExha93safQDdp+cPYpWymXOYs r8CQ3ZyCLAibAJrFNH/S7Pqc0sNU5rIgV6QhiB25jhBslgB7QhwRPoCZxEyvGRpmK/SA Jpbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706624131; x=1707228931; h=content-transfer-encoding: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=vozBgLmJv/rdOMEkPKdl09xML/Bps5vdYqJJE1TpBcM=; b=NDsSd/GPKlCKM8EnAPBwOUjAVMf8VKch+Git3bEK5rh6FOzzdFcKD1cXV08zwyJvQ/ 4rr8HJnkrcr2H5zPrMDrQvNk461cYGRrI/KfCMXWetAGCojCcEzLcysx/O+Gvva4uqXS b2s/nMVa06cZBGDxkMlSWMAE+XsAs1Ku6ehIGicbbFjVJ2izj9XN2S8+ntnLyPDwTiOF eqls8lSJc4SZ6TEqTBDlCdaxhee86Y8utmh0TG74/8pOOXYNtNwKV0TwgBH9OdvP6gqP KlG52/HuYZ3ILubT+SbyWePDrQty0FO0/K7ksud/wphLXIhy+xC5cIiFTUqvQkrPWGfq uR5Q== X-Gm-Message-State: AOJu0YxxJzR/jOt2FDcYHQ4Ps2QW2Ni36Bn06onJpe5aLU6NRIDuqc5J fjZ89XW2/xY5VSiHr4QQsDbQpc8upPH0AUdAbt9FAc1h486A2lSAe9fa9ip9H5Mt/ZN36/0paPf cSRDI7v/azd8Z1aP2zFOmkyN4c5o= X-Google-Smtp-Source: AGHT+IGv9qu3rtDe0Q1EkY9VdjV7B7zSDucQYJc+XZ8Wy83CpCfcUbeJLxqu6/O4AXJ9yEXaM9VkzFlgKQEKD7l55l0= X-Received: by 2002:a05:6808:2202:b0:3bd:c227:5cff with SMTP id bd2-20020a056808220200b003bdc2275cffmr9456629oib.26.1706624131282; Tue, 30 Jan 2024 06:15:31 -0800 (PST) MIME-Version: 1.0 References: <567ED6CA.2040504@sigaev.ru> <16a7e3aa-24c0-4986-8820-ea2857bd7b6b@postgrespro.ru> <421656a9-5df7-41bb-9d58-1c1edbd5dc3e@postgrespro.ru> <28c727ba-5260-42a8-88b0-4ecdeeca6ef8@postgrespro.ru> <4c1c2c0b-802f-45ae-a7cd-007bfd8957cf@postgrespro.ru> <52f0d302-7963-452f-8c5a-f66d261514eb@postgrespro.ru> <43ad8a48-b980-410d-a83c-5beebf82a4ed@postgrespro.ru> <04ef16eb-46c1-4ce7-9f68-d1c80ef0be81@postgrespro.ru> <59e67a40-95a8-4d74-ae4e-027ea0f59084@postgrespro.ru> <59b77a8a-29d6-4727-bf26-4a30a6a9719a@postgrespro.ru> <32d23d97-d07f-4d44-9933-ba3295fb3ed8@postgrespro.ru> In-Reply-To: From: jian he Date: Tue, 30 Jan 2024 22:15:20 +0800 Message-ID: Subject: Re: POC, WIP: OR-clause support for indexes To: Andrei Lepikhov Cc: Alena Rybakina , Robert Haas , pgsql-hackers@postgresql.org, Alexander Korotkov , Peter Geoghegan , "Finnerty, Jim" , Marcos Pegoraro , teodor@sigaev.ru, Ranier Vilela , Tomas Vondra , Peter Eisentraut 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 Tue, Dec 5, 2023 at 6:55=E2=80=AFPM Andrei Lepikhov wrote: > > Here is fresh version with the pg_dump.pl regex fixed. Now it must pass > buildfarm. +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)); + + if (*queryId =3D=3D UINT64CONST(0)) + *queryId =3D UINT64CONST(1); + + return jstate; +} +/* + * Hash function that's compatible with guc_name_compare + */ +static uint32 +orclause_hash(const void *data, Size keysize) +{ + OrClauseGroupKey *key =3D (OrClauseGroupKey *) data; + uint64 hash; + + (void) JumbleExpr(key->expr, &hash); + hash +=3D ((uint64) key->opno + (uint64) key->exprtype) % UINT64_MAX; + return hash; +} correct me if i am wrong: in orclause_hash, you just want to return a uint32, then why does the JumbleExpr function return struct JumbleState. here JumbleExpr, we just simply hash part of a Query struct, so JumbleExpr's queryId would be confused with JumbleQuery function's query= Id. not sure the purpose of the following: + if (*queryId =3D=3D UINT64CONST(0)) + *queryId =3D UINT64CONST(1); even if *queryId is 0 `hash +=3D ((uint64) key->opno + (uint64) key->exprtype) % UINT64_MAX;` will make the hash return non-zero? + MemSet(&info, 0, sizeof(info)); i am not sure this is necessary. Some comments on OrClauseGroupEntry would be great. seems there is no doc. create or replace function retint(int) returns int as $func$ begin return $1 + round(10 * random()); end $func$ LANGUAGE plpgsql; set enable_or_transformation to on; EXPLAIN (COSTS OFF) SELECT count(*) FROM tenk1 WHERE thousand =3D 42 AND (tenthous * retint(1) =3D NULL OR tenthous * retint(1) =3D 3) OR thousand =3D 41; returns: QUERY PLAN ---------------------------------------------------------------------------= ---------------------------------------- Aggregate -> Seq Scan on tenk1 Filter: (((thousand =3D 42) AND ((tenthous * retint(1)) =3D ANY ('{NULL,3}'::integer[]))) OR (thousand =3D 41)) (3 rows) Based on the query plan, retint executed once, but here it should be executed twice? maybe we need to use contain_volatile_functions to check through the other part of the operator expression. + if (IsA(leftop, Const)) + { + opno =3D get_commutator(opno); + + if (!OidIsValid(opno)) + { + /* Commuter doesn't exist, we can't reverse the order */ + or_list =3D lappend(or_list, orqual); + continue; + } + + nconst_expr =3D get_rightop(orqual); + const_expr =3D get_leftop(orqual); + } + else if (IsA(rightop, Const)) + { + const_expr =3D get_rightop(orqual); + nconst_expr =3D get_leftop(orqual); + } + else + { + or_list =3D lappend(or_list, orqual); + continue; + } do we need to skip this transformation for the const type is anyarray?