@@ -279,13 +279,24 @@ learn_subplan_recurse(PlanState *p, aqo_obj_stat *ctx)
279
279
if (!p -> instrument )
280
280
return true;
281
281
282
- if (!INSTR_TIME_IS_ZERO (p -> instrument -> starttime ))
282
+ if (!ctx -> isTimedOut )
283
+ InstrEndLoop (p -> instrument );
284
+ else if (p -> instrument -> running )
283
285
{
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 ;
287
294
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
+ }
289
300
290
301
saved_subplan_list = p -> subPlan ;
291
302
saved_initplan_list = p -> initPlan ;
@@ -328,7 +339,7 @@ should_learn(aqo_obj_stat *ctx, double predicted, double *nrows)
328
339
{
329
340
if (ctx -> learn && * nrows > predicted * 1.2 )
330
341
{
331
- * nrows += (* nrows - predicted )* 3 . ;
342
+ * nrows += (* nrows - predicted )* 10 . ;
332
343
return true;
333
344
}
334
345
}
@@ -500,8 +511,8 @@ learnOnPlanState(PlanState *p, void *context)
500
511
501
512
if (should_learn (ctx ,predicted ,& learn_rows ))
502
513
{
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" ,
505
516
query_context .query_hash ,aqo_node -> fss ,predicted ,learn_rows );
506
517
507
518
if (IsA (p ,AggState ))
@@ -664,7 +675,7 @@ aqo_timeout_handler(void)
664
675
ctx .learn = query_context .learn_aqo ;
665
676
ctx .isTimedOut = true;
666
677
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." );
668
679
learnOnPlanState (timeoutCtl .queryDesc -> planstate , (void * )& ctx );
669
680
}
670
681