@@ -106,15 +106,16 @@ public class StructInfo {
106
106
// this is for LogicalCompatibilityContext later
107
107
private final Map <RelationId , StructInfoNode > relationIdStructInfoNodeMap ;
108
108
// this recorde the predicates which can pull up, not shuttled
109
- private Predicates predicates ;
109
+ private final Predicates predicates ;
110
110
// split predicates is shuttled
111
- private final SplitPredicate splitPredicate ;
112
- private final EquivalenceClass equivalenceClass ;
111
+ private SplitPredicate splitPredicate ;
112
+ private EquivalenceClass equivalenceClass ;
113
113
// Key is the expression shuttled and the value is the origin expression
114
114
// this is for building LogicalCompatibilityContext later.
115
115
private final Map <ExpressionPosition , Map <Expression , Expression >> shuttledExpressionsToExpressionsMap ;
116
116
// Record the exprId and the corresponding expr map, this is used by expression shuttled
117
117
private final Map <ExprId , Expression > namedExprIdAndExprMapping ;
118
+ private final List <? extends Expression > planOutputShuttledExpressions ;
118
119
119
120
/**
120
121
* The construct method for StructInfo
@@ -125,30 +126,25 @@ private StructInfo(Plan originalPlan, ObjectId originalPlanId, HyperGraph hyperG
125
126
@ Nullable Predicates predicates ,
126
127
Map <ExpressionPosition , Map <Expression , Expression >> shuttledExpressionsToExpressionsMap ,
127
128
Map <ExprId , Expression > namedExprIdAndExprMapping ,
128
- BitSet tableIdSet ) {
129
+ BitSet tableIdSet ,
130
+ SplitPredicate splitPredicate ,
131
+ EquivalenceClass equivalenceClass ,
132
+ List <? extends Expression > planOutputShuttledExpressions ) {
129
133
this .originalPlan = originalPlan ;
130
134
this .originalPlanId = originalPlanId ;
131
135
this .hyperGraph = hyperGraph ;
132
- this .valid = valid
133
- && hyperGraph .getNodes ().stream ().allMatch (n -> ((StructInfoNode ) n ).getExpressions () != null );
136
+ this .valid = valid ;
134
137
this .topPlan = topPlan ;
135
138
this .bottomPlan = bottomPlan ;
136
139
this .relations = relations ;
137
140
this .tableBitSet = tableIdSet ;
138
141
this .relationIdStructInfoNodeMap = relationIdStructInfoNodeMap ;
139
142
this .predicates = predicates ;
140
- if (predicates == null ) {
141
- // collect predicate from top plan which not in hyper graph
142
- Set <Expression > topPlanPredicates = new LinkedHashSet <>();
143
- topPlan .accept (PREDICATE_COLLECTOR , topPlanPredicates );
144
- this .predicates = Predicates .of (topPlanPredicates );
145
- }
146
- Pair <SplitPredicate , EquivalenceClass > derivedPredicates =
147
- predicatesDerive (this .predicates , topPlan , tableBitSet );
148
- this .splitPredicate = derivedPredicates .key ();
149
- this .equivalenceClass = derivedPredicates .value ();
143
+ this .splitPredicate = splitPredicate ;
144
+ this .equivalenceClass = equivalenceClass ;
150
145
this .shuttledExpressionsToExpressionsMap = shuttledExpressionsToExpressionsMap ;
151
146
this .namedExprIdAndExprMapping = namedExprIdAndExprMapping ;
147
+ this .planOutputShuttledExpressions = planOutputShuttledExpressions ;
152
148
}
153
149
154
150
/**
@@ -157,7 +153,8 @@ private StructInfo(Plan originalPlan, ObjectId originalPlanId, HyperGraph hyperG
157
153
public StructInfo withPredicates (Predicates predicates ) {
158
154
return new StructInfo (this .originalPlan , this .originalPlanId , this .hyperGraph , this .valid , this .topPlan ,
159
155
this .bottomPlan , this .relations , this .relationIdStructInfoNodeMap , predicates ,
160
- this .shuttledExpressionsToExpressionsMap , this .namedExprIdAndExprMapping , this .tableBitSet );
156
+ this .shuttledExpressionsToExpressionsMap , this .namedExprIdAndExprMapping , this .tableBitSet ,
157
+ null , null , this .planOutputShuttledExpressions );
161
158
}
162
159
163
160
/**
@@ -166,7 +163,8 @@ public StructInfo withPredicates(Predicates predicates) {
166
163
public StructInfo withTableBitSet (BitSet tableBitSet ) {
167
164
return new StructInfo (this .originalPlan , this .originalPlanId , this .hyperGraph , this .valid , this .topPlan ,
168
165
this .bottomPlan , this .relations , this .relationIdStructInfoNodeMap , this .predicates ,
169
- this .shuttledExpressionsToExpressionsMap , this .namedExprIdAndExprMapping , tableBitSet );
166
+ this .shuttledExpressionsToExpressionsMap , this .namedExprIdAndExprMapping , tableBitSet ,
167
+ this .splitPredicate , this .equivalenceClass , this .planOutputShuttledExpressions );
170
168
}
171
169
172
170
private static boolean collectStructInfoFromGraph (HyperGraph hyperGraph ,
@@ -252,11 +250,10 @@ private static boolean collectStructInfoFromGraph(HyperGraph hyperGraph,
252
250
}
253
251
254
252
// derive some useful predicate by predicates
255
- private Pair <SplitPredicate , EquivalenceClass > predicatesDerive (Predicates predicates , Plan originalPlan ,
256
- BitSet tableBitSet ) {
253
+ private static Pair <SplitPredicate , EquivalenceClass > predicatesDerive (Predicates predicates , Plan originalPlan ) {
257
254
// construct equivalenceClass according to equals predicates
258
255
List <Expression > shuttledExpression = ExpressionUtils .shuttleExpressionWithLineage (
259
- new ArrayList <>(predicates .getPulledUpPredicates ()), originalPlan , tableBitSet ).stream ()
256
+ new ArrayList <>(predicates .getPulledUpPredicates ()), originalPlan , new BitSet () ).stream ()
260
257
.map (Expression .class ::cast )
261
258
.collect (Collectors .toList ());
262
259
SplitPredicate splitPredicate = Predicates .splitPredicates (ExpressionUtils .and (shuttledExpression ));
@@ -328,9 +325,19 @@ public static StructInfo of(Plan originalPlan, @Nullable Plan topPlan, @Nullable
328
325
relationIdStructInfoNodeMap ,
329
326
tableBitSet ,
330
327
cascadesContext );
328
+ valid = valid
329
+ && hyperGraph .getNodes ().stream ().allMatch (n -> ((StructInfoNode ) n ).getExpressions () != null );
330
+ // collect predicate from top plan which not in hyper graph
331
+ Set <Expression > topPlanPredicates = new LinkedHashSet <>();
332
+ topPlan .accept (PREDICATE_COLLECTOR , topPlanPredicates );
333
+ Predicates predicates = Predicates .of (topPlanPredicates );
334
+ // this should use the output of originalPlan to make sure the output right order
335
+ List <? extends Expression > planOutputShuttledExpressions =
336
+ ExpressionUtils .shuttleExpressionWithLineage (originalPlan .getOutput (), originalPlan , new BitSet ());
331
337
return new StructInfo (originalPlan , originalPlanId , hyperGraph , valid , topPlan , bottomPlan ,
332
- relationList , relationIdStructInfoNodeMap , null , shuttledHashConjunctsToConjunctsMap ,
333
- namedExprIdAndExprMapping , tableBitSet );
338
+ relationList , relationIdStructInfoNodeMap , predicates , shuttledHashConjunctsToConjunctsMap ,
339
+ namedExprIdAndExprMapping , tableBitSet , null , null ,
340
+ planOutputShuttledExpressions );
334
341
}
335
342
336
343
/**
@@ -350,10 +357,6 @@ public Predicates getPredicates() {
350
357
return predicates ;
351
358
}
352
359
353
- public EquivalenceClass getEquivalenceClass () {
354
- return equivalenceClass ;
355
- }
356
-
357
360
public Plan getOriginalPlan () {
358
361
return originalPlan ;
359
362
}
@@ -362,8 +365,28 @@ public HyperGraph getHyperGraph() {
362
365
return hyperGraph ;
363
366
}
364
367
368
+ /**
369
+ * lazy init for performance
370
+ */
365
371
public SplitPredicate getSplitPredicate () {
366
- return splitPredicate ;
372
+ if (this .splitPredicate == null && this .predicates != null ) {
373
+ Pair <SplitPredicate , EquivalenceClass > derivedPredicates = predicatesDerive (this .predicates , topPlan );
374
+ this .splitPredicate = derivedPredicates .key ();
375
+ this .equivalenceClass = derivedPredicates .value ();
376
+ }
377
+ return this .splitPredicate ;
378
+ }
379
+
380
+ /**
381
+ * lazy init for performance
382
+ */
383
+ public EquivalenceClass getEquivalenceClass () {
384
+ if (this .equivalenceClass == null && this .predicates != null ) {
385
+ Pair <SplitPredicate , EquivalenceClass > derivedPredicates = predicatesDerive (this .predicates , topPlan );
386
+ this .splitPredicate = derivedPredicates .key ();
387
+ this .equivalenceClass = derivedPredicates .value ();
388
+ }
389
+ return this .equivalenceClass ;
367
390
}
368
391
369
392
public boolean isValid () {
@@ -416,6 +439,10 @@ public BitSet getTableBitSet() {
416
439
return tableBitSet ;
417
440
}
418
441
442
+ public List <? extends Expression > getPlanOutputShuttledExpressions () {
443
+ return planOutputShuttledExpressions ;
444
+ }
445
+
419
446
/**
420
447
* Judge the source graph logical is whether the same as target
421
448
* For inner join should judge only the join tables,
0 commit comments