fix to-string for noop label filters (#8799)

Label Filter optimizations omit `.*` label filters from the execution
pipeline but intruduced a bug where those stages were also ommitted from
calls to `String` on the expression. This results in unparsable queries
and panics when queries are cloned via `query.String()`

This PR makes `noopLabelFilter` embed matchers and inherit their
`String` method just like the `StringLabelFilters` do
jdb/2023-03-update-doc.mk
Travis Patterson 3 years ago committed by GitHub
parent 22b672986a
commit 83ba93c867
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 23
      pkg/logql/log/label_filter.go
  2. 2
      pkg/logql/log/label_filter_test.go
  3. 4
      pkg/logql/syntax/ast.go
  4. 11
      pkg/logql/syntax/parser_test.go

@ -19,9 +19,6 @@ var (
_ LabelFilterer = &DurationLabelFilter{}
_ LabelFilterer = &NumericLabelFilter{}
_ LabelFilterer = &StringLabelFilter{}
// NoopLabelFilter is a label filter that doesn't filter out any values.
NoopLabelFilter = noopLabelFilter{}
)
// LabelFilterType is an enum for label filtering types.
@ -118,18 +115,26 @@ func (b *BinaryLabelFilter) String() string {
return sb.String()
}
type noopLabelFilter struct{}
type NoopLabelFilter struct {
*labels.Matcher
}
func (noopLabelFilter) String() string { return "" }
func (noopLabelFilter) Process(_ int64, line []byte, _ *LabelsBuilder) ([]byte, bool) {
func (NoopLabelFilter) Process(_ int64, line []byte, _ *LabelsBuilder) ([]byte, bool) {
return line, true
}
func (noopLabelFilter) RequiredLabelNames() []string { return []string{} }
func (NoopLabelFilter) RequiredLabelNames() []string { return []string{} }
func (f NoopLabelFilter) String() string {
if f.Matcher != nil {
return f.Matcher.String()
}
return ""
}
// ReduceAndLabelFilter Reduces multiple label filterer into one using binary and operation.
func ReduceAndLabelFilter(filters []LabelFilterer) LabelFilterer {
if len(filters) == 0 {
return NoopLabelFilter
return &NoopLabelFilter{}
}
if len(filters) == 1 {
return filters[0]
@ -340,7 +345,7 @@ func NewStringLabelFilter(m *labels.Matcher) LabelFilterer {
}
if f == TrueFilter {
return NoopLabelFilter
return &NoopLabelFilter{m}
}
return &lineFilterLabelFilter{

@ -318,7 +318,7 @@ func TestReduceAndLabelFilter(t *testing.T) {
filters []LabelFilterer
want LabelFilterer
}{
{"empty", nil, NoopLabelFilter},
{"empty", nil, &NoopLabelFilter{}},
{"1", []LabelFilterer{NewBytesLabelFilter(LabelFilterEqual, "foo", 5)}, NewBytesLabelFilter(LabelFilterEqual, "foo", 5)},
{
"2",

@ -82,7 +82,7 @@ func (m MultiStageExpr) stages() ([]log.Stage, error) {
if err != nil {
return nil, logqlmodel.NewStageError(e.String(), err)
}
if p == log.NoopStage || p == log.NoopLabelFilter {
if p == log.NoopStage {
continue
}
c = append(c, p)
@ -410,6 +410,8 @@ func (e *LabelFilterExpr) Stage() (log.Stage, error) {
switch ip := e.LabelFilterer.(type) {
case *log.IPLabelFilter:
return ip, ip.PatternError()
case *log.NoopLabelFilter:
return log.NoopStage, nil
}
return e.LabelFilterer, nil
}

@ -3409,3 +3409,14 @@ func TestParseLabels(t *testing.T) {
})
}
}
func TestNoOpLabelToString(t *testing.T) {
logExpr := `{container_name="app"} | foo=~".*"`
l, err := ParseLogSelector(logExpr, false)
require.NoError(t, err)
require.Equal(t, logExpr, l.String())
stages, err := l.(*PipelineExpr).MultiStages.stages()
require.NoError(t, err)
require.Len(t, stages, 0)
}

Loading…
Cancel
Save