19
19
import org .elasticsearch .xpack .esql .core .expression .Literal ;
20
20
import org .elasticsearch .xpack .esql .core .expression .NameId ;
21
21
import org .elasticsearch .xpack .esql .core .expression .NamedExpression ;
22
+ import org .elasticsearch .xpack .esql .core .expression .function .scalar .ScalarFunction ;
22
23
import org .elasticsearch .xpack .esql .core .tree .Source ;
23
24
import org .elasticsearch .xpack .esql .core .type .DataType ;
24
25
import org .elasticsearch .xpack .esql .core .util .Holder ;
25
26
import org .elasticsearch .xpack .esql .expression .function .aggregate .AggregateFunction ;
26
27
import org .elasticsearch .xpack .esql .expression .function .aggregate .Count ;
27
28
import org .elasticsearch .xpack .esql .expression .function .aggregate .Min ;
28
29
import org .elasticsearch .xpack .esql .expression .function .aggregate .Top ;
30
+ import org .elasticsearch .xpack .esql .expression .function .aggregate .Values ;
29
31
import org .elasticsearch .xpack .esql .expression .function .scalar .conditional .Case ;
30
32
import org .elasticsearch .xpack .esql .expression .function .scalar .multivalue .ConfidenceInterval ;
31
33
import org .elasticsearch .xpack .esql .expression .function .scalar .multivalue .MvAppend ;
@@ -300,6 +302,7 @@ private LogicalPlan approximatePlan(double sampleProbability) {
300
302
logger .debug ("generating approximate plan (p={})" , sampleProbability );
301
303
Holder <Boolean > encounteredStats = new Holder <>(false );
302
304
Set <NameId > variablesWithConfidenceInterval = new HashSet <>();
305
+ Set <NameId > variablesWithPastConfidenceInterval = new HashSet <>();
303
306
304
307
Alias bucketId = new Alias (
305
308
Source .EMPTY ,
@@ -345,21 +348,33 @@ private LogicalPlan approximatePlan(double sampleProbability) {
345
348
} else if (encounteredStats .get ()) {
346
349
System .out .println ("@@@ UPDATE variablesWithConfidenceInterval" );
347
350
System .out .println ("plan = " + plan );
348
- System .out .println ("vars = " + variablesWithConfidenceInterval );
351
+ System .out .println ("vars = " + variablesWithConfidenceInterval + " / " + variablesWithPastConfidenceInterval );
349
352
switch (plan ) {
350
353
case Eval eval :
351
- for (NamedExpression field : eval .fields ()) {
354
+ for (Alias field : eval .fields ()) {
352
355
if (field .anyMatch (expr -> expr instanceof NamedExpression named && variablesWithConfidenceInterval .contains (named .id ()))) {
353
- variablesWithConfidenceInterval .add (field .id ());
356
+ // TODO: blacklist / whitelist?
357
+ if (field .child () instanceof MvAppend == false && field .dataType ().isNumeric ()) {
358
+ variablesWithConfidenceInterval .add (field .id ());
359
+ } else {
360
+ variablesWithPastConfidenceInterval .add (field .id ());
361
+ }
362
+ } else if (field .anyMatch (expr -> expr instanceof NamedExpression named && variablesWithPastConfidenceInterval .contains (named .id ()))) {
363
+ variablesWithPastConfidenceInterval .add (field .id ());
354
364
}
355
365
}
356
366
break ;
367
+ case Project project :
368
+ List <NamedExpression > projections = new ArrayList <>(project .projections ());
369
+ projections .add (bucketId .toAttribute ());
370
+ plan = project .withProjections (projections );
371
+ break ;
357
372
case Rename rename :
358
373
// TODO
359
374
break ;
360
375
default :
361
376
}
362
- System .out .println ("vars = " + variablesWithConfidenceInterval );
377
+ System .out .println ("vars = " + variablesWithConfidenceInterval + " / " + variablesWithPastConfidenceInterval );
363
378
}
364
379
return plan ;
365
380
});
@@ -372,17 +387,22 @@ private LogicalPlan approximatePlan(double sampleProbability) {
372
387
if (attribute .id () == bucketId .id ()) {
373
388
continue ;
374
389
}
375
- if (variablesWithConfidenceInterval .contains (attribute .id ())) {
376
- aggregates . add ( new Alias (
390
+ if (variablesWithConfidenceInterval .contains (attribute .id ()) || variablesWithPastConfidenceInterval . contains ( attribute . id ()) ) {
391
+ Alias bestEstimate = new Alias (
377
392
Source .EMPTY ,
378
393
attribute .name (),
379
- new ConfidenceInterval (
394
+ new Values (
380
395
Source .EMPTY ,
381
- new Min (
382
- Source .EMPTY ,
383
- attribute ,
384
- new Equals (Source .EMPTY , bucketId .toAttribute (), Literal .integer (Source .EMPTY , -1 ))
385
- ),
396
+ attribute ,
397
+ new Equals (Source .EMPTY , bucketId .toAttribute (), Literal .integer (Source .EMPTY , -1 ))
398
+ )
399
+ );
400
+ aggregates .add (bestEstimate );
401
+ if (variablesWithConfidenceInterval .contains (attribute .id ())) {
402
+ aggregates .add (new Alias (
403
+ Source .EMPTY , "CONFIDENCE_INTERVAL(" + attribute .name () + ")" , new ConfidenceInterval (
404
+ Source .EMPTY ,
405
+ bestEstimate .toAttribute (),
386
406
new Top (
387
407
Source .EMPTY ,
388
408
attribute ,
@@ -391,9 +411,11 @@ private LogicalPlan approximatePlan(double sampleProbability) {
391
411
Literal .keyword (Source .EMPTY , "ASC" )
392
412
),
393
413
Literal .integer (Source .EMPTY , BUCKET_COUNT ),
394
- Literal .fromDouble (Source .EMPTY , 0.0 ) // TODO: fix, 0.0 or NaN ??
414
+ Literal .fromDouble (Source .EMPTY , 0.0 )
415
+ // TODO: fix, 0.0 or NaN ?? TODO: remove!!
395
416
)
396
- ));
417
+ ));
418
+ }
397
419
} else {
398
420
aggregates .add (attribute );
399
421
groupings .add (attribute );
0 commit comments