Skip to content

Commit 34272f3

Browse files
committed
refactoring, introduce function canonicalize_custom_exprs(), use get_partitioning_clauses() in pathman_rel_pathlist_hook()
1 parent 23625e6 commit 34272f3

File tree

5 files changed

+85
-89
lines changed

5 files changed

+85
-89
lines changed

src/hooks.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,10 +308,10 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
308308
*pathkeyDesc = NULL;
309309
double paramsel = 1.0; /* default part selectivity */
310310
WalkerContext context;
311-
ListCell *lc;
312-
int i;
313311
Node *expr;
314312
bool modify_append_nodes;
313+
ListCell *lc;
314+
int i;
315315

316316
/* Make copy of partitioning expression and fix Var's varno attributes */
317317
expr = PrelExpressionForRelid(prel, rti);
@@ -462,6 +462,12 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
462462
/* Get existing parameterization */
463463
ppi = get_appendrel_parampathinfo(rel, inner_required);
464464

465+
/* Skip if there are no partitioning clauses */
466+
if (!get_partitioning_clauses(list_union(rel->baserestrictinfo,
467+
rel->joininfo),
468+
prel, rti))
469+
return;
470+
465471
if (IsA(cur_path, AppendPath) && pg_pathman_enable_runtimeappend)
466472
inner_path = create_runtimeappend_path(root, cur_path,
467473
ppi, paramsel);

src/include/runtimeappend.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ typedef struct
3838
/* Restrictions to be checked during ReScan and Exec */
3939
List *custom_exprs;
4040

41+
/* Refined clauses for partition pruning */
42+
List *canon_custom_exprs;
43+
4144
/* All available plans \ plan states */
4245
HTAB *children_table;
4346
HASHCTL children_table_config;

src/nodes_common.c

Lines changed: 45 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,41 @@ clause_contains_prel_expr(Node *node, Node *prel_expr)
329329
return expression_tree_walker(node, clause_contains_prel_expr, prel_expr);
330330
}
331331

