@@ -371,7 +371,11 @@ func (q *query) evalSample(ctx context.Context, expr syntax.SampleExpr) (promql_
371
371
case SampleVector :
372
372
maxSeriesCapture := func (id string ) int { return q .limits .MaxQuerySeries (ctx , id ) }
373
373
maxSeries := validation .SmallestPositiveIntPerTenant (tenantIDs , maxSeriesCapture )
374
- return q .JoinSampleVector (next , vec , stepEvaluator , maxSeries )
374
+ mfl := false
375
+ if rae , ok := expr .(* syntax.RangeAggregationExpr ); ok && (rae .Operation == syntax .OpRangeTypeFirstWithTimestamp || rae .Operation == syntax .OpRangeTypeLastWithTimestamp ) {
376
+ mfl = true
377
+ }
378
+ return q .JoinSampleVector (next , vec , stepEvaluator , maxSeries , mfl )
375
379
case ProbabilisticQuantileVector :
376
380
return MergeQuantileSketchVector (next , vec , stepEvaluator , q .params )
377
381
default :
@@ -381,9 +385,31 @@ func (q *query) evalSample(ctx context.Context, expr syntax.SampleExpr) (promql_
381
385
return nil , errors .New ("unexpected empty result" )
382
386
}
383
387
384
- func (q * query ) JoinSampleVector (next bool , r StepResult , stepEvaluator StepEvaluator , maxSeries int ) (promql_parser.Value , error ) {
385
- seriesIndex := map [uint64 ]* promql.Series {}
388
+ func vectorsToSeries (vec promql.Vector , sm map [uint64 ]promql.Series ) {
389
+ for _ , p := range vec {
390
+ var (
391
+ series promql.Series
392
+ hash = p .Metric .Hash ()
393
+ ok bool
394
+ )
395
+
396
+ series , ok = sm [hash ]
397
+ if ! ok {
398
+ series = promql.Series {
399
+ Metric : p .Metric ,
400
+ Floats : make ([]promql.FPoint , 0 , 1 ),
401
+ }
402
+ sm [hash ] = series
403
+ }
404
+ series .Floats = append (series .Floats , promql.FPoint {
405
+ T : p .T ,
406
+ F : p .F ,
407
+ })
408
+ sm [hash ] = series
409
+ }
410
+ }
386
411
412
+ func (q * query ) JoinSampleVector (next bool , r StepResult , stepEvaluator StepEvaluator , maxSeries int , mergeFirstLast bool ) (promql_parser.Value , error ) {
387
413
vec := promql.Vector {}
388
414
if next {
389
415
vec = r .SampleVector ()
@@ -393,8 +419,21 @@ func (q *query) JoinSampleVector(next bool, r StepResult, stepEvaluator StepEval
393
419
if len (vec ) > maxSeries {
394
420
return nil , logqlmodel .NewSeriesLimitError (maxSeries )
395
421
}
422
+ seriesIndex := map [uint64 ]promql.Series {}
396
423
397
424
if GetRangeType (q .params ) == InstantType {
425
+ // an instant query sharded first/last_over_time can return a single vector
426
+ if mergeFirstLast {
427
+ vectorsToSeries (vec , seriesIndex )
428
+ series := make ([]promql.Series , 0 , len (seriesIndex ))
429
+ for _ , s := range seriesIndex {
430
+ series = append (series , s )
431
+ }
432
+ result := promql .Matrix (series )
433
+ sort .Sort (result )
434
+ return result , stepEvaluator .Error ()
435
+ }
436
+
398
437
sortByValue , err := Sortable (q .params )
399
438
if err != nil {
400
439
return nil , fmt .Errorf ("fail to check Sortable, logql: %s ,err: %s" , q .params .QueryString (), err )
@@ -412,26 +451,7 @@ func (q *query) JoinSampleVector(next bool, r StepResult, stepEvaluator StepEval
412
451
413
452
for next {
414
453
vec = r .SampleVector ()
415
- for _ , p := range vec {
416
- var (
417
- series * promql.Series
418
- hash = p .Metric .Hash ()
419
- ok bool
420
- )
421
-
422
- series , ok = seriesIndex [hash ]
423
- if ! ok {
424
- series = & promql.Series {
425
- Metric : p .Metric ,
426
- Floats : make ([]promql.FPoint , 0 , stepCount ),
427
- }
428
- seriesIndex [hash ] = series
429
- }
430
- series .Floats = append (series .Floats , promql.FPoint {
431
- T : p .T ,
432
- F : p .F ,
433
- })
434
- }
454
+ vectorsToSeries (vec , seriesIndex )
435
455
// as we slowly build the full query for each steps, make sure we don't go over the limit of unique series.
436
456
if len (seriesIndex ) > maxSeries {
437
457
return nil , logqlmodel .NewSeriesLimitError (maxSeries )
@@ -444,7 +464,7 @@ func (q *query) JoinSampleVector(next bool, r StepResult, stepEvaluator StepEval
444
464
445
465
series := make ([]promql.Series , 0 , len (seriesIndex ))
446
466
for _ , s := range seriesIndex {
447
- series = append (series , * s )
467
+ series = append (series , s )
448
468
}
449
469
result := promql .Matrix (series )
450
470
sort .Sort (result )
0 commit comments