diff --git a/pkg/policy/grammar.ebnf b/pkg/policy/grammar.ebnf index a27c9cf6..2bcd3a20 100644 --- a/pkg/policy/grammar.ebnf +++ b/pkg/policy/grammar.ebnf @@ -36,12 +36,15 @@ AndChain ::= Expr ::= '@' Ident (* filter reference *) - | Ident, Op, Value (* attribute filter *) + | Key, Op, Value (* attribute filter *) ; Op ::= 'EQ' | 'NE' | 'GE' | 'GT' | 'LT' | 'LE' ; +Key ::= Ident | String +; + Value ::= Ident | Number | String ; diff --git a/pkg/policy/grammar.go b/pkg/policy/grammar.go index 0a7ce7f9..3c695277 100644 --- a/pkg/policy/grammar.go +++ b/pkg/policy/grammar.go @@ -52,7 +52,7 @@ type andChain struct { } type simpleExpr struct { - Key string `@Ident` + Key string `@(Ident | String)` // We don't use literals here to improve error messages. Op string `@Ident` Value string `@(Ident | String | Int)` diff --git a/pkg/policy/query_test.go b/pkg/policy/query_test.go index a3c9ad50..b7c4cc76 100644 --- a/pkg/policy/query_test.go +++ b/pkg/policy/query_test.go @@ -235,6 +235,27 @@ func TestValidation(t *testing.T) { } +func TestFilterStringSymbols(t *testing.T) { + q := `REP 1 IN S +SELECT 1 FROM F AS S +FILTER "UN-LOCODE" EQ "RU LED" AS F` + + expected := new(netmap.PlacementPolicy) + expected.SetReplicas([]*netmap.Replica{ + newReplica("S", 1), + }) + expected.SetSelectors([]*netmap.Selector{ + newSelector(1, netmap.UnspecifiedClause, "", "F", "S"), + }) + expected.SetFilters([]*netmap.Filter{ + newFilter("F", "UN-LOCODE", "RU LED", netmap.EQ), + }) + + r, err := Parse(q) + require.NoError(t, err) + require.EqualValues(t, expected, r) +} + func newFilter(name, key, value string, op netmap.Operation, sub ...*netmap.Filter) *netmap.Filter { f := new(netmap.Filter) f.SetName(name)