Skip to content

Commit 54b7a64

Browse files
authored
Fix sidx tag filter range check issue (#991)
1 parent a9d081b commit 54b7a64

24 files changed

+541
-114
lines changed

.github/actions/build-docker-image/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ runs:
5454
ls -lh banyandb-testing-image.tar.gz
5555
5656
- name: Upload docker image artifact
57-
uses: actions/upload-artifact@v4
57+
uses: actions/upload-artifact@v7
5858
with:
5959
name: ${{ inputs.artifact-name }}
6060
path: banyandb-testing-image.tar.gz

.github/actions/setup-build-env/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ runs:
3232
steps:
3333
- name: Download build artifacts
3434
if: inputs.download-artifacts == 'true'
35-
uses: actions/download-artifact@v7
35+
uses: actions/download-artifact@v8
3636
with:
3737
name: build-artifacts
3838

.github/workflows/e2e.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,13 @@ jobs:
104104
df -h
105105
du -sh .
106106
docker images
107-
- uses: actions/upload-artifact@v4
107+
- uses: actions/upload-artifact@v7
108108
if: ${{ failure() }}
109109
name: Upload Logs
110110
with:
111111
name: test-logs-${{ matrix.test.name }}
112112
path: "${{ env.SW_INFRA_E2E_LOG_DIR }}"
113-
- uses: actions/upload-artifact@v4
113+
- uses: actions/upload-artifact@v7
114114
if: ${{ (failure() && matrix.test.name == 'Lifecycle') }}
115115
name: Upload generated data
116116
with:

.github/workflows/prepare.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ jobs:
5555
npm run build
5656
cd ..
5757
- name: Upload generated files
58-
uses: actions/upload-artifact@v6
58+
uses: actions/upload-artifact@v7
5959
with:
6060
name: build-artifacts
6161
path: |

.github/workflows/property-repair.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ jobs:
6464
if: ${{ failure() }}
6565
id: sanitize-name
6666
run: echo "sanitized=$(echo '${{ inputs.test-name }}' | sed 's/[^a-zA-Z0-9._-]/-/g')" >> $GITHUB_OUTPUT
67-
- uses: actions/upload-artifact@v4
67+
- uses: actions/upload-artifact@v7
6868
if: ${{ failure() }}
6969
name: Upload BanyanDB Data Folder
7070
with:

.github/workflows/test-integration-distributed.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
test-integration-distributed:
2424
strategy:
2525
matrix:
26-
tz: ["UTC", "Asia/Shanghai", "America/Los_Angeles"]
26+
tz: ["UTC", "America/Los_Angeles"]
2727
uses: ./.github/workflows/test.yml
2828
with:
2929
test-name: Integration Distributed

.github/workflows/test-integration-standalone.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
test-integration-standalone:
2424
strategy:
2525
matrix:
26-
tz: ["UTC", "Asia/Shanghai", "America/Los_Angeles"]
26+
tz: ["UTC", "America/Los_Angeles"]
2727
uses: ./.github/workflows/test.yml
2828
with:
2929
test-name: Integration Standalone

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ jobs:
7575
if: ${{ failure() }}
7676
id: sanitize-name
7777
run: echo "sanitized=$(echo '${{ inputs.test-name }}-${{ inputs.timezone }}' | sed 's/[^a-zA-Z0-9._-]/-/g')" >> $GITHUB_OUTPUT
78-
- uses: actions/upload-artifact@v4
78+
- uses: actions/upload-artifact@v7
7979
if: ${{ failure() }}
8080
name: Upload BanyanDB Data Folder
8181
with:

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Release Notes.
3838
- Fix the lifecycle panic when the trace has no sidx.
3939
- Fix panic in sidx merge and flush operations when part counts don't match expectations.
4040
- Fix trace queries with range conditions on the same tag (e.g., duration) combined with ORDER BY by deduplicating tag names when merging logical expression branches.
41+
- Fix sidx tag filter range check returning inverted skip decision and use correct int64 encoding for block min/max.
4142

4243
### Document
4344

banyand/cmd/dump/sidx.go

Lines changed: 98 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
"github.com/apache/skywalking-banyandb/banyand/internal/sidx"
4040
"github.com/apache/skywalking-banyandb/banyand/protector"
4141
"github.com/apache/skywalking-banyandb/pkg/convert"
42+
"github.com/apache/skywalking-banyandb/pkg/encoding"
4243
"github.com/apache/skywalking-banyandb/pkg/fs"
4344
"github.com/apache/skywalking-banyandb/pkg/index/inverted"
4445
"github.com/apache/skywalking-banyandb/pkg/logger"
@@ -797,6 +798,13 @@ func dumpSidxFullScan(sidxPath, segmentPath string, criteria *modelv1.Criteria,
797798
}
798799
}
799800

801+
// Discover projected tag value types so binary values (for example int64) can be rendered as readable values.
802+
projectionTagTypes, err := discoverProjectionTagTypes(sidxPath, projectionTagNames)
803+
if err != nil {
804+
fmt.Fprintf(os.Stderr, "Warning: failed to discover projection tag types: %v\n", err)
805+
projectionTagTypes = nil
806+
}
807+
800808
// Create dynamic tag registry if criteria is provided
801809
var tagRegistry *dynamicTagRegistry
802810
if criteria != nil {
@@ -878,9 +886,9 @@ func dumpSidxFullScan(sidxPath, segmentPath string, criteria *modelv1.Criteria,
878886

879887
// Output results
880888
if csvOutput {
881-
return outputScanResultsAsCSV(results, seriesMap, projectionTagNames, dataFilter)
889+
return outputScanResultsAsCSV(results, seriesMap, projectionTagNames, projectionTagTypes, dataFilter)
882890
}
883-
return outputScanResultsAsText(results, sidxPath, seriesMap, projectionTagNames, dataFilter)
891+
return outputScanResultsAsText(results, sidxPath, seriesMap, projectionTagNames, projectionTagTypes, dataFilter)
884892
}
885893

886894
// parseProjectionTags parses a comma-separated list of tag names.
@@ -939,7 +947,9 @@ func loadSeriesMap(segmentPath string) (map[common.SeriesID]string, error) {
939947
return seriesMap, nil
940948
}
941949

942-
func outputScanResultsAsText(results []*sidx.QueryResponse, sidxPath string, seriesMap map[common.SeriesID]string, projectionTagNames []string, dataFilter string) error {
950+
func outputScanResultsAsText(results []*sidx.QueryResponse, sidxPath string, seriesMap map[common.SeriesID]string,
951+
projectionTagNames []string, projectionTagTypes map[string]pbv1.ValueType, dataFilter string,
952+
) error {
943953
fmt.Printf("Opening sidx: %s\n", sidxPath)
944954
fmt.Printf("================================================================================\n\n")
945955

@@ -984,9 +994,9 @@ func outputScanResultsAsText(results []*sidx.QueryResponse, sidxPath string, ser
984994
if len(projectionTagNames) > 0 && resp.Tags != nil {
985995
for _, tagName := range projectionTagNames {
986996
if tagValues, ok := resp.Tags[tagName]; ok && i < len(tagValues) {
987-
tagValue := tagValues[i]
997+
tagValue := decodeProjectedTagValue(tagValues[i], projectionTagTypes[tagName])
988998
// Calculate size of the tag value
989-
tagSize := len(tagValue)
999+
tagSize := len(tagValues[i])
9901000
fmt.Printf(" %s: %s (size: %d bytes)\n", tagName, tagValue, tagSize)
9911001
}
9921002
}
@@ -1008,7 +1018,9 @@ func outputScanResultsAsText(results []*sidx.QueryResponse, sidxPath string, ser
10081018
return nil
10091019
}
10101020

1011-
func outputScanResultsAsCSV(results []*sidx.QueryResponse, seriesMap map[common.SeriesID]string, projectionTagNames []string, dataFilter string) error {
1021+
func outputScanResultsAsCSV(results []*sidx.QueryResponse, seriesMap map[common.SeriesID]string,
1022+
projectionTagNames []string, projectionTagTypes map[string]pbv1.ValueType, dataFilter string,
1023+
) error {
10121024
writer := csv.NewWriter(os.Stdout)
10131025
defer writer.Flush()
10141026

@@ -1058,9 +1070,9 @@ func outputScanResultsAsCSV(results []*sidx.QueryResponse, seriesMap map[common.
10581070

10591071
if resp.Tags != nil {
10601072
if tagValues, ok := resp.Tags[tagName]; ok && i < len(tagValues) {
1061-
tagValue = tagValues[i]
1073+
tagValue = decodeProjectedTagValue(tagValues[i], projectionTagTypes[tagName])
10621074
// Calculate size of the tag value
1063-
tagSize = fmt.Sprintf("%d", len(tagValue))
1075+
tagSize = fmt.Sprintf("%d", len(tagValues[i]))
10641076
}
10651077
}
10661078

@@ -1077,3 +1089,81 @@ func outputScanResultsAsCSV(results []*sidx.QueryResponse, seriesMap map[common.
10771089

10781090
return nil
10791091
}
1092+
1093+
func discoverProjectionTagTypes(sidxPath string, projectionTagNames []string) (map[string]pbv1.ValueType, error) {
1094+
if len(projectionTagNames) == 0 {
1095+
return nil, nil
1096+
}
1097+
partEntries, err := os.ReadDir(sidxPath)
1098+
if err != nil {
1099+
return nil, fmt.Errorf("failed to read sidx path %s: %w", sidxPath, err)
1100+
}
1101+
partPaths := make([]string, 0, len(partEntries))
1102+
for _, entry := range partEntries {
1103+
if !entry.IsDir() {
1104+
continue
1105+
}
1106+
partPaths = append(partPaths, filepath.Join(sidxPath, entry.Name()))
1107+
}
1108+
sort.Strings(partPaths)
1109+
1110+
result := make(map[string]pbv1.ValueType, len(projectionTagNames))
1111+
for _, tagName := range projectionTagNames {
1112+
for _, partPath := range partPaths {
1113+
tmPath := filepath.Join(partPath, tagName+".tm")
1114+
data, readErr := os.ReadFile(tmPath)
1115+
if readErr != nil {
1116+
continue
1117+
}
1118+
valueType, parseErr := parseSidxTagValueType(data)
1119+
if parseErr != nil {
1120+
fmt.Fprintf(os.Stderr, "Warning: failed to parse %s: %v\n", tmPath, parseErr)
1121+
break
1122+
}
1123+
result[tagName] = valueType
1124+
break
1125+
}
1126+
}
1127+
return result, nil
1128+
}
1129+
1130+
func parseSidxTagValueType(data []byte) (pbv1.ValueType, error) {
1131+
src, _, err := encoding.DecodeBytes(data)
1132+
if err != nil {
1133+
return pbv1.ValueTypeUnknown, fmt.Errorf("cannot decode tag name: %w", err)
1134+
}
1135+
if len(src) < 1 {
1136+
return pbv1.ValueTypeUnknown, fmt.Errorf("invalid tag metadata: missing value type")
1137+
}
1138+
return pbv1.ValueType(src[0]), nil
1139+
}
1140+
1141+
func decodeProjectedTagValue(raw string, valueType pbv1.ValueType) string {
1142+
if raw == "" {
1143+
return raw
1144+
}
1145+
rawBytes := []byte(raw)
1146+
1147+
switch valueType {
1148+
case pbv1.ValueTypeInt64:
1149+
if len(rawBytes) != 8 {
1150+
return raw
1151+
}
1152+
return strconv.FormatInt(convert.BytesToInt64(rawBytes), 10)
1153+
case pbv1.ValueTypeFloat64:
1154+
if len(rawBytes) != 8 {
1155+
return raw
1156+
}
1157+
return strconv.FormatFloat(convert.BytesToFloat64(rawBytes), 'f', -1, 64)
1158+
case pbv1.ValueTypeTimestamp:
1159+
if len(rawBytes) != 8 {
1160+
return raw
1161+
}
1162+
nanos := convert.BytesToInt64(rawBytes)
1163+
return strconv.FormatInt(nanos, 10)
1164+
case pbv1.ValueTypeBinaryData:
1165+
return fmt.Sprintf("%x", rawBytes)
1166+
default:
1167+
return raw
1168+
}
1169+
}

0 commit comments

Comments
 (0)