Skip to content

Commit 45d4f5b

Browse files
index planning: Remove unnecessary error handling (#12738)
The `estimatePredicateCardinality` function wasn't actually returning any errors in its implementation, so this simplifies the function signature by removing the unused error return value. This cleanup removes dead code and simplifies the calling sites. --------- Signed-off-by: Dimitar Dimitrov <[email protected]>
1 parent 042de5b commit 45d4f5b

File tree

5 files changed

+18
-47
lines changed

5 files changed

+18
-47
lines changed

pkg/ingester/lookupplan/plan.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ package lookupplan
44

55
import (
66
"context"
7-
"fmt"
87
"slices"
98

109
"github.com/prometheus/prometheus/model/labels"
@@ -31,22 +30,19 @@ type plan struct {
3130
}
3231

3332
// newScanOnlyPlan returns a plan in which all predicates would be used to scan and none to reach from the index.
34-
func newScanOnlyPlan(ctx context.Context, stats index.Statistics, matchers []*labels.Matcher) (plan, error) {
33+
func newScanOnlyPlan(ctx context.Context, stats index.Statistics, matchers []*labels.Matcher) plan {
3534
p := plan{
3635
predicates: make([]planPredicate, 0, len(matchers)),
3736
indexPredicate: make([]bool, 0, len(matchers)),
3837
totalSeries: stats.TotalSeries(),
3938
}
4039
for _, m := range matchers {
41-
pred, err := newPlanPredicate(ctx, m, stats)
42-
if err != nil {
43-
return plan{}, fmt.Errorf("error converting matcher to plan predicate: %w", err)
44-
}
40+
pred := newPlanPredicate(ctx, m, stats)
4541
p.predicates = append(p.predicates, pred)
4642
p.indexPredicate = append(p.indexPredicate, false)
4743
}
4844

49-
return p, nil
45+
return p
5046
}
5147

5248
func (p plan) IndexMatchers() []*labels.Matcher {

pkg/ingester/lookupplan/plan_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010

1111
"github.com/prometheus/prometheus/model/labels"
1212
"github.com/stretchr/testify/assert"
13-
"github.com/stretchr/testify/require"
1413

1514
"github.com/grafana/mimir/pkg/util"
1615
)
@@ -74,8 +73,7 @@ func TestPlanCosts(t *testing.T) {
7473
allMatchers = append(allMatchers, tc.scanMatchers...)
7574

7675
// Create a scan-only plan with all matchers
77-
p, err := newScanOnlyPlan(ctx, stats, allMatchers)
78-
require.NoError(t, err)
76+
p := newScanOnlyPlan(ctx, stats, allMatchers)
7977

8078
// Use index for the first N predicates (corresponding to index matchers)
8179
for i := 0; i < len(tc.indexMatchers); i++ {

pkg/ingester/lookupplan/planner.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,7 @@ func (p CostBasedPlanner) PlanIndexLookup(ctx context.Context, inPlan index.Look
5555
return inPlan, errTooManyMatchers
5656
}
5757

58-
allPlansUnordered, err := p.generatePlans(ctx, p.stats, matchers)
59-
if err != nil {
60-
return nil, fmt.Errorf("error generating plans: %w", err)
61-
}
58+
allPlansUnordered := p.generatePlans(ctx, p.stats, matchers)
6259

6360
type planWithCost struct {
6461
plan
@@ -93,14 +90,11 @@ func (p CostBasedPlanner) PlanIndexLookup(ctx context.Context, inPlan index.Look
9390

9491
var errTooManyMatchers = errors.New("too many matchers to generate plans")
9592

96-
func (p CostBasedPlanner) generatePlans(ctx context.Context, statistics index.Statistics, matchers []*labels.Matcher) ([]plan, error) {
97-
noopPlan, err := newScanOnlyPlan(ctx, statistics, matchers)
98-
if err != nil {
99-
return nil, fmt.Errorf("error generating index lookup plan: %w", err)
100-
}
93+
func (p CostBasedPlanner) generatePlans(ctx context.Context, statistics index.Statistics, matchers []*labels.Matcher) []plan {
94+
noopPlan := newScanOnlyPlan(ctx, statistics, matchers)
10195
allPlans := make([]plan, 0, 1<<uint(len(matchers)))
10296

103-
return generatePredicateCombinations(allPlans, noopPlan, 0), nil
97+
return generatePredicateCombinations(allPlans, noopPlan, 0)
10498
}
10599

106100
// generatePredicateCombinations recursively generates all possible plans with their predicates toggled as index or as scan predicates.

pkg/ingester/lookupplan/predicate.go

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ package lookupplan
44

55
import (
66
"context"
7-
"fmt"
87

98
"github.com/prometheus/prometheus/model/labels"
109
"github.com/prometheus/prometheus/tsdb/index"
@@ -27,26 +26,18 @@ type planPredicate struct {
2726
indexScanCost float64
2827
}
2928

30-
func newPlanPredicate(ctx context.Context, m *labels.Matcher, stats index.Statistics) (planPredicate, error) {
31-
var err error
29+
func newPlanPredicate(ctx context.Context, m *labels.Matcher, stats index.Statistics) planPredicate {
3230
pred := planPredicate{
3331
matcher: m,
3432
singleMatchCost: m.SingleMatchCost(),
3533
}
3634
pred.labelNameUniqueVals = stats.LabelValuesCount(ctx, m.Name)
37-
if err != nil {
38-
return planPredicate{}, fmt.Errorf("error getting label values count for label %s: %w", m.Name, err)
39-
}
4035
pred.selectivity = m.EstimateSelectivity(pred.labelNameUniqueVals)
4136

42-
pred.cardinality, err = estimatePredicateCardinality(ctx, m, stats, pred.selectivity)
43-
if err != nil {
44-
return planPredicate{}, fmt.Errorf("error estimating cardinality for label %s: %w", m.Name, err)
45-
}
46-
37+
pred.cardinality = estimatePredicateCardinality(ctx, m, stats, pred.selectivity)
4738
pred.indexScanCost = estimatePredicateIndexScanCost(pred, m)
4839

49-
return pred, nil
40+
return pred
5041
}
5142

5243
func estimatePredicateIndexScanCost(pred planPredicate, m *labels.Matcher) float64 {
@@ -75,11 +66,10 @@ func estimatePredicateIndexScanCost(pred planPredicate, m *labels.Matcher) float
7566
panic("estimatePredicateIndexScanCost called with unhandled matcher type: " + m.Type.String() + m.String())
7667
}
7768

78-
func estimatePredicateCardinality(ctx context.Context, m *labels.Matcher, stats index.Statistics, selectivity float64) (uint64, error) {
69+
func estimatePredicateCardinality(ctx context.Context, m *labels.Matcher, stats index.Statistics, selectivity float64) uint64 {
7970
var (
8071
seriesBehindSelectedValues uint64
8172
matchesAnyValues bool
82-
err error
8373
)
8474

8575
switch m.Type {
@@ -107,18 +97,15 @@ func estimatePredicateCardinality(ctx context.Context, m *labels.Matcher, stats
10797
seriesBehindSelectedValues += uint64(float64(labelNameCardinality) * selectivity)
10898
}
10999
}
110-
if err != nil {
111-
return 0, fmt.Errorf("error getting series per label value for label %s: %w", m.Name, err)
112-
}
113100
switch m.Type {
114101
case labels.MatchNotEqual, labels.MatchNotRegexp:
115102
if !matchesAnyValues {
116103
// This label name doesn't exist. This means that negating this will select everything.
117-
return stats.TotalSeries(), nil
104+
return stats.TotalSeries()
118105
}
119-
return stats.TotalSeries() - seriesBehindSelectedValues, nil
106+
return stats.TotalSeries() - seriesBehindSelectedValues
120107
}
121-
return seriesBehindSelectedValues, nil
108+
return seriesBehindSelectedValues
122109
}
123110

124111
func (pr planPredicate) indexLookupCost() float64 {

pkg/ingester/lookupplan/predicate_test.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ func TestFilterCost(t *testing.T) {
4646
for _, tc := range testCases {
4747
testName := fmt.Sprintf("%d_series_%s", tc.seriesCount, tc.matcher)
4848
t.Run(testName, func(t *testing.T) {
49-
pred, err := newPlanPredicate(ctx, tc.matcher, stats)
50-
assert.NoError(t, err)
49+
pred := newPlanPredicate(ctx, tc.matcher, stats)
5150

5251
cost := pred.filterCost(tc.seriesCount)
5352
assert.GreaterOrEqual(t, cost, 0.0, "can't have negative costs")
@@ -89,8 +88,7 @@ func TestIndexLookupCost(t *testing.T) {
8988

9089
for tcIdx, tc := range testCases {
9190
t.Run(tc.matcher.String(), func(t *testing.T) {
92-
pred, err := newPlanPredicate(ctx, tc.matcher, stats)
93-
assert.NoError(t, err)
91+
pred := newPlanPredicate(ctx, tc.matcher, stats)
9492

9593
actualCost := pred.indexLookupCost()
9694
assert.GreaterOrEqual(t, actualCost, 0.0, "can't have negative cost")
@@ -135,9 +133,7 @@ func TestCardinalityEstimation(t *testing.T) {
135133

136134
for tcIdx, tc := range testCases {
137135
t.Run(tc.matcher.String(), func(t *testing.T) {
138-
pred, err := newPlanPredicate(ctx, tc.matcher, stats)
139-
assert.NoError(t, err)
140-
136+
pred := newPlanPredicate(ctx, tc.matcher, stats)
141137
actualCardinality := pred.cardinality
142138

143139
if tc.deltaTolerance > 0 {

0 commit comments

Comments
 (0)