Skip to content

Commit

Permalink
pkg/parcacol: Fix potential schema inconsistencies
Browse files Browse the repository at this point in the history
Dynamic label names were not sorted, causing merging of them to create
unknown behavior and potentially cause inconsistent schemas.
  • Loading branch information
brancz committed Jun 30, 2022
1 parent a1d90dd commit d6ddb29
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 24 deletions.
3 changes: 3 additions & 0 deletions pkg/parcacol/ingest.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"context"
"errors"
"fmt"
"sort"

"github.com/go-kit/log"
"github.com/go-kit/log/level"
Expand Down Expand Up @@ -65,6 +66,8 @@ func separateNameFromLabels(ls labels.Labels) (string, labels.Labels, error) {
return "", nil, ErrMissingNameLabel
}

sort.Sort(out)

return name, out, nil
}

Expand Down
32 changes: 8 additions & 24 deletions pkg/parcacol/sample.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
"github.com/parca-dev/parca/pkg/profile"
)

// NormalizedProfileToParquetBuffer converts a normalized profile to a Parquet
// buffer. The passed labels must be sorted.
func NormalizedProfileToParquetBuffer(schema *dynparquet.Schema, ls labels.Labels, p *profile.NormalizedProfile) (*dynparquet.Buffer, error) {
names := labelNames(ls)
pprofLabels := profileLabelNames(p)
Expand All @@ -43,7 +45,6 @@ func NormalizedProfileToParquetBuffer(schema *dynparquet.Schema, ls labels.Label
r = SampleToParquetRow(
schema,
r[:0],
names,
pprofLabels,
pprofNumLabels,
ls,
Expand Down Expand Up @@ -103,10 +104,12 @@ func profileNumLabelNames(p *profile.NormalizedProfile) []string {
return names
}

// SampleToParquetRow converts a sample to a Parquet row. The passed labels
// must be sorted.
func SampleToParquetRow(
schema *dynparquet.Schema,
row parquet.Row,
labelNames, profileLabelNames, profileNumLabelNames []string,
profileLabelNames, profileNumLabelNames []string,
ls labels.Labels,
meta profile.Meta,
s *profile.NormalizedSample,
Expand Down Expand Up @@ -150,28 +153,9 @@ func SampleToParquetRow(

// All remaining cases take care of dynamic columns
case ColumnLabels:
labelNamesLen := len(labelNames)
i, j := 0, 0
for i < labelNamesLen {
if labelNames[i] == ls[j].Name {
value := parquet.ValueOf(ls[j].Value).Level(0, 1, columnIndex)
row = append(row, value)
columnIndex++
i++
j++

if j >= len(ls) {
for ; i < labelNamesLen; i++ {
row = append(row, parquet.ValueOf(nil).Level(0, 0, columnIndex))
}
break
}
} else {
// If nothing matches we add a NULL to the column
row = append(row, parquet.ValueOf(nil).Level(0, 0, columnIndex))
columnIndex++
i++
}
for _, label := range ls {
row = append(row, parquet.ValueOf(label.Value).Level(0, 1, columnIndex))
columnIndex++
}
case ColumnPprofLabels:
for _, name := range profileLabelNames {
Expand Down

0 comments on commit d6ddb29

Please sign in to comment.