332+
333+
/* Prepare CustomScan's custom expression for walk_expr_tree() */
334+
static Node *
335+
canonicalize_custom_exprs_mutator(Node *node, void *cxt)
336+
{
337+
if (node == NULL)
338+
return NULL;
339+
340+
if (IsA(node, Var))
341+
{
342+
Var *var = palloc(sizeof(Var));
343+
*var = *(Var *) node;
344+
345+
/* Replace original 'varnoold' */
346+
var->varnoold = INDEX_VAR;
347+
348+
/* Restore original 'varattno' */
349+
var->varattno = var->varoattno;
350+
351+
/* Forget 'location' */
352+
var->location = -1;
353+
354+
return (Node *) var;
355+
}
356+
357+
return expression_tree_mutator(node, canonicalize_custom_exprs_mutator, NULL);
358+
}
359+
360+
static List *
361+
canonicalize_custom_exprs(List *custom_exps)
362+
{
363+
return (List *) canonicalize_custom_exprs_mutator((Node *) custom_exps, NULL);
364+
}
365+
366+
332367
/*
333368
* Filter all available clauses and extract relevant ones.
334369
*/
@@ -603,14 +638,20 @@ create_append_scan_state_common(CustomScan *node,
603638
void
604639
begin_append_common(CustomScanState *node, EState *estate, int eflags)
605640
{
641+
RuntimeAppendState *scan_state = (RuntimeAppendState *) node;
642+
606643
node->ss.ps.ps_TupFromTlist = false;
644+
645+
/* Prepare custom expression according to set_set_customscan_references() */
646+
scan_state->canon_custom_exprs =
647+
canonicalize_custom_exprs(scan_state->custom_exprs);
607648
}
608649

609650
TupleTableSlot *
610651
exec_append_common(CustomScanState *node,
611652
void (*fetch_next_tuple) (CustomScanState *node))
612653
{
613-
RuntimeAppendState *scan_state = (RuntimeAppendState *) node;
654+
RuntimeAppendState *scan_state = (RuntimeAppendState *) node;
614655

615656
/* ReScan if no plans are selected */
616657
if (scan_state->ncur_plans == 0)
@@ -660,51 +701,6 @@ end_append_common(CustomScanState *node)
660701
hash_destroy(scan_state->children_table);
661702
}
662703

663-
/* Find first Var with varno == INDEX_VAR, and returns its varnoold */
664-
static bool
665-
find_varnoold(Node *node, int *varnoold)
666-
{
667-
if (node == NULL)
668-
return false;
669-
670-
if (IsA(node, Var))
671-
{
672-
Var *var = (Var *) node;
673-
if (var->varno == INDEX_VAR)
674-
{
675-
/* we found it */
676-
*varnoold = var->varnoold;
677-
return true;
678-
}
679-
return false;
680-
}
681-
682-
return expression_tree_walker(node, find_varnoold, (void *) varnoold);
683-
}
684-
685-
/*
686-
* To check equality we need to modify partitioning expression's Vars like
687-
* they appear in custom_exprs, it means that varno should be equal to
688-
* INDEX_VAR and varnoold should be changed according to query
689-
*/
690-
static bool
691-
prepare_vars(Node *node, const int *varnoold)
692-
{
693-
if (node == NULL)
694-
return false;
695-
696-
if (IsA(node, Var))
697-
{
698-
Var *var = (Var *) node;
699-
Assert(var->varno == 1);
700-
var->varno = INDEX_VAR;
701-
var->varnoold = *varnoold;
702-
return false;
703-
}
704-
705-
return expression_tree_walker(node, prepare_vars, (void *) varnoold);
706-
}
707-
708704
void
709705
rescan_append_common(CustomScanState *node)
710706
{
@@ -718,28 +714,17 @@ rescan_append_common(CustomScanState *node)
718714
int nparts;
719715
Node *prel_expr;
720716

721-
int varnoold = -100; /* not possible number */
722-
723717
prel = get_pathman_relation_info(scan_state->relid);
724718
Assert(prel);
725719

726-
/* Prepare expression. Copy and modify 'varno' and 'varnoold' attributes */
727-
prel_expr = copyObject(prel->expr);
728-
foreach(lc, scan_state->custom_exprs)
729-
{
730-
find_varnoold((Node *) lfirst(lc), &varnoold);
731-
if (varnoold != -100)
732-
break;
733-
}
734-
735-
if (varnoold != -100)
736-
prepare_vars(prel_expr, &varnoold);
720+
/* Prepare expression according to set_set_customscan_references() */
721+
prel_expr = PrelExpressionForRelid(prel, INDEX_VAR);
737722

738723
/* First we select all available partitions... */
739724
ranges = list_make1_irange_full(prel, IR_COMPLETE);
740725

741726
InitWalkerContext(&wcxt, prel_expr, prel, econtext, false);
742-
foreach (lc, scan_state->custom_exprs)
727+
foreach (lc, scan_state->canon_custom_exprs)
743728
{
744729
WrapperNode *wn;
745730

src/partition_filter.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ make_partition_filter(Plan *subplan, Oid parent_relid,
502502
Node *
503503
partition_filter_create_scan_state(CustomScan *node)
504504
{
505-
PartitionFilterState *state;
505+
PartitionFilterState *state;
506506

507507
state = (PartitionFilterState *) palloc0(sizeof(PartitionFilterState));
508508
NodeSetTag(state, T_CustomScanState);
@@ -531,11 +531,12 @@ partition_filter_create_scan_state(CustomScan *node)
531531
void
532532
partition_filter_begin(CustomScanState *node, EState *estate, int eflags)
533533
{
534-
Index varno = 1;
535-
Node *expr;
536-
MemoryContext old_mcxt;
537534
PartitionFilterState *state = (PartitionFilterState *) node;
535+
536+
MemoryContext old_mcxt;
538537
const PartRelationInfo *prel;
538+
Node *expr;
539+
Index parent_varno = 1;
539540
ListCell *lc;
540541

541542
/* It's convenient to store PlanState in 'custom_ps' */
@@ -548,18 +549,16 @@ partition_filter_begin(CustomScanState *node, EState *estate, int eflags)
548549
Assert(prel != NULL);
549550

550551
/* Change varno in Vars according to range table */
551-
expr = copyObject(prel->expr);
552552
foreach(lc, estate->es_range_table)
553553
{
554554
RangeTblEntry *entry = lfirst(lc);
555+
555556
if (entry->relid == state->partitioned_table)
556-
{
557-
if (varno > 1)
558-
ChangeVarNodes(expr, 1, varno, 0);
559557
break;
560-
}
561-
varno += 1;
558+
559+
parent_varno += 1;
562560
}
561+
expr = PrelExpressionForRelid(prel, parent_varno);
563562

564563
/* Prepare state for expression execution */
565564
old_mcxt = MemoryContextSwitchTo(estate->es_query_cxt);

src/pg_pathman.c

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -712,9 +712,9 @@ wrapper_make_expression(WrapperNode *wrap, int index, bool *alwaysTrue)
712712
static WrapperNode *
713713
handle_const(const Const *c, WalkerContext *context)
714714
{
715+
WrapperNode *result = (WrapperNode *) palloc0(sizeof(WrapperNode));
716+
int strategy = BTEqualStrategyNumber;
715717
const PartRelationInfo *prel = context->prel;
716-
WrapperNode *result = (WrapperNode *) palloc0(sizeof(WrapperNode));
717-
int strategy = BTEqualStrategyNumber;
718718

719719
result->orig = (const Node *) c;
720720

@@ -725,7 +725,7 @@ handle_const(const Const *c, WalkerContext *context)
725725
if (!context->for_insert || c->constisnull)
726726
{
727727
result->rangeset = NIL;
728-
result->paramsel = 1.0;
728+
result->paramsel = 0.0;
729729

730730
return result;
731731
}
@@ -796,18 +796,18 @@ handle_const(const Const *c, WalkerContext *context)
796796
static WrapperNode *
797797
handle_boolexpr(const BoolExpr *expr, WalkerContext *context)
798798
{
799-
WrapperNode *result = (WrapperNode *) palloc0(sizeof(WrapperNode));
800-
ListCell *lc;
799+
WrapperNode *result = (WrapperNode *) palloc0(sizeof(WrapperNode));
800+
ListCell *lc;
801801
const PartRelationInfo *prel = context->prel;
802802

803-
result->orig = (const Node *)expr;
803+
result->orig = (const Node *) expr;
804804
result->args = NIL;
805805
result->paramsel = 1.0;
806806

807-
if (expr->boolop == AND_EXPR)
808-
result->rangeset = list_make1_irange_full(prel, IR_COMPLETE);
809-
else
810-
result->rangeset = NIL;
807+
/* First, set default rangeset */
808+
result->rangeset = (expr->boolop == AND_EXPR) ?
809+
list_make1_irange_full(prel, IR_COMPLETE) :
810+
NIL;
811811

812812
foreach (lc, expr->args)
813813
{
@@ -856,9 +856,9 @@ handle_boolexpr(const BoolExpr *expr, WalkerContext *context)
856856
static WrapperNode *
857857
handle_arrexpr(const ScalarArrayOpExpr *expr, WalkerContext *context)
858858
{
859-
WrapperNode *result = (WrapperNode *) palloc(sizeof(WrapperNode));
860-
Node *exprnode = (Node *) linitial(expr->args);
861-
Node *arraynode = (Node *) lsecond(expr->args);
859+
WrapperNode *result = (WrapperNode *) palloc(sizeof(WrapperNode));
860+
Node *exprnode = (Node *) linitial(expr->args);
861+
Node *arraynode = (Node *) lsecond(expr->args);
862862
const PartRelationInfo *prel = context->prel;
863863

864864
result->orig = (const Node *) expr;
@@ -993,8 +993,8 @@ handle_arrexpr(const ScalarArrayOpExpr *expr, WalkerContext *context)
993993
static WrapperNode *
994994
handle_opexpr(const OpExpr *expr, WalkerContext *context)
995995
{
996-
WrapperNode *result = (WrapperNode *) palloc0(sizeof(WrapperNode));
997-
Node *var, *param;
996+
WrapperNode *result = (WrapperNode *) palloc0(sizeof(WrapperNode));
997+
Node *var, *param;
998998
const PartRelationInfo *prel = context->prel;
999999

10001000
result->orig = (const Node *) expr;
@@ -1006,7 +1006,8 @@ handle_opexpr(const OpExpr *expr, WalkerContext *context)
10061006
{
10071007
if (IsConstValue(context, param))
10081008
{
1009-
handle_binary_opexpr(context, result, var, ExtractConst(context, param));
1009+
handle_binary_opexpr(context, result, var,
1010+
ExtractConst(context, param));
10101011
return result;
10111012
}
10121013
else if (IsA(param, Param) || IsA(param, Var))
@@ -1026,6 +1027,7 @@ handle_opexpr(const OpExpr *expr, WalkerContext *context)
10261027
}
10271028

10281029
/* Binary operator handler */
1030+
/* FIXME: varnode */
10291031
static void
10301032
handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
10311033
const Node *varnode, const Const *c)
@@ -1113,6 +1115,7 @@ handle_binary_opexpr(WalkerContext *context, WrapperNode *result,
11131115
}
11141116

11151117
/* Estimate selectivity of parametrized quals */
1118+
/* FIXME: varnode */
11161119
static void
11171120
handle_binary_opexpr_param(const PartRelationInfo *prel,
11181121
WrapperNode *result, const Node *varnode)
@@ -1460,7 +1463,7 @@ translate_col_privs(const Bitmapset *parent_privs,
14601463
attno = InvalidAttrNumber;
14611464
foreach(lc, translated_vars)
14621465
{
1463-
Var *var = (Var *) lfirst(lc);
1466+
Var *var = (Var *) lfirst(lc);
14641467

14651468
attno++;
14661469
if (var == NULL) /* ignore dropped columns */

0 commit comments

Comments
 (0)