Skip to content

Commit 3c1f29a

Browse files
avaminglimy-ship-it
authored andcommitted
[AQUMV] Refactor view query target list process.
Before this commit, we separate view query's targetlist into pure_vars and no_pure_vars. This is used to match sub expression for Greedy Algorithm with special order. However, we could combine all that expression into one list expcet those have no vars. The more complex expression is, the higher order is. And pure vars is guaranteed to be later in order. Fix some fields lost of TargetEntry by the way. Authored-by: Zhang Mingli avamingli@gmail.com
1 parent 1b13352 commit 3c1f29a

1 file changed

Lines changed: 25 additions & 61 deletions

File tree

src/backend/optimizer/plan/aqumv.c

Lines changed: 25 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,15 @@ static Node *aqumv_adjust_varno_mutator(Node *node, aqumv_adjust_varno_context *
5858

5959
typedef struct
6060
{
61-
List *mv_pure_vars_index; /* Index list of pure Vars. */
62-
List *mv_nonpure_vars_index; /* Index list of nonpure Vars. */
6361
List *mv_query_tlist; /* view query's target list. */
62+
List *mv_tlist_ordered_index; /* Index list by complexity order. */
6463
TupleDesc mv_tupledesc; /* mv relation's tuple desc. */
6564
bool has_unmatched; /* True if we fail to rewrite an expression. */
6665
} aqumv_equivalent_transformation_context;
6766

6867
static aqumv_equivalent_transformation_context* aqumv_init_context(List *view_tlist, TupleDesc mv_tupledesc);
6968
static bool aqumv_process_targetlist(aqumv_equivalent_transformation_context *context, List *query_tlist, List **mv_final_tlist);
70-
static void aqumv_process_nonpure_vars_expr(aqumv_equivalent_transformation_context* context);
69+
static void aqumv_sort_targetlist(aqumv_equivalent_transformation_context* context);
7170
static Node *aqumv_adjust_sub_matched_expr_mutator(Node *node, aqumv_equivalent_transformation_context *context);
7271

7372
typedef struct
@@ -290,9 +289,6 @@ answer_query_using_materialized_views(PlannerInfo *root,
290289

291290
context = aqumv_init_context(viewQuery->targetList, matviewRel->rd_att);
292291

293-
/* Sort nonpure vars expression, prepare for Greedy Algorithm. */
294-
aqumv_process_nonpure_vars_expr(context);
295-
296292
/*
297293
* Process and rewrite target list, return false if failed.
298294
*/
@@ -444,8 +440,6 @@ static aqumv_equivalent_transformation_context*
444440
aqumv_init_context(List *view_tlist, TupleDesc mv_tupledesc)
445441
{
446442
aqumv_equivalent_transformation_context *context = palloc0(sizeof(aqumv_equivalent_transformation_context));
447-
List *mv_pure_vars_index = NIL; /* Index of TargetEntry[Var] in view query. */
448-
List *mv_nonpure_vars_index = NIL; /* Index of nonpure[Var] expression in view query. */
449443
ListCell *lc;
450444

451445
/*
@@ -465,17 +459,16 @@ aqumv_init_context(List *view_tlist, TupleDesc mv_tupledesc)
465459
if(!contain_var_clause((Node*)tle))
466460
continue;
467461

468-
if (IsA(tle->expr, Var))
469-
mv_pure_vars_index = lappend_int(mv_pure_vars_index, i);
470-
else
471-
mv_nonpure_vars_index = lappend_int(mv_nonpure_vars_index, i);
462+
/* To be sorted later */
463+
context->mv_tlist_ordered_index = lappend_int(context->mv_tlist_ordered_index, i);
472464
}
473465

474-
context->mv_pure_vars_index = mv_pure_vars_index;
475-
context->mv_nonpure_vars_index = mv_nonpure_vars_index;
476466
context->mv_tupledesc = mv_tupledesc;
477467
context->mv_query_tlist = view_tlist;
478468
context->has_unmatched = false;
469+
470+
/* Sort target list expressions, prepare for Greedy Algorithm. */
471+
aqumv_sort_targetlist(context);
479472
return context;
480473
}
481474

@@ -503,14 +496,14 @@ nonpure_vars_expr_compare(const ListCell *a, const ListCell *b)
503496
}
504497

