@@ -228,18 +228,48 @@ learnOnPlanState(PlanState *p, void *context)
228228if (p -> instrument && (p -> righttree != NULL || p -> lefttree == NULL ||
229229p -> plan -> path_clauses != NIL ))
230230{
231- double learn_rows ;
231+ double learn_rows = 0. ;
232+ double predicted ;
232233
233234InstrEndLoop (p -> instrument );
234- if (p -> instrument -> nloops > 0 )
235+ if (p -> instrument -> nloops > 0. )
235236{
236- learn_rows = p -> instrument -> ntuples /p -> instrument -> nloops ;
237+ /* If we can strongly calculate produced rows, do it. */
238+ if (p -> worker_instrument )
239+ {
240+ double wnloops = 0. ;
241+ double wntuples = 0. ;
242+ int i ;
243+
244+ for (i = 0 ;i < p -> worker_instrument -> num_workers ;i ++ )
245+ {
246+ double t = p -> worker_instrument -> instrument [i ].ntuples ;
247+ double l = p -> worker_instrument -> instrument [i ].nloops ;
248+ wntuples += t ;
249+ wnloops += l ;
250+ learn_rows += t /l ;
251+ }
252+
253+ Assert (p -> instrument -> nloops >=wnloops );
254+ Assert (p -> instrument -> ntuples >=wntuples );
255+ if (p -> instrument -> nloops - wnloops > 0.5 )
256+ learn_rows += (p -> instrument -> ntuples - wntuples ) /
257+ (p -> instrument -> nloops - wnloops );
258+ }
259+ else
260+ /* We don't have any workers. */
261+ learn_rows = p -> instrument -> ntuples /p -> instrument -> nloops ;
237262
238- if (p -> plan -> parallel_aware || (p -> plan -> path_parallel_workers > 0 &&
263+ if (p -> plan -> predicted_cardinality > 0. )
264+ predicted = p -> plan -> predicted_cardinality ;
265+ else if (p -> plan -> parallel_aware ||
266+ (p -> plan -> path_parallel_workers > 0 &&
239267(nodeTag (p -> plan )== T_HashJoin ||
240268nodeTag (p -> plan )== T_MergeJoin ||
241269nodeTag (p -> plan )== T_NestLoop )))
242- learn_rows *= (p -> plan -> path_parallel_workers + 1 );
270+ predicted = p -> plan -> plan_rows * get_parallel_divisor (p -> plan -> path_parallel_workers );
271+ else
272+ predicted = p -> plan -> plan_rows ;
243273
244274/* It is needed for correct exp(result) calculation. */
245275if (learn_rows < 1. )
@@ -260,8 +290,8 @@ learnOnPlanState(PlanState *p, void *context)
260290 * than a subtree will never be visited.
261291 */
262292if (!(p -> instrument -> ntuples <=0. && p -> instrument -> nloops <=0. ))
263- learn_sample (ctx -> clauselist ,ctx -> selectivities ,ctx -> relidslist ,
264- learn_rows ,p -> plan -> plan_rows );
293+ learn_sample (ctx -> clauselist ,ctx -> selectivities ,
294+ ctx -> relidslist , learn_rows ,predicted );
265295}
266296}
267297