From 3fc26690258edd90739d98c6e7c1d28696a042dd Mon Sep 17 00:00:00 2001 From: "Steven L. Speek" Date: Fri, 20 Jun 2014 22:55:43 +0200 Subject: [PATCH] search: empty string values for attr and tag predicates Fixes issue_461 Change-Id: I94cba8be70f30eca456d990ba4f4db2618b24553 --- pkg/search/expr_test.go | 6 +++--- pkg/search/predicate.go | 32 ++++++++++++++++--------------- pkg/search/predicate_test.go | 37 ++++++++++++++++++++++++++++++++++++ pkg/search/query.go | 2 +- 4 files changed, 58 insertions(+), 19 deletions(-) diff --git a/pkg/search/expr_test.go b/pkg/search/expr_test.go index 91c0fc207..6c38a3966 100644 --- a/pkg/search/expr_test.go +++ b/pkg/search/expr_test.go @@ -572,9 +572,9 @@ var parseExpTests = []parserTestCase{ in: "attr:foo:", want: &Constraint{ Permanode: &PermanodeConstraint{ - Attr: "foo", - Value: "", - SkipHidden: true, + Attr: "foo", + ValueMatches: &StringConstraint{Empty: true}, + SkipHidden: true, }, }, }, diff --git a/pkg/search/predicate.go b/pkg/search/predicate.go index 4b8465aa3..eeb3931bd 100644 --- a/pkg/search/predicate.go +++ b/pkg/search/predicate.go @@ -238,13 +238,7 @@ func (a attribute) Description() string { } func (a attribute) Predicate(ctx *context.Context, args []string) (*Constraint, error) { - c := &Constraint{ - Permanode: &PermanodeConstraint{ - Attr: args[0], - SkipHidden: true, - Value: args[1], - }, - } + c := attrConst(args[0], args[1]) if strings.HasPrefix(args[1], "~") { // Substring. Hack. Figure out better way to do this. c.Permanode.Value = "" @@ -321,14 +315,7 @@ func (t tag) Description() string { } func (t tag) Predicate(ctx *context.Context, args []string) (*Constraint, error) { - c := &Constraint{ - Permanode: &PermanodeConstraint{ - Attr: "tag", - SkipHidden: true, - Value: args[0], - }, - } - return c, nil + return attrConst("tag", args[0]), nil } type title struct { @@ -571,6 +558,21 @@ func (h hasLocation) Predicate(ctx *context.Context, args []string) (*Constraint // Helpers +func attrConst(attr, val string) *Constraint { + c := &Constraint{ + Permanode: &PermanodeConstraint{ + Attr: attr, + SkipHidden: true, + }, + } + if val == "" { + c.Permanode.ValueMatches = &StringConstraint{Empty: true} + } else { + c.Permanode.Value = val + } + return c +} + func permOfFile(fc *FileConstraint) *Constraint { return &Constraint{ Permanode: &PermanodeConstraint{ diff --git a/pkg/search/predicate_test.go b/pkg/search/predicate_test.go index e32f34a66..04f7bc6a1 100644 --- a/pkg/search/predicate_test.go +++ b/pkg/search/predicate_test.go @@ -190,6 +190,18 @@ var keywordTests = []keywordTestcase{ want: attrfoobarC, }, + { + object: newAttribute(), + args: []string{"foo", ""}, + want: &Constraint{ + Permanode: &PermanodeConstraint{ + Attr: "foo", + ValueMatches: &StringConstraint{Empty: true}, + SkipHidden: true, + }, + }, + }, + { object: newAttribute(), args: []string{"foo", "~bar"}, @@ -255,6 +267,31 @@ var keywordTests = []keywordTestcase{ }, }, + { + object: newTag(), + args: []string{""}, + want: &Constraint{ + Permanode: &PermanodeConstraint{ + Attr: "tag", + ValueMatches: &StringConstraint{Empty: true}, + SkipHidden: true, + }, + }, + }, + + { + object: newTitle(), + args: []string{""}, + want: &Constraint{ + Permanode: &PermanodeConstraint{ + Attr: "title", + SkipHidden: true, + ValueMatches: &StringConstraint{ + CaseInsensitive: true, + }, + }}, + }, + { object: newTitle(), args: []string{"foo"}, diff --git a/pkg/search/query.go b/pkg/search/query.go index f47614795..53e883dc5 100644 --- a/pkg/search/query.go +++ b/pkg/search/query.go @@ -225,7 +225,7 @@ func (q *SearchQuery) checkValid(ctx *context.Context) (sq *SearchQuery, err err return nil, fmt.Errorf("Error parsing search expression %q: %v", expr, err) } if err := sq.Constraint.checkValid(); err != nil { - log.Fatalf("Internal error: parseExpression(%q) returned invalid constraint: %v", expr, err) + return nil, fmt.Errorf("Internal error: parseExpression(%q) returned invalid constraint: %v", expr, err) } return sq, nil }