Re: POC, WIP: OR-clause support for indexes - Mailing list pgsql-hackers
From | jian he |
---|---|
Subject | Re: POC, WIP: OR-clause support for indexes |
Date | |
Msg-id | CACJufxGXhJ823cdAdp2Ho7qC-HZ3_-dtdj-myaAi_u9RQLn45g@mail.gmail.com Whole thread Raw |
In response to | Re: POC, WIP: OR-clause support for indexes (Andrei Lepikhov <a.lepikhov@postgrespro.ru>) |
Responses |
Re: POC, WIP: OR-clause support for indexes
|
List | pgsql-hackers |
On Tue, Dec 5, 2023 at 6:55 PM Andrei Lepikhov <a.lepikhov@postgrespro.ru> 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 = NULL; + + Assert(queryId != NULL); + + jstate = (JumbleState *) palloc(sizeof(JumbleState)); + + /* Set up workspace for query jumbling */ + jstate->jumble = (unsigned char *) palloc(JUMBLE_SIZE); + jstate->jumble_len = 0; + jstate->clocations_buf_size = 32; + jstate->clocations = (LocationLen *) + palloc(jstate->clocations_buf_size * sizeof(LocationLen)); + jstate->clocations_count = 0; + jstate->highest_extern_param_id = 0; + + /* Compute query ID */ + _jumbleNode(jstate, (Node *) expr); + *queryId = DatumGetUInt64(hash_any_extended(jstate->jumble, + jstate->jumble_len, + 0)); + + if (*queryId == UINT64CONST(0)) + *queryId = UINT64CONST(1); + + return jstate; +} +/* + * Hash function that's compatible with guc_name_compare + */ +static uint32 +orclause_hash(const void *data, Size keysize) +{ + OrClauseGroupKey *key = (OrClauseGroupKey *) data; + uint64 hash; + + (void) JumbleExpr(key->expr, &hash); + hash += ((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 queryId. not sure the purpose of the following: + if (*queryId == UINT64CONST(0)) + *queryId = UINT64CONST(1); even if *queryId is 0 `hash += ((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 = 42 AND (tenthous * retint(1) = NULL OR tenthous * retint(1) = 3) OR thousand = 41; returns: QUERY PLAN ------------------------------------------------------------------------------------------------------------------- Aggregate -> Seq Scan on tenk1 Filter: (((thousand = 42) AND ((tenthous * retint(1)) = ANY ('{NULL,3}'::integer[]))) OR (thousand = 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 = get_commutator(opno); + + if (!OidIsValid(opno)) + { + /* Commuter doesn't exist, we can't reverse the order */ + or_list = lappend(or_list, orqual); + continue; + } + + nconst_expr = get_rightop(orqual); + const_expr = get_leftop(orqual); + } + else if (IsA(rightop, Const)) + { + const_expr = get_rightop(orqual); + nconst_expr = get_leftop(orqual); + } + else + { + or_list = lappend(or_list, orqual); + continue; + } do we need to skip this transformation for the const type is anyarray?
pgsql-hackers by date: