Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AQUMV] Expose the function adjust view query and varno fix. #469

Merged
merged 1 commit into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 109 additions & 101 deletions src/backend/optimizer/plan/aqumv.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "catalog/pg_inherits.h"
#include "catalog/pg_rewrite.h"
#include "cdb/cdbllize.h"
#include "optimizer/aqumv.h"
#include "optimizer/optimizer.h"
#include "optimizer/planmain.h"
#include "optimizer/planner.h"
Expand Down Expand Up @@ -50,6 +51,7 @@ typedef struct
int varno;
} aqumv_adjust_varno_context;

extern void aqumv_adjust_simple_query(Query *viewQuery);
static bool aqumv_process_from_quals(Node *query_quals, Node *mv_quals, List** post_quals);
static void aqumv_adjust_varno(Query *parse, int delta);
static Node *aqumv_adjust_varno_mutator(Node *node, aqumv_adjust_varno_context *context);
Expand Down Expand Up @@ -92,7 +94,6 @@ answer_query_using_materialized_views(PlannerInfo *root,
Query *parse = root->parse; /* Query of origin SQL. */
Query *viewQuery; /* Query of view. */
RelOptInfo *mv_final_rel = current_rel; /* Final rel after rewritten. */
ListCell *lc;
Node *jtnode;
Node *mvjtnode;
int varno;
Expand Down Expand Up @@ -270,35 +271,8 @@ answer_query_using_materialized_views(PlannerInfo *root,
subroot->tuple_fraction = root->tuple_fraction;
subroot->limit_tuples = root->limit_tuples;

/*
* AQUMV
* We have to rewrite now before we do the real Equivalent
* Transformation 'rewrite'.
* Because actions sotored in rule is not a normal query tree,
* it can't be used directly, ex: new/old realtions used to
* refresh mv.
* Earse unused relatoins, keep the right one.
*/
foreach(lc, viewQuery->rtable)
{
RangeTblEntry* rtetmp = lfirst(lc);
if ((rtetmp->relkind == RELKIND_MATVIEW) &&
(rtetmp->alias != NULL) &&
(strcmp(rtetmp->alias->aliasname, "new") == 0 ||
strcmp(rtetmp->alias->aliasname,"old") == 0))
{
foreach_delete_current(viewQuery->rtable, lc);
}
}

/*
* Now we have the right relation, adjust
* varnos in its query tree.
* AQUMV_FIXME_MVP: Only one single relation
* is supported now, we could assign varno
* to 1 opportunistically.
*/
aqumv_adjust_varno(viewQuery, 1);
/* Adjust to valid query tree and fix varno after rewrite.*/
aqumv_adjust_simple_query(viewQuery);

/*
* AQUMV_FIXME_MVP
Expand Down Expand Up @@ -500,77 +474,6 @@ aqumv_init_context(List *view_tlist, TupleDesc mv_tupledesc)
return context;
}

/*
* Process varno after we eliminate mv's actions("old" and "new" relation)
* Correct rindex and all varnos with a delta.
*
* MV's actions query tree:
* [rtable]
* RangeTblEntry [rtekind=RTE_RELATION]
* [alias] Alias [aliasname="old"]
* RangeTblEntry [rtekind=RTE_RELATION]
* [alias] Alias [aliasname="new"]
* RangeTblEntry [rtekind=RTE_RELATION]
* [jointree]
* FromExpr []
* [fromlist]
* RangeTblRef [rtindex=3]
* [targetList]
* TargetEntry [resno=1 resname="c1"]
* Var [varno=3 varattno=1]
* TargetEntry [resno=2 resname="c2"]
* Var [varno=3 varattno=2]
*------------------------------------------------------------------------------------------
* MV's query tree after rewrite:
* [rtable]
* RangeTblEntry [rtekind=RTE_RELATION]
* [jointree]
* FromExpr []
* [fromlist]
* RangeTblRef [rtindex=3]
* [targetList]
* TargetEntry [resno=1 resname="c1"]
* Var [varno=3 varattno=1]
* TargetEntry [resno=2 resname="c2"]
* Var [varno=3 varattno=2]
*------------------------------------------------------------------------------------------
* MV's query tree after varno adjust:
* [rtable]
* RangeTblEntry [rtekind=RTE_RELATION]
* [jointree]
* FromExpr []
* [fromlist]
* RangeTblRef [rtindex=1]
* [targetList]
* TargetEntry [resno=1 resname="c1"]
* Var [varno=1 varattno=1]
* TargetEntry [resno=2 resname="c2"]
* Var [varno=1 varattno=2]
*
*/
static void
aqumv_adjust_varno(Query* parse, int varno)
{
aqumv_adjust_varno_context context;
context.varno = varno;
parse = query_tree_mutator(parse, aqumv_adjust_varno_mutator, &context, QTW_DONT_COPY_QUERY);
}

/*
* Adjust varno and rindex with delta.
*/
static Node *aqumv_adjust_varno_mutator(Node *node, aqumv_adjust_varno_context *context)
{
if (node == NULL)
return NULL;
if (IsA(node, Var))
((Var *)node)->varno = context->varno;
else if (IsA(node, RangeTblRef))
/* AQUMV_FIXME_MVP: currently we have only one relation */
((RangeTblRef*) node)->rtindex = context->varno;
return expression_tree_mutator(node, aqumv_adjust_varno_mutator, context);
}

/*
* Compute a node complexity recursively.
* Complexity of a node is the total times we enter walker function after all
Expand Down Expand Up @@ -806,3 +709,108 @@ aqumv_process_targetlist(aqumv_equivalent_transformation_context *context, List

return !context->has_unmatched;
}

void aqumv_adjust_simple_query(Query *viewQuery)
{
ListCell *lc;
/*
* AQUMV
* We have to rewrite now before we do the real Equivalent
* Transformation 'rewrite'.
* Because actions sotored in rule is not a normal query tree,
* it can't be used directly, ex: new/old realtions used to
* refresh mv.
* Earse unused relatoins, keep the right one.
*/
foreach (lc, viewQuery->rtable)
{
RangeTblEntry *rtetmp = lfirst(lc);
if ((rtetmp->relkind == RELKIND_MATVIEW) &&
(rtetmp->alias != NULL) &&
(strcmp(rtetmp->alias->aliasname, "new") == 0 ||
strcmp(rtetmp->alias->aliasname, "old") == 0))
{
foreach_delete_current(viewQuery->rtable, lc);
}
}

/*
* Now we have the right relation, adjust
* varnos in its query tree.
* AQUMV_FIXME_MVP: Only one single relation
* is supported now, we could assign varno
* to 1 opportunistically.
*/
aqumv_adjust_varno(viewQuery, 1);
}

/*
* Process varno after we eliminate mv's actions("old" and "new" relation)
* Correct rindex and all varnos with a delta.
*
* MV's actions query tree:
* [rtable]
* RangeTblEntry [rtekind=RTE_RELATION]
* [alias] Alias [aliasname="old"]
* RangeTblEntry [rtekind=RTE_RELATION]
* [alias] Alias [aliasname="new"]
* RangeTblEntry [rtekind=RTE_RELATION]
* [jointree]
* FromExpr []
* [fromlist]
* RangeTblRef [rtindex=3]
* [targetList]
* TargetEntry [resno=1 resname="c1"]
* Var [varno=3 varattno=1]
* TargetEntry [resno=2 resname="c2"]
* Var [varno=3 varattno=2]
*------------------------------------------------------------------------------------------
* MV's query tree after rewrite:
* [rtable]
* RangeTblEntry [rtekind=RTE_RELATION]
* [jointree]
* FromExpr []
* [fromlist]
* RangeTblRef [rtindex=3]
* [targetList]
* TargetEntry [resno=1 resname="c1"]
* Var [varno=3 varattno=1]
* TargetEntry [resno=2 resname="c2"]
* Var [varno=3 varattno=2]
*------------------------------------------------------------------------------------------
* MV's query tree after varno adjust:
* [rtable]
* RangeTblEntry [rtekind=RTE_RELATION]
* [jointree]
* FromExpr []
* [fromlist]
* RangeTblRef [rtindex=1]
* [targetList]
* TargetEntry [resno=1 resname="c1"]
* Var [varno=1 varattno=1]
* TargetEntry [resno=2 resname="c2"]
* Var [varno=1 varattno=2]
*
*/
static void
aqumv_adjust_varno(Query* parse, int varno)
{
aqumv_adjust_varno_context context;
context.varno = varno;
parse = query_tree_mutator(parse, aqumv_adjust_varno_mutator, &context, QTW_DONT_COPY_QUERY);
}

static Node *aqumv_adjust_varno_mutator(Node *node, aqumv_adjust_varno_context *context)
{
if (node == NULL)
return NULL;
if (IsA(node, Var))
{
((Var *)node)->varno = context->varno;
((Var *)node)->varnosyn = context->varno; /* Keep syntactic with varno. */
}
else if (IsA(node, RangeTblRef))
/* AQUMV_FIXME_MVP: currently we have only one relation */
((RangeTblRef*) node)->rtindex = context->varno;
return expression_tree_mutator(node, aqumv_adjust_varno_mutator, context);
}
26 changes: 26 additions & 0 deletions src/include/optimizer/aqumv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*-------------------------------------------------------------------------
*
* aqumv.h
* prototypes for optimizer/plan/aqumv.c.
*
* Portions Copyright (c) 2024, HashData Technology Limited.
*
* Author: Zhang Mingli <avamingli@gmail.com>
*
* src/include/optimizer/aqumv.h
*
*-------------------------------------------------------------------------
*/
#ifndef AQUMV_H
#define AQUMV_H

#include "nodes/parsenodes.h"

/*
* Adjust parse tree storaged in view's actions.
* Query should be a simple query, ex:
* select from a single table.
*/
extern void aqumv_adjust_simple_query(Query *viewQuery);

#endif /* AQUMV_H */
Loading