diff --git a/pkg/sql/opt/cat/table.go b/pkg/sql/opt/cat/table.go index d0974a47f4e0..c6c40bae6c4b 100644 --- a/pkg/sql/opt/cat/table.go +++ b/pkg/sql/opt/cat/table.go @@ -302,7 +302,7 @@ type HistogramBucket struct { // DistinctRange is the estimated number of distinct values between the upper // bound of the previous bucket and UpperBound (both boundaries are - // exclusive). + // exclusive). The first bucket should always have DistinctRange=0. DistinctRange float64 // UpperBound is the upper bound of the bucket. diff --git a/pkg/sql/opt/props/histogram.go b/pkg/sql/opt/props/histogram.go index 06a9faf7156c..3cda530166c4 100644 --- a/pkg/sql/opt/props/histogram.go +++ b/pkg/sql/opt/props/histogram.go @@ -23,6 +23,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sem/eval" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/types" + "github.com/cockroachdb/cockroach/pkg/util/buildutil" "github.com/cockroachdb/cockroach/pkg/util/encoding" "github.com/cockroachdb/cockroach/pkg/util/timetz" "github.com/cockroachdb/errors" @@ -79,6 +80,15 @@ func (h *Histogram) numEq(i int) float64 { // selectivity applied. i must be greater than or equal to 0 and less than // bucketCount. func (h *Histogram) numRange(i int) float64 { + // The first bucket always has a zero value for NumRange, so the lower bound + // of the histogram is the upper bound of the first bucket. We only check this + // in test builds. + if i == 0 && h.buckets[i].NumRange != 0 { + if buildutil.CrdbTestBuild { + panic(errors.AssertionFailedf("the first bucket should have NumRange=0")) + } + return 0 + } return h.buckets[i].NumRange * h.selectivity } @@ -89,6 +99,13 @@ func (h *Histogram) distinctRange(i int) float64 { n := h.buckets[i].NumRange d := h.buckets[i].DistinctRange + if i == 0 && d != 0 { + if buildutil.CrdbTestBuild { + panic(errors.AssertionFailedf("the first bucket should have DistinctRange=0")) + } + return 0 + } + if d == 0 { return 0 } @@ -207,11 +224,6 @@ func (h *Histogram) maxDistinctValuesCount() float64 { return 0 } - // The first bucket always has a zero value for NumRange, so the lower bound - // of the histogram is the upper bound of the first bucket. - if h.numRange(0) != 0 { - panic(errors.AssertionFailedf("the first bucket should have NumRange=0")) - } previousUpperBound := h.upperBound(0) var count float64 @@ -326,12 +338,6 @@ func (h *Histogram) filter( return filtered } - // The first bucket always has a zero value for NumRange, so the lower bound - // of the histogram is the upper bound of the first bucket. - if h.numRange(0) != 0 { - panic(errors.AssertionFailedf("the first bucket should have NumRange=0")) - } - var iter histogramIter iter.init(h, desc) spanIndex := 0