diff --git a/pkg/sql/opt/cat/table.go b/pkg/sql/opt/cat/table.go index 3f3ba6b920cd..24c364bde181 100644 --- a/pkg/sql/opt/cat/table.go +++ b/pkg/sql/opt/cat/table.go @@ -300,7 +300,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 02cead265e85..6772f214027a 100644 --- a/pkg/sql/opt/props/histogram.go +++ b/pkg/sql/opt/props/histogram.go @@ -21,6 +21,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree/datumrange" "github.com/cockroachdb/cockroach/pkg/sql/types" + "github.com/cockroachdb/cockroach/pkg/util/buildutil" "github.com/cockroachdb/errors" "github.com/olekukonko/tablewriter" ) @@ -75,6 +76,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 } @@ -85,6 +95,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 } @@ -203,11 +220,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 @@ -322,12 +334,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