[#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 <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2021-02-24 17:02:50 +03:00 committed by Alex Vanin
parent 5900975d58
commit 5f800458a3
3 changed files with 26 additions and 2 deletions

View file

@ -36,12 +36,15 @@ AndChain ::=
Expr ::= Expr ::=
'@' Ident (* filter reference *) '@' Ident (* filter reference *)
| Ident, Op, Value (* attribute filter *) | Key, Op, Value (* attribute filter *)
; ;
Op ::= 'EQ' | 'NE' | 'GE' | 'GT' | 'LT' | 'LE' Op ::= 'EQ' | 'NE' | 'GE' | 'GT' | 'LT' | 'LE'
; ;
Key ::= Ident | String
;
Value ::= Ident | Number | String Value ::= Ident | Number | String
; ;

View file

@ -52,7 +52,7 @@ type andChain struct {
} }
type simpleExpr struct { type simpleExpr struct {
Key string `@Ident` Key string `@(Ident | String)`
// We don't use literals here to improve error messages. // We don't use literals here to improve error messages.
Op string `@Ident` Op string `@Ident`
Value string `@(Ident | String | Int)` Value string `@(Ident | String | Int)`

View file

@ -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 { func newFilter(name, key, value string, op netmap.Operation, sub ...*netmap.Filter) *netmap.Filter {
f := new(netmap.Filter) f := new(netmap.Filter)
f.SetName(name) f.SetName(name)