Copilot commented on code in PR #1019:
URL:
https://github.com/apache/skywalking-banyandb/pull/1019#discussion_r2972320083
##########
.github/workflows/test-fodc-e2e.yml:
##########
@@ -60,10 +60,11 @@ jobs:
download-artifacts: 'true'
setup-docker: 'true'
- - name: Setup kubectl
- uses: azure/setup-kubectl@v4
- with:
- version: v1.30.0
+ - name: Install kubectl
+ run: |
+ mkdir -p "${HOME}/.local/bin"
+ bash test/e2e-v2/script/prepare/setup-e2e-shell/install-kubectl.sh
/tmp "${HOME}/.local/bin" v1.30.0
Review Comment:
The workflow passes `v1.30.0` as a third argument to `install-kubectl.sh`,
but the script currently ignores positional arg #3 and only reads `K8SVERSION`
from the environment. As a result, this step will still install the script’s
default kubectl version. Set `K8SVERSION=v1.30.0` (or update the script to
accept the version argument) so the intended version is installed.
```suggestion
K8SVERSION=v1.30.0 bash
test/e2e-v2/script/prepare/setup-e2e-shell/install-kubectl.sh /tmp
"${HOME}/.local/bin"
```
##########
banyand/internal/sidx/query.go:
##########
@@ -484,15 +483,17 @@ func extractOrdering(req QueryRequest) bool {
return req.Order.Sort != modelv1.Sort_SORT_DESC
}
-// selectPartsForQuery selects relevant parts from snapshot based on key range.
-func selectPartsForQuery(snap *Snapshot, minKey, maxKey int64) []*part {
+// selectPartsForQuery selects relevant parts from snapshot based on key range
and optional timestamp range.
+func selectPartsForQuery(snap *Snapshot, minKey, maxKey int64, minTS, maxTS
*int64) []*part {
var selectedParts []*part
-
for _, pw := range snap.parts {
- if pw.overlapsKeyRange(minKey, maxKey) {
- selectedParts = append(selectedParts, pw.p)
+ if !pw.overlapsKeyRange(minKey, maxKey) {
+ continue
}
+ if minTS != nil && maxTS != nil &&
!pw.overlapsTimestampRange(*minTS, *maxTS) {
+ continue
Review Comment:
Timestamp pruning is only applied when *both* `minTS` and `maxTS` are
non-nil. If a caller supplies only one bound (open-ended range), part selection
will ignore timestamps entirely and may scan/query irrelevant parts. Consider
supporting one-sided ranges (e.g., if `minTS != nil` then require
`part.MaxTimestamp >= *minTS`; if `maxTS != nil` then require
`part.MinTimestamp <= *maxTS`).
```suggestion
switch {
case minTS != nil && maxTS != nil:
if !pw.overlapsTimestampRange(*minTS, *maxTS) {
continue
}
case minTS != nil:
if !pw.overlapsTimestampRange(*minTS, math.MaxInt64) {
continue
}
case maxTS != nil:
if !pw.overlapsTimestampRange(math.MinInt64, *maxTS) {
continue
}
```
##########
banyand/internal/sidx/sidx.go:
##########
@@ -100,6 +100,8 @@ func (s *sidx) ConvertToMemPart(reqs []WriteRequest,
segmentID int64) (*MemPart,
mp := GenerateMemPart()
mp.mustInitFromElements(es)
mp.partMetadata.SegmentID = segmentID
+ mp.partMetadata.MinTimestamp = minTimestamp
+ mp.partMetadata.MaxTimestamp = maxTimestamp
return mp, nil
Review Comment:
`ConvertToMemPart` now accepts optional `minTimestamp/maxTimestamp` but
doesn’t validate their relationship. If callers accidentally pass `minTimestamp
> maxTimestamp`, the invalid manifest can be written (marshal doesn’t call
`partMetadata.validate()`), and later opens/reads will fail validation. Add a
check here (or in `mustWriteMetadata`/`marshal`) to reject invalid timestamp
ranges early.
##########
banyand/internal/sidx/scan_query.go:
##########
@@ -102,6 +105,21 @@ func (s *sidx) ScanQuery(ctx context.Context, req
ScanQueryRequest) ([]*QueryRes
return results, nil
}
+// selectPartsForScan selects parts that overlap key and optional timestamp
range for scan queries.
+func selectPartsForScan(snap *Snapshot, minKey, maxKey int64, minTS, maxTS
*int64) []*partWrapper {
+ var selected []*partWrapper
+ for _, pw := range snap.parts {
+ if !pw.overlapsKeyRange(minKey, maxKey) {
+ continue
+ }
+ if minTS != nil && maxTS != nil &&
!pw.overlapsTimestampRange(*minTS, *maxTS) {
+ continue
Review Comment:
Timestamp pruning is only applied when *both* `minTS` and `maxTS` are
non-nil. If a caller supplies only one bound (open-ended range), scans will
ignore timestamps entirely. Consider supporting one-sided timestamp ranges in
`selectPartsForScan` similarly to key range handling.
```suggestion
// Apply timestamp pruning when either bound is provided; treat
missing bounds as open-ended.
if minTS != nil || maxTS != nil {
from := int64(math.MinInt64)
to := int64(math.MaxInt64)
if minTS != nil {
from = *minTS
}
if maxTS != nil {
to = *maxTS
}
if !pw.overlapsTimestampRange(from, to) {
continue
}
```
##########
banyand/internal/sidx/timestamp_test.go:
##########
@@ -0,0 +1,394 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package sidx
+
+import (
+ "context"
+ "encoding/json"
+ "path/filepath"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/apache/skywalking-banyandb/api/common"
+ "github.com/apache/skywalking-banyandb/banyand/observability"
+ "github.com/apache/skywalking-banyandb/banyand/protector"
+ "github.com/apache/skywalking-banyandb/pkg/fs"
+)
+
+// writeTestDataWithTimeRange writes test data with optional min/max
timestamps (back-compat: nil means no timestamps).
+func writeTestDataWithTimeRange(t *testing.T, sidx SIDX, reqs []WriteRequest,
segmentID int64, partID uint64, minTS, maxTS *int64) {
+ t.Helper()
+ memPart, err := sidx.ConvertToMemPart(reqs, segmentID, minTS, maxTS)
+ require.NoError(t, err)
+ require.NotNil(t, memPart)
+ sidx.IntroduceMemPart(partID, memPart)
+}
+
+func ptrInt64Ts(v int64) *int64 {
+ val := v
+ return &val
+}
+
+// TestConvertToMemPart_Timestamps verifies ConvertToMemPart with and without
timestamps.
+func TestConvertToMemPart_Timestamps(t *testing.T) {
+ sidx := createTestSIDX(t)
+ defer func() {
+ assert.NoError(t, sidx.Close())
+ }()
+
+ reqs := []WriteRequest{
+ createTestWriteRequest(1, 1000, "data1"),
+ createTestWriteRequest(1, 2000, "data2"),
+ }
+
+ t.Run("nil_timestamps_back_compat", func(t *testing.T) {
+ mp, err := sidx.ConvertToMemPart(reqs, 1, nil, nil)
+ require.NoError(t, err)
+ require.NotNil(t, mp)
+ require.Nil(t, mp.partMetadata.MinTimestamp)
+ require.Nil(t, mp.partMetadata.MaxTimestamp)
+ ReleaseMemPart(mp)
+ })
+
+ t.Run("with_timestamps", func(t *testing.T) {
+ minTS := int64(500)
+ maxTS := int64(2500)
+ mp, err := sidx.ConvertToMemPart(reqs, 1, &minTS, &maxTS)
+ require.NoError(t, err)
+ require.NotNil(t, mp)
+ require.NotNil(t, mp.partMetadata.MinTimestamp)
+ require.NotNil(t, mp.partMetadata.MaxTimestamp)
+ assert.Equal(t, int64(500), *mp.partMetadata.MinTimestamp)
+ assert.Equal(t, int64(2500), *mp.partMetadata.MaxTimestamp)
+ ReleaseMemPart(mp)
+ })
+}
+
+// TestManifest_BackCompat verifies manifest.json omits timestamps when nil
(back-compat).
+func TestManifest_BackCompat(t *testing.T) {
+ dir := t.TempDir()
+ fileSystem := fs.NewLocalFileSystem()
+ opts := NewDefaultOptions()
+ opts.Memory = protector.NewMemory(observability.NewBypassRegistry())
+ opts.Path = dir
+
+ sidxIface, err := NewSIDX(fileSystem, opts)
+ require.NoError(t, err)
+ raw := sidxIface.(*sidx)
+ defer func() {
+ assert.NoError(t, raw.Close())
+ }()
+
+ reqs := []WriteRequest{
+ createTestWriteRequest(1, 100, "data"),
+ }
+
+ t.Run("manifest_without_timestamps", func(t *testing.T) {
+ writeTestDataWithTimeRange(t, raw, reqs, 1, 1, nil, nil)
+ flushIntro, err := raw.Flush(map[uint64]struct{}{1: {}})
+ require.NoError(t, err)
+ raw.IntroduceFlushed(flushIntro)
+ flushIntro.Release()
+
+ manifestPath := filepath.Join(dir, "0000000000000001",
manifestFilename)
+ data, readErr := fileSystem.Read(manifestPath)
+ require.NoError(t, readErr)
+
+ var m struct {
+ MinTimestamp *int64 `json:"minTimestamp,omitempty"`
+ MaxTimestamp *int64 `json:"maxTimestamp,omitempty"`
+ MinKey int64 `json:"minKey"`
+ MaxKey int64 `json:"maxKey"`
+ }
+ require.NoError(t, json.Unmarshal(data, &m))
+ require.Nil(t, m.MinTimestamp)
+ require.Nil(t, m.MaxTimestamp)
+ assert.Equal(t, int64(100), m.MinKey)
+ assert.Equal(t, int64(100), m.MaxKey)
+ })
+
+ t.Run("manifest_with_timestamps", func(t *testing.T) {
+ minTS := int64(1000)
+ maxTS := int64(2000)
+ writeTestDataWithTimeRange(t, raw, reqs, 2, 2, &minTS, &maxTS)
+ flushIntro, err := raw.Flush(map[uint64]struct{}{2: {}})
+ require.NoError(t, err)
+ raw.IntroduceFlushed(flushIntro)
+ flushIntro.Release()
+
+ manifestPath := filepath.Join(dir, "0000000000000002",
manifestFilename)
+ data, readErr := fileSystem.Read(manifestPath)
+ require.NoError(t, readErr)
+
+ var m struct {
+ MinTimestamp *int64 `json:"minTimestamp,omitempty"`
+ MaxTimestamp *int64 `json:"maxTimestamp,omitempty"`
+ }
+ require.NoError(t, json.Unmarshal(data, &m))
+ require.NotNil(t, m.MinTimestamp)
+ require.NotNil(t, m.MaxTimestamp)
+ assert.Equal(t, int64(1000), *m.MinTimestamp)
+ assert.Equal(t, int64(2000), *m.MaxTimestamp)
+ })
+}
+
+// TestQuery_TimestampSelection verifies timestamp-aware part selection and
key-range fallback.
+func TestQuery_TimestampSelection(t *testing.T) {
+ reqs := []WriteRequest{
+ createTestWriteRequest(1, 1000, "data1000"),
+ createTestWriteRequest(1, 2000, "data2000"),
+ }
+
+ t.Run("back_compat_key_range_only", func(t *testing.T) {
+ sidx := createTestSIDX(t)
+ defer func() {
+ assert.NoError(t, sidx.Close())
+ }()
+ writeTestDataWithTimeRange(t, sidx, reqs, 1, 1, nil, nil)
+ waitForIntroducerLoop()
+
+ minKey := int64(500)
+ maxKey := int64(2500)
+ qr := QueryRequest{
+ SeriesIDs: []common.SeriesID{1},
+ MinKey: &minKey,
+ MaxKey: &maxKey,
+ }
+ resultsCh, errCh := sidx.StreamingQuery(context.Background(),
qr)
+ var keys []int64
+ for res := range resultsCh {
+ require.NoError(t, res.Error)
+ keys = append(keys, res.Keys...)
+ }
+ select {
+ case err, ok := <-errCh:
+ if ok {
+ require.NoError(t, err)
+ }
+ default:
+ }
+ assert.GreaterOrEqual(t, len(keys), 0, "key-range filter should
work without timestamps")
+ })
+
+ t.Run("timestamp_filter_overlaps", func(t *testing.T) {
+ sidx := createTestSIDX(t)
+ defer func() {
+ assert.NoError(t, sidx.Close())
+ }()
+ minTS := ptrInt64Ts(1000)
+ maxTS := ptrInt64Ts(3000)
+ writeTestDataWithTimeRange(t, sidx, reqs, 1, 1, minTS, maxTS)
+ waitForIntroducerLoop()
+
+ qMinTS := ptrInt64Ts(1500)
+ qMaxTS := ptrInt64Ts(2500)
+ qr := QueryRequest{
+ SeriesIDs: []common.SeriesID{1},
+ MinTimestamp: qMinTS,
+ MaxTimestamp: qMaxTS,
+ }
+ resultsCh, errCh := sidx.StreamingQuery(context.Background(),
qr)
+ var count int
+ for res := range resultsCh {
+ require.NoError(t, res.Error)
+ count += res.Len()
+ }
+ select {
+ case err, ok := <-errCh:
+ if ok {
+ require.NoError(t, err)
+ }
+ default:
+ }
+ assert.GreaterOrEqual(t, count, 0, "query with overlapping
timestamp range")
+ })
+
+ t.Run("timestamp_filter_no_overlap_excludes_part", func(t *testing.T) {
+ sidx := createTestSIDX(t)
+ defer func() {
+ assert.NoError(t, sidx.Close())
+ }()
+ minTS := ptrInt64Ts(1000)
+ maxTS := ptrInt64Ts(2000)
+ writeTestDataWithTimeRange(t, sidx, reqs, 1, 1, minTS, maxTS)
+ waitForIntroducerLoop()
+
+ qMinTS := ptrInt64Ts(5000)
+ qMaxTS := ptrInt64Ts(6000)
+ qr := QueryRequest{
+ SeriesIDs: []common.SeriesID{1},
+ MinTimestamp: qMinTS,
+ MaxTimestamp: qMaxTS,
+ }
+ resultsCh, errCh := sidx.StreamingQuery(context.Background(),
qr)
+ var count int
+ for res := range resultsCh {
+ require.NoError(t, res.Error)
+ count += res.Len()
+ }
+ select {
+ case err, ok := <-errCh:
+ if ok {
+ require.NoError(t, err)
+ }
+ default:
+ }
+ assert.Equal(t, 0, count, "parts outside timestamp range should
be excluded")
+ })
+}
+
+// TestScanQuery_TimestampSelection verifies ScanQuery timestamp-aware part
selection.
+func TestScanQuery_TimestampSelection(t *testing.T) {
+ reqs := []WriteRequest{
+ createTestWriteRequest(1, 100, "data"),
+ }
+
+ t.Run("back_compat_no_timestamp_filter", func(t *testing.T) {
+ sidx := createTestSIDX(t)
+ defer func() {
+ assert.NoError(t, sidx.Close())
+ }()
+ writeTestDataWithTimeRange(t, sidx, reqs, 1, 1, nil, nil)
+ waitForIntroducerLoop()
+
+ sqr := ScanQueryRequest{}
+ res, err := sidx.ScanQuery(context.Background(), sqr)
+ require.NoError(t, err)
+ assert.GreaterOrEqual(t, len(res), 0)
Review Comment:
This scan test assertion `assert.GreaterOrEqual(t, len(res), 0)` is always
true and doesn’t verify correctness. Please assert expected non-empty results
(or expected row counts) for the back-compat scan case so the new
part-selection logic is actually exercised.
```suggestion
total := 0
for _, r := range res {
total += r.Len()
}
assert.Equal(t, 1, total, "expected one row from back-compat
scan without timestamp filter")
```
##########
banyand/internal/sidx/timestamp_test.go:
##########
@@ -0,0 +1,394 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package sidx
+
+import (
+ "context"
+ "encoding/json"
+ "path/filepath"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/apache/skywalking-banyandb/api/common"
+ "github.com/apache/skywalking-banyandb/banyand/observability"
+ "github.com/apache/skywalking-banyandb/banyand/protector"
+ "github.com/apache/skywalking-banyandb/pkg/fs"
+)
+
+// writeTestDataWithTimeRange writes test data with optional min/max
timestamps (back-compat: nil means no timestamps).
+func writeTestDataWithTimeRange(t *testing.T, sidx SIDX, reqs []WriteRequest,
segmentID int64, partID uint64, minTS, maxTS *int64) {
+ t.Helper()
+ memPart, err := sidx.ConvertToMemPart(reqs, segmentID, minTS, maxTS)
+ require.NoError(t, err)
+ require.NotNil(t, memPart)
+ sidx.IntroduceMemPart(partID, memPart)
+}
+
+func ptrInt64Ts(v int64) *int64 {
+ val := v
+ return &val
+}
+
+// TestConvertToMemPart_Timestamps verifies ConvertToMemPart with and without
timestamps.
+func TestConvertToMemPart_Timestamps(t *testing.T) {
+ sidx := createTestSIDX(t)
+ defer func() {
+ assert.NoError(t, sidx.Close())
+ }()
+
+ reqs := []WriteRequest{
+ createTestWriteRequest(1, 1000, "data1"),
+ createTestWriteRequest(1, 2000, "data2"),
+ }
+
+ t.Run("nil_timestamps_back_compat", func(t *testing.T) {
+ mp, err := sidx.ConvertToMemPart(reqs, 1, nil, nil)
+ require.NoError(t, err)
+ require.NotNil(t, mp)
+ require.Nil(t, mp.partMetadata.MinTimestamp)
+ require.Nil(t, mp.partMetadata.MaxTimestamp)
+ ReleaseMemPart(mp)
+ })
+
+ t.Run("with_timestamps", func(t *testing.T) {
+ minTS := int64(500)
+ maxTS := int64(2500)
+ mp, err := sidx.ConvertToMemPart(reqs, 1, &minTS, &maxTS)
+ require.NoError(t, err)
+ require.NotNil(t, mp)
+ require.NotNil(t, mp.partMetadata.MinTimestamp)
+ require.NotNil(t, mp.partMetadata.MaxTimestamp)
+ assert.Equal(t, int64(500), *mp.partMetadata.MinTimestamp)
+ assert.Equal(t, int64(2500), *mp.partMetadata.MaxTimestamp)
+ ReleaseMemPart(mp)
+ })
+}
+
+// TestManifest_BackCompat verifies manifest.json omits timestamps when nil
(back-compat).
+func TestManifest_BackCompat(t *testing.T) {
+ dir := t.TempDir()
+ fileSystem := fs.NewLocalFileSystem()
+ opts := NewDefaultOptions()
+ opts.Memory = protector.NewMemory(observability.NewBypassRegistry())
+ opts.Path = dir
+
+ sidxIface, err := NewSIDX(fileSystem, opts)
+ require.NoError(t, err)
+ raw := sidxIface.(*sidx)
+ defer func() {
+ assert.NoError(t, raw.Close())
+ }()
+
+ reqs := []WriteRequest{
+ createTestWriteRequest(1, 100, "data"),
+ }
+
+ t.Run("manifest_without_timestamps", func(t *testing.T) {
+ writeTestDataWithTimeRange(t, raw, reqs, 1, 1, nil, nil)
+ flushIntro, err := raw.Flush(map[uint64]struct{}{1: {}})
+ require.NoError(t, err)
+ raw.IntroduceFlushed(flushIntro)
+ flushIntro.Release()
+
+ manifestPath := filepath.Join(dir, "0000000000000001",
manifestFilename)
+ data, readErr := fileSystem.Read(manifestPath)
+ require.NoError(t, readErr)
+
+ var m struct {
+ MinTimestamp *int64 `json:"minTimestamp,omitempty"`
+ MaxTimestamp *int64 `json:"maxTimestamp,omitempty"`
+ MinKey int64 `json:"minKey"`
+ MaxKey int64 `json:"maxKey"`
+ }
+ require.NoError(t, json.Unmarshal(data, &m))
+ require.Nil(t, m.MinTimestamp)
+ require.Nil(t, m.MaxTimestamp)
+ assert.Equal(t, int64(100), m.MinKey)
+ assert.Equal(t, int64(100), m.MaxKey)
+ })
+
+ t.Run("manifest_with_timestamps", func(t *testing.T) {
+ minTS := int64(1000)
+ maxTS := int64(2000)
+ writeTestDataWithTimeRange(t, raw, reqs, 2, 2, &minTS, &maxTS)
+ flushIntro, err := raw.Flush(map[uint64]struct{}{2: {}})
+ require.NoError(t, err)
+ raw.IntroduceFlushed(flushIntro)
+ flushIntro.Release()
+
+ manifestPath := filepath.Join(dir, "0000000000000002",
manifestFilename)
+ data, readErr := fileSystem.Read(manifestPath)
+ require.NoError(t, readErr)
+
+ var m struct {
+ MinTimestamp *int64 `json:"minTimestamp,omitempty"`
+ MaxTimestamp *int64 `json:"maxTimestamp,omitempty"`
+ }
+ require.NoError(t, json.Unmarshal(data, &m))
+ require.NotNil(t, m.MinTimestamp)
+ require.NotNil(t, m.MaxTimestamp)
+ assert.Equal(t, int64(1000), *m.MinTimestamp)
+ assert.Equal(t, int64(2000), *m.MaxTimestamp)
+ })
+}
+
+// TestQuery_TimestampSelection verifies timestamp-aware part selection and
key-range fallback.
+func TestQuery_TimestampSelection(t *testing.T) {
+ reqs := []WriteRequest{
+ createTestWriteRequest(1, 1000, "data1000"),
+ createTestWriteRequest(1, 2000, "data2000"),
+ }
+
+ t.Run("back_compat_key_range_only", func(t *testing.T) {
+ sidx := createTestSIDX(t)
+ defer func() {
+ assert.NoError(t, sidx.Close())
+ }()
+ writeTestDataWithTimeRange(t, sidx, reqs, 1, 1, nil, nil)
+ waitForIntroducerLoop()
+
+ minKey := int64(500)
+ maxKey := int64(2500)
+ qr := QueryRequest{
+ SeriesIDs: []common.SeriesID{1},
+ MinKey: &minKey,
+ MaxKey: &maxKey,
+ }
+ resultsCh, errCh := sidx.StreamingQuery(context.Background(),
qr)
+ var keys []int64
+ for res := range resultsCh {
+ require.NoError(t, res.Error)
+ keys = append(keys, res.Keys...)
+ }
+ select {
+ case err, ok := <-errCh:
+ if ok {
+ require.NoError(t, err)
+ }
+ default:
+ }
+ assert.GreaterOrEqual(t, len(keys), 0, "key-range filter should
work without timestamps")
+ })
+
+ t.Run("timestamp_filter_overlaps", func(t *testing.T) {
+ sidx := createTestSIDX(t)
+ defer func() {
+ assert.NoError(t, sidx.Close())
+ }()
+ minTS := ptrInt64Ts(1000)
+ maxTS := ptrInt64Ts(3000)
+ writeTestDataWithTimeRange(t, sidx, reqs, 1, 1, minTS, maxTS)
+ waitForIntroducerLoop()
+
+ qMinTS := ptrInt64Ts(1500)
+ qMaxTS := ptrInt64Ts(2500)
+ qr := QueryRequest{
+ SeriesIDs: []common.SeriesID{1},
+ MinTimestamp: qMinTS,
+ MaxTimestamp: qMaxTS,
+ }
+ resultsCh, errCh := sidx.StreamingQuery(context.Background(),
qr)
+ var count int
+ for res := range resultsCh {
+ require.NoError(t, res.Error)
+ count += res.Len()
+ }
+ select {
+ case err, ok := <-errCh:
+ if ok {
+ require.NoError(t, err)
+ }
+ default:
+ }
+ assert.GreaterOrEqual(t, count, 0, "query with overlapping
timestamp range")
Review Comment:
These assertions don’t validate behavior: `assert.GreaterOrEqual(t, count,
0)` (and similar) will always pass. To ensure the timestamp-based selection
works, assert on concrete expected results (e.g., `count > 0` for the overlap
case, and specific key/data values where possible).
```suggestion
assert.Greater(t, count, 0, "query with overlapping timestamp
range")
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]