forked from TrueCloudLab/frostfs-sdk-go
[#xx] Add support for SELECT-FILTER expressions
Signed-off-by: Alejandro Lopez <a.lopez@yadro.com>
This commit is contained in:
parent
b9afe7a2f9
commit
b91f9d8c79
8 changed files with 556 additions and 170 deletions
|
@ -560,6 +560,44 @@ func (p *PlacementPolicy) DecodeString(s string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// SelectFilterExpr is an expression containing only selectors and filters.
|
||||
// It's useful to evaluate their effect before being used in a policy.
|
||||
type SelectFilterExpr struct {
|
||||
cbf uint32
|
||||
selector *netmap.Selector
|
||||
filters []netmap.Filter
|
||||
}
|
||||
|
||||
// DecodeString decodes a string into a SelectFilterExpr.
|
||||
// Returns an error if s is malformed.
|
||||
func DecodeSelectFilterString(s string) (*SelectFilterExpr, error) {
|
||||
var v policyVisitor
|
||||
|
||||
input := antlr.NewInputStream(s)
|
||||
lexer := parser.NewQueryLexer(input)
|
||||
lexer.RemoveErrorListeners()
|
||||
lexer.AddErrorListener(&v)
|
||||
stream := antlr.NewCommonTokenStream(lexer, 0)
|
||||
|
||||
pp := parser.NewQuery(stream)
|
||||
pp.BuildParseTrees = true
|
||||
|
||||
pp.RemoveErrorListeners()
|
||||
pp.AddErrorListener(&v)
|
||||
sfExpr := pp.SelectFilterExpr().Accept(&v)
|
||||
|
||||
if len(v.errors) != 0 {
|
||||
return nil, v.errors[0]
|
||||
}
|
||||
|
||||
parsed, ok := sfExpr.(*SelectFilterExpr)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected parsed instance type %T", sfExpr)
|
||||
}
|
||||
|
||||
return parsed, nil
|
||||
}
|
||||
|
||||
var (
|
||||
// errUnknownFilter is returned when a value of FROM in a query is unknown.
|
||||
errUnknownFilter = errors.New("filter not found")
|
||||
|
@ -636,6 +674,39 @@ func (p *policyVisitor) VisitPolicy(ctx *parser.PolicyContext) any {
|
|||
return pl
|
||||
}
|
||||
|
||||
func (p *policyVisitor) VisitSelectFilterExpr(ctx *parser.SelectFilterExprContext) any {
|
||||
if len(p.errors) != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
sfExpr := new(SelectFilterExpr)
|
||||
|
||||
if cbfStmt := ctx.CbfStmt(); cbfStmt != nil {
|
||||
cbf, ok := cbfStmt.(*parser.CbfStmtContext).Accept(p).(uint32)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
sfExpr.cbf = cbf
|
||||
}
|
||||
|
||||
if selStmt := ctx.SelectStmt(); selStmt != nil {
|
||||
sel, ok := selStmt.Accept(p).(*netmap.Selector)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
sfExpr.selector = sel
|
||||
}
|
||||
|
||||
filtStmts := ctx.AllFilterStmt()
|
||||
sfExpr.filters = make([]netmap.Filter, 0, len(filtStmts))
|
||||
|
||||
for _, f := range filtStmts {
|
||||
sfExpr.filters = append(sfExpr.filters, *f.Accept(p).(*netmap.Filter))
|
||||
}
|
||||
|
||||
return sfExpr
|
||||
}
|
||||
|
||||
func (p *policyVisitor) VisitCbfStmt(ctx *parser.CbfStmtContext) any {
|
||||
cbf, err := strconv.ParseUint(ctx.GetBackupFactor().GetText(), 10, 32)
|
||||
if err != nil {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue