1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-19 13:42:17 +03:00

Extract make_SAOP_expr() function from match_orclause_to_indexcol()

This commit extracts the code to generate ScalarArrayOpExpr on top of the list
of expressions from match_orclause_to_indexcol() into a separate function
make_SAOP_expr().  This function was extracted to be used in optimization for
conversion of 'x IN (VALUES ...)' to 'x = ANY ...'.  make_SAOP_expr() is
placed in clauses.c file as only two additional headers were needed there
compared with other places.

Discussion: https://postgr.es/m/0184212d-1248-4f1f-a42d-f5cb1c1976d2%40tantorlabs.com
Author: Alena Rybakina <a.rybakina@postgrespro.ru>
Author: Andrei Lepikhov <lepihov@gmail.com>
Reviewed-by: Ivan Kush <ivan.kush@tantorlabs.com>
Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
This commit is contained in:
Alexander Korotkov
2025-04-04 16:01:28 +03:00
parent ee1ae8b99f
commit d48d2e2dc8
3 changed files with 88 additions and 60 deletions

View File

@@ -33,10 +33,8 @@
#include "optimizer/paths.h"
#include "optimizer/prep.h"
#include "optimizer/restrictinfo.h"
#include "utils/array.h"
#include "utils/lsyscache.h"
#include "utils/selfuncs.h"
#include "utils/syscache.h"
/* XXX see PartCollMatchesExprColl */
@@ -3304,7 +3302,6 @@ match_orclause_to_indexcol(PlannerInfo *root,
BoolExpr *orclause = (BoolExpr *) rinfo->orclause;
Node *indexExpr = NULL;
List *consts = NIL;
Node *arrayNode = NULL;
ScalarArrayOpExpr *saopexpr = NULL;
Oid matchOpno = InvalidOid;
IndexClause *iclause;
@@ -3475,63 +3472,8 @@ match_orclause_to_indexcol(PlannerInfo *root,
return NULL;
}
/*
* Assemble an array from the list of constants. It seems more profitable
* to build a const array. But in the presence of other nodes, we don't
* have a specific value here and must employ an ArrayExpr instead.
*/
if (haveNonConst)
{
ArrayExpr *arrayExpr = makeNode(ArrayExpr);
/* array_collid will be set by parse_collate.c */
arrayExpr->element_typeid = consttype;
arrayExpr->array_typeid = arraytype;
arrayExpr->multidims = false;
arrayExpr->elements = consts;
arrayExpr->location = -1;
arrayNode = (Node *) arrayExpr;
}
else
{
int16 typlen;
bool typbyval;
char typalign;
Datum *elems;
int i = 0;
ArrayType *arrayConst;
get_typlenbyvalalign(consttype, &typlen, &typbyval, &typalign);
elems = (Datum *) palloc(sizeof(Datum) * list_length(consts));
foreach_node(Const, value, consts)
{
Assert(!value->constisnull);
elems[i++] = value->constvalue;
}
arrayConst = construct_array(elems, i, consttype,
typlen, typbyval, typalign);
arrayNode = (Node *) makeConst(arraytype, -1, inputcollid,
-1, PointerGetDatum(arrayConst),
false, false);
pfree(elems);
list_free(consts);
}
/* Build the SAOP expression node */
saopexpr = makeNode(ScalarArrayOpExpr);
saopexpr->opno = matchOpno;
saopexpr->opfuncid = get_opcode(matchOpno);
saopexpr->hashfuncid = InvalidOid;
saopexpr->negfuncid = InvalidOid;
saopexpr->useOr = true;
saopexpr->inputcollid = inputcollid;
saopexpr->args = list_make2(indexExpr, arrayNode);
saopexpr->location = -1;
saopexpr = make_SAOP_expr(matchOpno, indexExpr, consttype, inputcollid,
inputcollid, consts, haveNonConst);
/*
* Finally, build an IndexClause based on the SAOP node. Use