avamingli commented on code in PR #705:
URL: https://github.com/apache/cloudberry/pull/705#discussion_r1867057569
##########
src/backend/optimizer/plan/aqumv.c:
##########
@@ -293,69 +325,195 @@ answer_query_using_materialized_views(PlannerInfo *root,
context = aqumv_init_context(viewQuery->targetList,
matviewRel->rd_att);
- /*
- * Process and rewrite target list, return false if failed.
- */
- if(!aqumv_process_targetlist(context, parse->targetList,
&mv_final_tlist))
+ if (!parse->hasAggs && viewQuery->hasAggs)
continue;
- viewQuery->targetList = mv_final_tlist;
+ if (parse->hasAggs && viewQuery->hasAggs)
+ {
+ if (parse->hasDistinctOn ||
+ parse->distinctClause != NIL ||
+ parse->groupClause != NIL ||
+ parse->groupingSets != NIL ||
+ parse->groupDistinct)
+ continue;
+
+ /* No Group by now. */
+ if (viewQuery->hasDistinctOn ||
+ viewQuery->distinctClause != NIL ||
+ viewQuery->groupClause != NIL ||
+ viewQuery->groupingSets != NIL ||
+ viewQuery->groupDistinct ||
+ viewQuery->havingQual != NULL || /* HAVING
clause is not supported on IMMV yet. */
+ limit_needed(viewQuery)) /* LIMIT, OFFSET is
not supported on IMMV yet. */
+ continue;
- /*
- * NB: Update processed_tlist again in case that tlist has been
changed.
- */
- preprocess_targetlist(subroot);
+ /*
+ * There is a trick for ORDER BY for both origin query
and view query.
+ * As we has no Groupy By here, the aggregation results
would be either one or
+ * zero rows that make the Order By clause pointless.
+ * We could avoid considering the sort columns if it's
a junk for view matching.
+ * This in-place update raw_processed_tlist.
+ */
+ if (parse->sortClause != NIL || viewQuery->sortClause
!= NIL)
+ {
+ ListCell *lc;
+ ListCell *lcc;
+
+ foreach (lc, raw_processed_tlist)
+ {
+ TargetEntry *tle = (TargetEntry *)
lfirst(lc);
+ if (!tle->resjunk || (0 ==
tle->ressortgroupref))
+ continue;
+
+ foreach (lcc, parse->sortClause)
+ {
+ SortGroupClause *srt =
(SortGroupClause *) lfirst(lcc);
+ if (tle->ressortgroupref ==
srt->tleSortGroupRef)
+
foreach_delete_current(raw_processed_tlist, lc);
+ }
+ }
+ /* Earse view's sort caluse, it's ok to let
alone view's target list. */
+ viewQuery->sortClause = NIL;
+ }
- /*
- * We have successfully processed target list, and all columns
in Aggrefs
- * could be computed from viewQuery.
- */
- viewQuery->hasAggs = parse->hasAggs;
- viewQuery->hasDistinctOn = parse->hasDistinctOn;
- /*
- * For HAVING quals have aggregations, we have already
processed them in
- * Aggrefs during aqumv_process_targetlist().
- * For HAVING quals don't have aggregations, they may be pushed
down to
- * jointree's quals and would be processed in post_quals later.
- * Set havingQual before we preprocess_aggrefs for that.
- */
- viewQuery->havingQual = parse->havingQual;
- if (viewQuery->hasAggs)
- {
- preprocess_aggrefs(subroot, (Node *)
subroot->processed_tlist);
- preprocess_aggrefs(subroot, viewQuery->havingQual);
+ /*
+ * Process Limit:
+ * The result would be one row at most.
+ * View may be useful even Limit clause is different,
ex:
+ * View:
+ * create incremental materialized view mv as
+ * select count(*) as mc1 from t;
+ * Query:
+ * select count(*) from t limit 1;
+ * Rewrite to:
+ * select mc1 from mv limit 1;
+ */
+ /* Below logic is based on view has no LIMIT/OFFSET. */
+ Assert(!limit_needed(viewQuery));
+ if (limit_needed(parse))
+ {
+ Node *node;
+ /*
+ * AQUMV don't support sublinks now.
+ * Use query's LIMIT/OFFSET if they are const
in case.
+ */
+ node = parse->limitCount;
+ if (node && !IsA(node, Const))
+ continue;
+
+ node = parse->limitOffset;
+ if (node && !IsA(node, Const))
+ continue;
+
+ viewQuery->limitCount =
copyObject(parse->limitCount);
+ viewQuery->limitOffset =
copyObject(parse->limitOffset);
+ viewQuery->limitOption = parse->limitOption;
+ }
+
+ preprocess_qual_conditions(subroot, (Node *)
viewQuery->jointree);
+
+ if(!aqumv_process_from_quals(parse->jointree->quals,
viewQuery->jointree->quals, &post_quals))
+ continue;
+
+ if (post_quals != NIL)
Review Comment:
We answer `aggregation` query directly, post_quals can't apple then.
##########
src/backend/optimizer/plan/aqumv.c:
##########
@@ -293,69 +325,195 @@ answer_query_using_materialized_views(PlannerInfo *root,
context = aqumv_init_context(viewQuery->targetList,
matviewRel->rd_att);
- /*
- * Process and rewrite target list, return false if failed.
- */
- if(!aqumv_process_targetlist(context, parse->targetList,
&mv_final_tlist))
+ if (!parse->hasAggs && viewQuery->hasAggs)
continue;
- viewQuery->targetList = mv_final_tlist;
+ if (parse->hasAggs && viewQuery->hasAggs)
+ {
+ if (parse->hasDistinctOn ||
+ parse->distinctClause != NIL ||
+ parse->groupClause != NIL ||
+ parse->groupingSets != NIL ||
+ parse->groupDistinct)
+ continue;
+
+ /* No Group by now. */
+ if (viewQuery->hasDistinctOn ||
+ viewQuery->distinctClause != NIL ||
+ viewQuery->groupClause != NIL ||
+ viewQuery->groupingSets != NIL ||
+ viewQuery->groupDistinct ||
+ viewQuery->havingQual != NULL || /* HAVING
clause is not supported on IMMV yet. */
+ limit_needed(viewQuery)) /* LIMIT, OFFSET is
not supported on IMMV yet. */
+ continue;
- /*
- * NB: Update processed_tlist again in case that tlist has been
changed.
- */
- preprocess_targetlist(subroot);
+ /*
+ * There is a trick for ORDER BY for both origin query
and view query.
+ * As we has no Groupy By here, the aggregation results
would be either one or
+ * zero rows that make the Order By clause pointless.
+ * We could avoid considering the sort columns if it's
a junk for view matching.
+ * This in-place update raw_processed_tlist.
+ */
+ if (parse->sortClause != NIL || viewQuery->sortClause
!= NIL)
+ {
+ ListCell *lc;
+ ListCell *lcc;
+
+ foreach (lc, raw_processed_tlist)
+ {
+ TargetEntry *tle = (TargetEntry *)
lfirst(lc);
+ if (!tle->resjunk || (0 ==
tle->ressortgroupref))
+ continue;
+
+ foreach (lcc, parse->sortClause)
+ {
+ SortGroupClause *srt =
(SortGroupClause *) lfirst(lcc);
+ if (tle->ressortgroupref ==
srt->tleSortGroupRef)
+
foreach_delete_current(raw_processed_tlist, lc);
+ }
+ }
+ /* Earse view's sort caluse, it's ok to let
alone view's target list. */
+ viewQuery->sortClause = NIL;
+ }
- /*
- * We have successfully processed target list, and all columns
in Aggrefs
- * could be computed from viewQuery.
- */
- viewQuery->hasAggs = parse->hasAggs;
- viewQuery->hasDistinctOn = parse->hasDistinctOn;
- /*
- * For HAVING quals have aggregations, we have already
processed them in
- * Aggrefs during aqumv_process_targetlist().
- * For HAVING quals don't have aggregations, they may be pushed
down to
- * jointree's quals and would be processed in post_quals later.
- * Set havingQual before we preprocess_aggrefs for that.
- */
- viewQuery->havingQual = parse->havingQual;
- if (viewQuery->hasAggs)
- {
- preprocess_aggrefs(subroot, (Node *)
subroot->processed_tlist);
- preprocess_aggrefs(subroot, viewQuery->havingQual);
+ /*
+ * Process Limit:
+ * The result would be one row at most.
+ * View may be useful even Limit clause is different,
ex:
+ * View:
+ * create incremental materialized view mv as
+ * select count(*) as mc1 from t;
+ * Query:
+ * select count(*) from t limit 1;
+ * Rewrite to:
+ * select mc1 from mv limit 1;
+ */
+ /* Below logic is based on view has no LIMIT/OFFSET. */
+ Assert(!limit_needed(viewQuery));
+ if (limit_needed(parse))
+ {
+ Node *node;
+ /*
+ * AQUMV don't support sublinks now.
+ * Use query's LIMIT/OFFSET if they are const
in case.
+ */
+ node = parse->limitCount;
+ if (node && !IsA(node, Const))
+ continue;
+
+ node = parse->limitOffset;
+ if (node && !IsA(node, Const))
+ continue;
+
+ viewQuery->limitCount =
copyObject(parse->limitCount);
+ viewQuery->limitOffset =
copyObject(parse->limitOffset);
+ viewQuery->limitOption = parse->limitOption;
+ }
+
+ preprocess_qual_conditions(subroot, (Node *)
viewQuery->jointree);
+
+ if(!aqumv_process_from_quals(parse->jointree->quals,
viewQuery->jointree->quals, &post_quals))
+ continue;
+
+ if (post_quals != NIL)
Review Comment:
We answer `aggregation` query directly, post_quals can't apply then.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]