505498
/*
506-
* In-place update order of mv_nonpure_vars_index List
499+
* In-place update order of mv_tlist_ordered_index List
507500
*/
508501
static void
509-
aqumv_process_nonpure_vars_expr(aqumv_equivalent_transformation_context* context)
502+
aqumv_sort_targetlist(aqumv_equivalent_transformation_context* context)
510503
{
511504
ListCell* lc;
512505
List *expr_to_sort_list = NIL;
513-
foreach(lc, context->mv_nonpure_vars_index)
506+
foreach(lc, context->mv_tlist_ordered_index)
514507
{
515508
int index = lfirst_int(lc);
516509
Node *expr = lfirst(list_nth_cell(context->mv_query_tlist, index));
@@ -524,13 +517,14 @@ aqumv_process_nonpure_vars_expr(aqumv_equivalent_transformation_context* context
524517

525518
/* Sort the expr list */
526519
list_sort(expr_to_sort_list, nonpure_vars_expr_compare);
527-
/* Reorder mv_nonpure_vars_index */
528-
context->mv_nonpure_vars_index = NIL;
520+
/* Reorder */
521+
context->mv_tlist_ordered_index = NIL;
529522
foreach(lc, expr_to_sort_list)
530523
{
531524
expr_to_sort *ets = (expr_to_sort *) lfirst(lc);
532-
context->mv_nonpure_vars_index = lappend_int(context->mv_nonpure_vars_index, ets->tlist_index);
525+
context->mv_tlist_ordered_index = lappend_int(context->mv_tlist_ordered_index, ets->tlist_index);
533526
}
527+
list_free_deep(expr_to_sort_list);
534528
return;
535529
}
536530

@@ -606,7 +600,7 @@ static Node *aqumv_adjust_sub_matched_expr_mutator(Node *node, aqumv_equivalent_
606600
return is_targetEntry ? node : (Node *)node_expr;
607601

608602
ListCell *lc = NULL;
609-
foreach(lc, context->mv_nonpure_vars_index)
603+
foreach(lc, context->mv_tlist_ordered_index)
610604
{
611605
int index = lfirst_int(lc);
612606
TargetEntry *tle = list_nth_node(TargetEntry, context->mv_query_tlist, index);
@@ -618,17 +612,12 @@ static Node *aqumv_adjust_sub_matched_expr_mutator(Node *node, aqumv_equivalent_
618612
attr->atttypid,
619613
attr->atttypmod,
620614
attr->attcollation,
621-
0 /* AQUMV_FIXME_MVP: no subquery. */);
622-
newVar->location = -2; /* hack here, use -2 to indicate already rewrited by mv rel Vars. */
615+
0 /* AQUMV_FIXME_MVP: consider subquery? */);
616+
newVar->location = -1;
623617
if (is_targetEntry)
624618
{
625-
TargetEntry *qtle = (TargetEntry *) node;
626-
/*
627-
* AQUMV_FIXME_MVP:
628-
* resorigtbl, resorigcol, resjunck in viewQuery is also rejunck in mv table itself ?
629-
*/
630-
TargetEntry *mvtle = makeTargetEntry((Expr *)newVar, qtle->resno, qtle->resname, qtle->resjunk);
631-
return (Node *) mvtle;
619+
((TargetEntry *) node)->expr = (Expr*) newVar;
620+
return node;
632621
}
633622
else
634623
return (Node *) newVar;
@@ -642,39 +631,14 @@ static Node *aqumv_adjust_sub_matched_expr_mutator(Node *node, aqumv_equivalent_
642631
*/
643632
if (!contain_var_clause((Node *)node_expr))
644633
return is_targetEntry ? node : (Node *)node_expr;
645-
646-
/* Try match with mv_pure_vars_index, but do not disturb already rewrited exprs(Var->location = -2) */
647-
if (IsA(node_expr, Var))
648-
{
649-
Var *var = (Var *)node_expr;
650-
if (var->location == -2)
651-
return node;
652634

653-
lc = NULL;
654-
foreach(lc, context->mv_pure_vars_index)
655-
{
656-
int index = lfirst_int(lc);
657-
TargetEntry *tle = list_nth_node(TargetEntry, context->mv_query_tlist, index);
658-
if (equal(node_expr, tle->expr))
659-
{
660-
Form_pg_attribute attr = TupleDescAttr(context->mv_tupledesc, index);
661-
Var *newVar = makeVar(1, /* AQUMV_FIXME_MVP: single relation */
662-
attr->attnum,
663-
attr->atttypid,
664-
attr->atttypmod,
665-
attr->attcollation,
666-
0 /* AQUMV_FIXME_MVP: no subquery. */);
667-
if (is_targetEntry)
668-
{
669-
((TargetEntry *)node)->expr = (Expr *)newVar;
670-
return node;
671-
}
672-
else
673-
return (Node *)newVar;
674-
}
675-
}
635+
/*
636+
* Failed to rewrite.
637+
* We have walked through all exprs in mv_tlist_ordered_index,
638+
* but didn't find a match for Var at leaf nodes.
639+
*/
640+
if (IsA(node_expr, Var))
676641
context->has_unmatched = true;
677-
}
678642

679643
return expression_tree_mutator(node, aqumv_adjust_sub_matched_expr_mutator, context);
680644
}

0 commit comments

Comments
 (0)