diff --git a/app/vmselect/promql/exec_test.go b/app/vmselect/promql/exec_test.go index 60430bdf1b..d923484379 100644 --- a/app/vmselect/promql/exec_test.go +++ b/app/vmselect/promql/exec_test.go @@ -5,10 +5,11 @@ import ( "testing" "time" + "github.com/VictoriaMetrics/metricsql" + "github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/netstorage" "github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/searchutils" "github.com/VictoriaMetrics/VictoriaMetrics/lib/storage" - "github.com/VictoriaMetrics/metricsql" ) func TestEscapeDots(t *testing.T) { @@ -245,6 +246,23 @@ func TestExecSuccess(t *testing.T) { resultExpected := []netstorage.Result{r} f(q, resultExpected) }) + t.Run("bitmap_and(NaN, 1)", func(t *testing.T) { + t.Parallel() + q := `bitmap_and(NaN, 1)` + var resultExpected []netstorage.Result + f(q, resultExpected) + }) + t.Run("bitmap_and(round(rand(1) > 0.5, 1), 1)", func(t *testing.T) { + t.Parallel() + q := `bitmap_and(round(rand(1) > 0.5, 1), 1)` + r := netstorage.Result{ + MetricName: metricNameExpected, + Values: []float64{1, 1, 1, nan, nan, 1}, + Timestamps: timestampsExpected, + } + resultExpected := []netstorage.Result{r} + f(q, resultExpected) + }) t.Run("bitmap_or(0xA2, 0x11)", func(t *testing.T) { t.Parallel() q := `bitmap_or(0xA2, 0x11)` @@ -267,6 +285,23 @@ func TestExecSuccess(t *testing.T) { resultExpected := []netstorage.Result{r} f(q, resultExpected) }) + t.Run("bitmap_or(NaN, 1)", func(t *testing.T) { + t.Parallel() + q := `bitmap_or(NaN, 1)` + var resultExpected []netstorage.Result + f(q, resultExpected) + }) + t.Run("bitmap_or(round(rand(1) > 0.5, 1), 1)", func(t *testing.T) { + t.Parallel() + q := `bitmap_or(round(rand(1) > 0.5, 1), 1)` + r := netstorage.Result{ + MetricName: metricNameExpected, + Values: []float64{1, 1, 1, nan, nan, 1}, + Timestamps: timestampsExpected, + } + resultExpected := []netstorage.Result{r} + f(q, resultExpected) + }) t.Run("bitmap_xor(0xB3, 0x11)", func(t *testing.T) { t.Parallel() q := `bitmap_xor(0xB3, 0x11)` @@ -289,6 +324,23 @@ func TestExecSuccess(t *testing.T) { resultExpected := []netstorage.Result{r} f(q, resultExpected) }) + t.Run("bitmap_xor(NaN, 1)", func(t *testing.T) { + t.Parallel() + q := `bitmap_xor(NaN, 1)` + var resultExpected []netstorage.Result + f(q, resultExpected) + }) + t.Run("bitmap_xor(round(rand(1) > 0.5, 1), 1)", func(t *testing.T) { + t.Parallel() + q := `bitmap_xor(round(rand(1) > 0.5, 1), 1)` + r := netstorage.Result{ + MetricName: metricNameExpected, + Values: []float64{0, 0, 0, nan, nan, 0}, + Timestamps: timestampsExpected, + } + resultExpected := []netstorage.Result{r} + f(q, resultExpected) + }) t.Run("timezone_offset(UTC)", func(t *testing.T) { t.Parallel() q := `timezone_offset("UTC")` diff --git a/app/vmselect/promql/transform.go b/app/vmselect/promql/transform.go index 94da2a5727..64b4f59b9d 100644 --- a/app/vmselect/promql/transform.go +++ b/app/vmselect/promql/transform.go @@ -11,12 +11,13 @@ import ( "strings" "time" + "github.com/VictoriaMetrics/metricsql" + "github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/searchutils" "github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil" "github.com/VictoriaMetrics/VictoriaMetrics/lib/decimal" "github.com/VictoriaMetrics/VictoriaMetrics/lib/logger" "github.com/VictoriaMetrics/VictoriaMetrics/lib/storage" - "github.com/VictoriaMetrics/metricsql" ) var transformFuncs = map[string]transformFunc{ @@ -2589,6 +2590,9 @@ func newTransformBitmap(bitmapFunc func(a, b uint64) uint64) func(tfa *transform } tf := func(values []float64) { for i, v := range values { + if math.IsNaN(v) { + continue + } values[i] = float64(bitmapFunc(uint64(v), uint64(ns[i]))) } } diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index bc5b82fcbd..7426c8580b 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -58,6 +58,7 @@ The sandbox cluster installation is running under the constant load generated by * BUGFIX: [Official Grafana dashboards for VictoriaMetrics](https://grafana.com/orgs/victoriametrics): move vmagent's `Concurrent inserts` panel to Troubleshooting section from `Ingestion` section because this panel is related to both: scraped and ingested data. Before, it could have give a misleading impression that it is related to ingested metrics only. * BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): fix the bug causing render looping when switching to heatmap. * BUGFIX: [VictoriaMetrics enterprise](https://docs.victoriametrics.com/enterprise.html) validate `-dedup.minScrapeInterval` value and `-downsampling.period` intervals are multiples of each other. See [these docs](https://docs.victoriametrics.com/#downsampling). +* BUGFIX: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): fix bitmap_*() functions behavior. These functions will return `NaN` if timeseries has no value for timestamp. Previously these functions return `0`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4996). * BUGFIX: [vmbackup](https://docs.victoriametrics.com/vmbackup.html): properly copy `appliedRetention.txt` files inside `<-storageDataPath>/{data}` folders during [incremental backups](https://docs.victoriametrics.com/vmbackup.html#incremental-backups). Previously the new `appliedRetention.txt` could be skipped during incremental backups, which could lead to increased load on storage after restoring from backup. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5005). * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): suppress `context canceled` error messages in logs when `vmagent` is reloading service discovery config. This error could appear starting from [v1.93.5](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.93.5). See [this PR](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5048). * BUGFIX: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): allow passing [median_over_time](https://docs.victoriametrics.com/MetricsQL.html#median_over_time) to [aggr_over_time](https://docs.victoriametrics.com/MetricsQL.html#aggr_over_time). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5034).