@@ -18,6 +18,7 @@ typedef struct
1818List * clauselist ;
1919List * selectivities ;
2020List * relidslist ;
21+ bool learn ;
2122}aqo_obj_stat ;
2223
2324static double cardinality_sum_errors ;
@@ -90,9 +91,6 @@ learn_sample(List *clauselist, List *selectivities, List *relidslist,
9091double target ;
9192int i ;
9293
93- cardinality_sum_errors += fabs (log (predicted_cardinality )-
94- log (true_cardinality ));
95- cardinality_num_objects += 1 ;
9694/*
9795 * Suppress the optimization for debug purposes.
9896if (fabs(log(predicted_cardinality) - log(true_cardinality)) <
@@ -200,7 +198,7 @@ static bool
200198learnOnPlanState (PlanState * p ,void * context )
201199{
202200aqo_obj_stat * ctx = (aqo_obj_stat * )context ;
203- aqo_obj_stat SubplanCtx = {NIL ,NIL ,NIL };
201+ aqo_obj_stat SubplanCtx = {NIL ,NIL ,NIL , ctx -> learn };
204202
205203planstate_tree_walker (p ,learnOnPlanState , (void * )& SubplanCtx );
206204
@@ -294,14 +292,18 @@ learnOnPlanState(PlanState *p, void *context)
294292learn_rows = 1. ;
295293}
296294
295+ cardinality_sum_errors += fabs (log (predicted )-
296+ log (learn_rows ));
297+ cardinality_num_objects += 1 ;
298+
297299/*
298300 * A subtree was not visited. In this case we can not teach AQO
299301 * because ntuples value is equal to 0 and we will got
300302 * learn rows == 1.
301303 * It is false teaching, because at another place of a plan
302304 * scanning of the node may produce many tuples.
303305 */
304- if (p -> instrument -> nloops >=1 )
306+ if (ctx -> learn && p -> instrument -> nloops >=1 )
305307learn_sample (SubplanCtx .clauselist ,SubplanCtx .selectivities ,
306308p -> plan -> path_relids ,learn_rows ,predicted );
307309}
@@ -366,15 +368,17 @@ aqo_ExecutorStart(QueryDesc *queryDesc, int eflags)
366368{
367369instr_time current_time ;
368370
369- if (query_context .use_aqo || query_context .learn_aqo )
371+ if (!IsParallelWorker ()&&
372+ (query_context .use_aqo || query_context .learn_aqo || force_collect_stat ))
370373{
371374INSTR_TIME_SET_CURRENT (current_time );
372375INSTR_TIME_SUBTRACT (current_time ,query_context .query_starttime );
373376query_context .query_planning_time = INSTR_TIME_GET_DOUBLE (current_time );
374377
375378query_context .explain_only = ((eflags & EXEC_FLAG_EXPLAIN_ONLY )!= 0 );
376379
377- if (query_context .learn_aqo && !query_context .explain_only )
380+ if ((query_context .learn_aqo || force_collect_stat )&&
381+ !query_context .explain_only )
378382queryDesc -> instrument_options |=INSTRUMENT_ROWS ;
379383
380384/* Save all query-related parameters into the query context. */
@@ -425,9 +429,9 @@ aqo_ExecutorEnd(QueryDesc *queryDesc)
425429query_context .collect_stat = false;
426430}
427431
428- if (query_context .learn_aqo )
432+ if (query_context .learn_aqo || query_context . collect_stat )
429433{
430- aqo_obj_stat ctx = {NIL ,NIL ,NIL };
434+ aqo_obj_stat ctx = {NIL ,NIL ,NIL , query_context . learn_aqo };
431435
432436cardinality_sum_errors = 0. ;
433437cardinality_num_objects = 0 ;
@@ -443,13 +447,14 @@ aqo_ExecutorEnd(QueryDesc *queryDesc)
443447INSTR_TIME_SET_CURRENT (endtime );
444448INSTR_TIME_SUBTRACT (endtime ,query_context .query_starttime );
445449totaltime = INSTR_TIME_GET_DOUBLE (endtime );
446- if (query_context . learn_aqo && cardinality_num_objects > 0 )
450+ if (cardinality_num_objects > 0 )
447451cardinality_error = cardinality_sum_errors /
448452cardinality_num_objects ;
449453else
450454cardinality_error = -1 ;
451455
452456stat = get_aqo_stat (query_context .query_hash );
457+
453458if (stat != NULL )
454459{
455460if (query_context .use_aqo )
@@ -699,7 +704,7 @@ void print_into_explain(PlannedStmt *plannedstmt, IntoClause *into,
699704case AQO_MODE_LEARN :
700705ExplainPropertyText ("AQO mode" ,"LEARN" ,es );
701706break ;
702- case AQO_MODE_FIXED :
707+ case AQO_MODE_FROZEN :
703708ExplainPropertyText ("AQO mode" ,"FIXED" ,es );
704709break ;
705710default :