v18-0001-Minor-miscellaneous-refactor-based-on-v18.no-cfbot

application/octet-stream

Filename: v18-0001-Minor-miscellaneous-refactor-based-on-v18.no-cfbot
Type: application/octet-stream
Part: 0
Message: Re: POC, WIP: OR-clause support for indexes
From b57b1701ab8fe3e319ba5a7cd190fe04ca2696e0 Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Mon, 4 Mar 2024 10:18:12 +0800
Subject: [PATCH v18 1/1] Minor miscellaneous refactor based on v18.

---
 src/backend/optimizer/path/indxpath.c | 11 ++++----
 src/backend/parser/parse_expr.c       | 40 +++++++++++++++------------
 2 files changed, 27 insertions(+), 24 deletions(-)

diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 47bf5382..a7758df6 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -1284,7 +1284,7 @@ build_paths_for_SAOP(PlannerInfo *root, RelOptInfo *rel, RestrictInfo *rinfo,
 		ArrayType		   *arrayval = NULL;
 		ArrayExpr		   *arr = NULL;
 		Const			   *arrayconst;
-		ScalarArrayOpExpr	dest;
+		ScalarArrayOpExpr  *dest = NULL;
 
 		pd = (PredicatesData *) lfirst(lc);
 		if (pd->elems == NIL)
@@ -1295,6 +1295,7 @@ build_paths_for_SAOP(PlannerInfo *root, RelOptInfo *rel, RestrictInfo *rinfo,
 		arrayconst = lsecond_node(Const, saop->args);
 		arrayval = DatumGetArrayTypeP(arrayconst->constvalue);
 		arr = makeNode(ArrayExpr);
+		dest = makeNode(ScalarArrayOpExpr);
 		arr->array_collid = arrayconst->constcollid;
 		arr->array_typeid = arrayconst->consttype;
 		arr->element_typeid = arrayval->elemtype;
@@ -1303,10 +1304,10 @@ build_paths_for_SAOP(PlannerInfo *root, RelOptInfo *rel, RestrictInfo *rinfo,
 		arr->multidims = false;
 
 		/* Compose new SAOP, partially covering the source one */
-		memcpy(&dest, saop, sizeof(ScalarArrayOpExpr));
-		dest.args = list_make2(linitial(saop->args), arr);
+		memcpy(dest, saop, sizeof(ScalarArrayOpExpr));
+		dest->args = list_make2(linitial(saop->args), arr);
 
-		clause = (Expr *) estimate_expression_value(root, (Node *) &dest);
+		clause = (Expr *) estimate_expression_value(root, (Node *) dest);
 
 		/*
 		 * Create new RestrictInfo. It maybe more heavy than just copy node,
@@ -1330,13 +1331,11 @@ build_paths_for_SAOP(PlannerInfo *root, RelOptInfo *rel, RestrictInfo *rinfo,
 		Assert(!predicate_implied_by(index->indpred, other_clauses, false));
 
 		/* Time to generate index paths */
-
 		MemSet(&clauseset, 0, sizeof(clauseset));
 		match_clauses_to_index(root, list_make1(rinfo1), index, &clauseset);
 		match_clauses_to_index(root, other_clauses, index, &clauseset);
 
 		/* Predicate has found already. So, it is ok for the empty match */
-
 		indexpaths = build_index_paths(root, rel,
 									   index, &clauseset,
 									   true,
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 10ceccc8..8a7432a4 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -169,23 +169,29 @@ orclause_match(const void *data1, const void *data2, Size keysize)
 }
 
 /*
- * TransformOrExprToANY -
- *	  Discover the args of an OR expression and try to group similar OR
- *	  expressions to an ANY operation.
- *	  Transformation must be already done on input args list before the call.
- *	  Transformation groups two-sided equality operations. One side of such an
- *	  operation must be plain constant or constant expression. The other side of
- *	  the clause must be a variable expression without volatile functions.
- *	  The grouping technique is based on the similarity of variable sides of the
- *	  expression: using queryId and equal() routine, it groups constant sides of
- *	  similar clauses into an array. After the grouping procedure, each couple
- *	  ('variable expression' and 'constant array') form a new SAOP operation,
- *	  which is added to the args list of the returning expression.
+ * TransformOrExprToANY
+ * Discover the args of an OR expression and try to group similar OR
+ * expressions to an ANY operation.
  *
- *	  NOTE: function returns OR BoolExpr if more than one clause are detected in
- *	  the final args list, or ScalarArrayOpExpr if all args were grouped into
- *	  the single SAOP expression.
- */
+ * Transformation must be already done on input args list before the call.
+ * Transformation groups mulitple OR expressions
+ * (i.e. ExpressionA OR ExpressionB) into a SAOP expression. For each single
+ * expression, one side of such an expression must be a plain constant or
+ * constant expression. The other side of the expression must be a variable
+ * expression without volatile functions.
+ *
+ * The grouping technique is based on the sameness of the expression's variable
+ * side. We use variable sides expression's hash key comparison function and
+ * hash routine to evaulate the sameness. Iff the variable side is the same,
+ * then we groups multiple expression's constant into an array.
+ * After the grouping procedure, each couple
+ * ('variable expression' and 'constant array') form a new SAOP expression,
+ * which is added to the args list of the returning expression.
+ *
+ * NOTE: function returns OR BoolExpr if more than one clause are detected in
+ * the final args list, or ScalarArrayOpExpr if all args were grouped into
+ * the single SAOP expression.
+*/
 static Node *
 TransformOrExprToANY(ParseState *pstate, List *args, int location)
 {
@@ -328,7 +334,6 @@ TransformOrExprToANY(ParseState *pstate, List *args, int location)
 	 * Go through the list of groups and convert each, where number of
 	 * consts more than 1. trivial groups move to OR-list again
 	 */
-
 	foreach (lc, entries)
 	{
 		Oid				    scalar_type;
@@ -353,7 +358,6 @@ TransformOrExprToANY(ParseState *pstate, List *args, int location)
 		/*
 		 * Do the transformation.
 		 */
-
 		scalar_type = entry->key.exprtype;
 		array_type = OidIsValid(scalar_type) ? get_array_type(scalar_type) :
 											   InvalidOid;
-- 
2.34.1