From 5f800458a397607e44e890c2fe91e9cb784e9bf0 Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Wed, 24 Feb 2021 17:02:50 +0300 Subject: [PATCH] [#410] pkg/policy: Parse strings in filter key With UN/LOCODE support, storage node may have `UN-LOCODE` attribute. Policy parser should support both `Ident` and `Strings` as filter keys to parse rules such as `FILTER "UN-LOCODE" EQ "RU LED" AS F`. Signed-off-by: Alex Vanin --- pkg/policy/grammar.ebnf | 5 ++++- pkg/policy/grammar.go | 2 +- pkg/policy/query_test.go | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) 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)