fanfuxiaoran commented on code in PR #705:
URL: https://github.com/apache/cloudberry/pull/705#discussion_r1867108142


##########
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:
   Got it . Exactly, the `post_quals` cannot apply on the agg result.
   Thanks for your explanation ,



-- 
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]

Reply via email to