( ctx context.Context, f *QueryFilter, )
| 486 | } |
| 487 | |
| 488 | func (h *QueryHandler) selectMetricHeatmap( |
| 489 | ctx context.Context, f *QueryFilter, |
| 490 | ) (*histutil.Heatmap, error) { |
| 491 | tableName, groupingInterval := DatapointTableForGrouping( |
| 492 | &f.TimeFilter, org.GroupingIntervalLarge) |
| 493 | |
| 494 | q := h.CH.NewSelect(). |
| 495 | ColumnExpr("quantilesBFloat16MergeState(0.5, 0.9, 0.99)(d.histogram) AS value"). |
| 496 | ColumnExpr("toStartOfInterval(d.time, INTERVAL ? minute) AS time_", |
| 497 | groupingInterval.Minutes()). |
| 498 | TableExpr("? AS d", ch.Name(tableName)). |
| 499 | Where("d.project_id = ?", f.Project.ID). |
| 500 | Where("d.metric = ?", f.Metric[0]). |
| 501 | Where("d.time >= ?", f.TimeGTE). |
| 502 | Where("d.time < ?", f.TimeLT). |
| 503 | GroupExpr("time_"). |
| 504 | OrderExpr("time_"). |
| 505 | Limit(10000) |
| 506 | |
| 507 | for _, part := range f.allParts { |
| 508 | if part.Error.Wrapped != nil { |
| 509 | continue |
| 510 | } |
| 511 | switch ast := part.AST.(type) { |
| 512 | case *ast.Selector: |
| 513 | part.Error.Wrapped = errors.New("not supported by heatmap") |
| 514 | case *ast.Grouping: |
| 515 | part.Error.Wrapped = errors.New("not supported by heatmap") |
| 516 | case *ast.Where: |
| 517 | if err := compileFilters(q, InstrumentHistogram, ast.Filters); err != nil { |
| 518 | part.Error.Wrapped = err |
| 519 | } |
| 520 | default: |
| 521 | return nil, fmt.Errorf("unexpected ast: %T", ast) |
| 522 | } |
| 523 | } |
| 524 | |
| 525 | var bfloat16Col []map[bfloat16.T]uint64 |
| 526 | var timeCol []time.Time |
| 527 | |
| 528 | if err := q.ScanColumns(ctx, &bfloat16Col, &timeCol); err != nil { |
| 529 | return nil, err |
| 530 | } |
| 531 | |
| 532 | tdigestCol := make([][]float32, len(bfloat16Col)) |
| 533 | for i, m := range bfloat16Col { |
| 534 | tdigest := make([]float32, 0, 2*len(m)) |
| 535 | for value, count := range m { |
| 536 | tdigest = append(tdigest, value.Float32(), float32(count)) |
| 537 | } |
| 538 | tdigestCol[i] = tdigest |
| 539 | } |
| 540 | |
| 541 | tdigestCol = bunutil.Fill(tdigestCol, timeCol, nil, f.TimeGTE, f.TimeLT, groupingInterval) |
| 542 | timeCol = bunutil.FillTime(timeCol, f.TimeGTE, f.TimeLT, groupingInterval) |
| 543 | heatmap := histutil.BuildHeatmap(tdigestCol, timeCol) |
| 544 | |
| 545 | return heatmap, nil |
no test coverage detected