@@ -279,13 +279,24 @@ learn_subplan_recurse(PlanState *p, aqo_obj_stat *ctx)
279279if (!p -> instrument )
280280return true;
281281
282- if (!INSTR_TIME_IS_ZERO (p -> instrument -> starttime ))
282+ if (!ctx -> isTimedOut )
283+ InstrEndLoop (p -> instrument );
284+ else if (p -> instrument -> running )
283285{
284- Assert (ctx -> isTimedOut );
285- InstrStopNode (p -> instrument ,0 );
286- }
286+ /*
287+ * We can't use node instrumentation functions because after the end
288+ * of this timeout handler query can work for some time.
289+ * We change ntuples and nloops to unify walking logic and because we
290+ * know that the query execution results meaningless.
291+ */
292+ p -> instrument -> ntuples += p -> instrument -> tuplecount ;
293+ p -> instrument -> nloops += 1 ;
287294
288- InstrEndLoop (p -> instrument );
295+ /*
296+ * TODO: can we simply use ExecParallelCleanup to implement gathering of
297+ * instrument data in the case of parallel workers?
298+ */
299+ }
289300
290301saved_subplan_list = p -> subPlan ;
291302saved_initplan_list = p -> initPlan ;
@@ -328,7 +339,7 @@ should_learn(aqo_obj_stat *ctx, double predicted, double *nrows)
328339{
329340if (ctx -> learn && * nrows > predicted * 1.2 )
330341{
331- * nrows += (* nrows - predicted )* 3 . ;
342+ * nrows += (* nrows - predicted )* 10 . ;
332343return true;
333344}
334345}
@@ -500,8 +511,8 @@ learnOnPlanState(PlanState *p, void *context)
500511
501512if (should_learn (ctx ,predicted ,& learn_rows ))
502513{
503- if (ctx -> isTimedOut )
504- elog (DEBUG1 ,"[AQO] Learn on partially executed plan node. fs: %lu, fss: %d, predicted rows: %.0lf, updated prediction: %.0lf" ,
514+ if (ctx -> isTimedOut && aqo_show_details )
515+ elog (NOTICE ,"[AQO] Learn on partially executed plan node. fs: %lu, fss: %d, predicted rows: %.0lf, updated prediction: %.0lf" ,
505516query_context .query_hash ,aqo_node -> fss ,predicted ,learn_rows );
506517
507518if (IsA (p ,AggState ))
@@ -664,7 +675,7 @@ aqo_timeout_handler(void)
664675ctx .learn = query_context .learn_aqo ;
665676ctx .isTimedOut = true;
666677
667- elog (DEBUG1 ,"AQO timeout was expired. Try to learn on partial data." );
678+ elog (NOTICE ,"[ AQO] Time limit for execution of the statement was expired. Try to learn on partial data." );
668679learnOnPlanState (timeoutCtl .queryDesc -> planstate , (void * )& ctx );
669680}
670681