21
21
import org .apache .doris .nereids .trees .expressions .Expression ;
22
22
import org .apache .doris .nereids .trees .expressions .NamedExpression ;
23
23
import org .apache .doris .nereids .trees .expressions .Slot ;
24
+ import org .apache .doris .nereids .trees .expressions .SlotReference ;
24
25
import org .apache .doris .nereids .trees .plans .GroupPlan ;
25
26
import org .apache .doris .nereids .trees .plans .Plan ;
27
+ import org .apache .doris .nereids .trees .plans .RelationId ;
26
28
import org .apache .doris .nereids .trees .plans .logical .LogicalFilter ;
27
29
import org .apache .doris .nereids .trees .plans .logical .LogicalJoin ;
28
30
import org .apache .doris .nereids .trees .plans .logical .LogicalPlan ;
29
31
import org .apache .doris .nereids .trees .plans .logical .LogicalProject ;
30
32
import org .apache .doris .nereids .trees .plans .logical .LogicalRelation ;
31
33
import org .apache .doris .nereids .trees .plans .visitor .DefaultPlanVisitor ;
34
+ import org .apache .doris .nereids .trees .plans .visitor .PlanVisitors ;
35
+ import org .apache .doris .nereids .trees .plans .visitor .PlanVisitors .SlotReferenceReplacer .ExprReplacer ;
32
36
33
37
import com .google .common .collect .BiMap ;
34
38
39
+ import java .util .HashMap ;
40
+ import java .util .HashSet ;
35
41
import java .util .List ;
36
42
import java .util .Map ;
43
+ import java .util .Objects ;
44
+ import java .util .Set ;
37
45
import java .util .stream .Collectors ;
38
46
39
47
/**
@@ -45,26 +53,70 @@ public abstract class AbstractMaterializedViewJoinRule extends AbstractMateriali
45
53
protected Plan rewriteView (MatchMode matchMode ,
46
54
StructInfo queryStructInfo ,
47
55
StructInfo viewStructInfo ,
48
- BiMap <Long , Long > queryToViewTableMappings ,
49
- Plan temporaryRewrite ) {
56
+ BiMap <RelationId , RelationId > queryToViewTableMappings ,
57
+ Plan tempRewritedPlan ) {
50
58
51
59
List <Expression > expressions = rewriteExpression (queryStructInfo .getTopExpressions (),
52
60
queryStructInfo ,
53
61
viewStructInfo ,
54
62
queryToViewTableMappings ,
55
- temporaryRewrite
63
+ tempRewritedPlan
56
64
);
57
65
if (expressions == null ) {
58
66
return queryStructInfo .getPlan ();
59
67
}
60
- // TODO add rewrited project correctly
61
- Map <Slot , Slot > mvOutputSet = temporaryRewrite .getLogicalProperties ().getOutputMap ();
62
- // Simplify implement
63
- List <NamedExpression > namedExpressions = queryStructInfo .getPlan ().getLogicalProperties ().getOutput ()
64
- .stream ()
65
- .map (slot -> (NamedExpression ) mvOutputSet .get (slot ))
66
- .collect (Collectors .toList ());
67
- return new LogicalProject <>(namedExpressions , temporaryRewrite );
68
+ // PoC Generate mapping from query slot reference to mv slot reference, note: clone
69
+ // if any slot can not map then bail out
70
+ // simplfy implement
71
+ Set <SlotReference > querySlotSet = new HashSet <>();
72
+ queryStructInfo .getPlan ().accept (PlanVisitors .SLOT_REFERENCE_COLLECTOR , querySlotSet );
73
+
74
+ Set <SlotReference > viewSlotSet = new HashSet <>();
75
+ viewStructInfo .getPlan ().accept (PlanVisitors .SLOT_REFERENCE_COLLECTOR , viewSlotSet );
76
+
77
+ Map <SlotReference , SlotReference > queryToViewSlotMapping = new HashMap <>();
78
+ for (SlotReference querySlot : querySlotSet ) {
79
+ for (SlotReference viewSlot : viewSlotSet ) {
80
+ if (Objects .equals (querySlot .getName (), viewSlot .getName ())
81
+ && Objects .equals (querySlot .getQualifier (), viewSlot .getQualifier ())) {
82
+ queryToViewSlotMapping .put (querySlot , viewSlot );
83
+ }
84
+ }
85
+ }
86
+ // PoC Generate mapping from mv sql output to mv scan out put
87
+ Map <SlotReference , SlotReference > mvToMvScanMapping = new HashMap <>();
88
+ List <Slot > mvScanSlotList = tempRewritedPlan .getOutput ();
89
+ List <Slot > mvSlotList = viewStructInfo .getPlan ().getOutput ();
90
+ for (int i = 0 ; i < mvSlotList .size (); i ++) {
91
+ mvToMvScanMapping .put ((SlotReference ) mvSlotList .get (i ), (SlotReference ) mvScanSlotList .get (i ));
92
+ }
93
+
94
+ // TODO check if the query expr can derive from the view
95
+ // PoC If the query expression can get from mv sql, so replace the mv scan slot reference
96
+ // PoC according to the mapping above. Simplify implement
97
+ Map <Slot , Slot > mvScanToQueryMapping = new HashMap <>();
98
+ List <Slot > output = queryStructInfo .getPlan ().getOutput ();
99
+ for (Slot querySlot : output ) {
100
+ Slot mvSlot = queryToViewSlotMapping .get (querySlot );
101
+ if (mvSlot == null ) {
102
+ return null ;
103
+ }
104
+ SlotReference mvScanSlot = mvToMvScanMapping .get (mvSlot );
105
+ if (mvScanSlot == null ) {
106
+ return null ;
107
+ }
108
+ mvScanToQueryMapping .put (mvScanSlot , querySlot );
109
+ }
110
+ // Replace the mv scan output with query slot, lazy before add filter and other project
111
+
112
+ // tempRewritedPlan.accept(SlotReferenceReplacer.INSTANCE, mvScanToQueryMapping);
113
+
114
+ tempRewritedPlan .getOutput ().stream ()
115
+ .forEach (slot -> slot .accept (ExprReplacer .INSTANCE , mvScanToQueryMapping ));
116
+ LogicalProject <Plan > planLogicalProject = new LogicalProject <>(
117
+ output .stream ().map (NamedExpression .class ::cast ).collect (Collectors .toList ()),
118
+ tempRewritedPlan );
119
+ return planLogicalProject ;
68
120
}
69
121
70
122
protected boolean isPatternSupport (LogicalProject topProject , Plan plan ) {
0 commit comments