github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/blockchain/query/filter/parser.go (about) 1 package filter 2 3 import ( 4 "fmt" 5 "strconv" 6 7 "github.com/bytom/bytom/errors" 8 ) 9 10 // ErrBadFilter is returned from Parse when 11 // it encounters an invalid filter expression. 12 var ErrBadFilter = errors.New("invalid query filter") 13 14 // Predicate represents a parsed filter predicate. 15 type Predicate struct { 16 expr expr 17 selectorTypes map[string]Type 18 Parameters int 19 } 20 21 // String returns a cleaned, canonical representation of the 22 // predicate. 23 func (p Predicate) String() string { 24 if p.expr == nil { 25 return "" 26 } 27 return p.expr.String() 28 } 29 30 // MarshalText implements the encoding.TextMarshaler interface and 31 // returns a cleaned, canonical representation of the predicate. 32 func (p Predicate) MarshalText() ([]byte, error) { 33 return []byte(p.expr.String()), nil 34 } 35 36 // Parse parses a predicate and returns an internal representation of the 37 // predicate or an error if it fails to parse. 38 func Parse(predicate string, tbl *Table, vals []interface{}) (p Predicate, err error) { 39 expr, parser, err := parse(predicate) 40 if err != nil { 41 return p, errors.WithDetail(ErrBadFilter, err.Error()) 42 } 43 selectorTypes, err := typeCheck(expr, tbl, vals) 44 if err != nil { 45 return p, errors.WithDetail(ErrBadFilter, err.Error()) 46 } 47 48 return Predicate{ 49 expr: expr, 50 selectorTypes: selectorTypes, 51 Parameters: parser.maxPlaceholder, 52 }, nil 53 } 54 55 // Field is a type for simple expressions that simply access an attribute of 56 // the queried object. They're used for GROUP BYs. 57 type Field struct { 58 expr expr 59 } 60 61 func (f Field) String() string { 62 return f.expr.String() 63 } 64 65 // ParseField parses a field expression (either an attrExpr or a selectorExpr). 66 func ParseField(s string) (f Field, err error) { 67 expr, _, err := parse(s) 68 if err != nil { 69 return f, errors.WithDetail(ErrBadFilter, err.Error()) 70 } 71 if expr == nil { 72 return f, errors.WithDetail(ErrBadFilter, "empty field expression") 73 } 74 75 switch expr.(type) { 76 case attrExpr, selectorExpr: 77 return Field{expr: expr}, nil 78 default: 79 return f, errors.WithDetailf(ErrBadFilter, "%q is not a valid field expression", s) 80 } 81 } 82 83 func parse(exprString string) (expr expr, parser *parser, err error) { 84 defer func() { 85 r := recover() 86 if perr, ok := r.(parseError); ok { 87 err = perr 88 } else if r != nil { 89 panic(r) 90 } 91 }() 92 parser = newParser([]byte(exprString)) 93 94 // An empty expression is a valid predicate. 95 if parser.tok == tokEOF { 96 return nil, parser, nil 97 } 98 99 expr = parseExpr(parser) 100 parser.parseTok(tokEOF) 101 return expr, parser, err 102 } 103 104 func newParser(src []byte) *parser { 105 p := new(parser) 106 p.scanner.init(src) 107 p.next() // advance onto the first input token 108 return p 109 } 110 111 // The parser structure holds the parser's internal state. 112 type parser struct { 113 scanner scanner 114 115 maxPlaceholder int 116 117 // Current token 118 pos int // token position 119 tok token // one token look-ahead 120 lit string // token literal 121 } 122 123 func determineBinaryOp(p *parser, minPrecedence int) (op *binaryOp, ok bool) { 124 op, ok = binaryOps[p.lit] 125 return op, ok && op.precedence >= minPrecedence 126 } 127 128 // next advances to the next token. 129 func (p *parser) next() { 130 p.pos, p.tok, p.lit = p.scanner.Scan() 131 } 132 133 func (p *parser) parseLit(lit string) { 134 if p.lit != lit { 135 p.errorf("got %s, expected %s", p.lit, lit) 136 } 137 p.next() 138 } 139 140 func (p *parser) parseTok(tok token) { 141 if p.tok != tok { 142 p.errorf("got %s, expected %s", p.lit, tok.String()) 143 } 144 p.next() 145 } 146 147 func parseExpr(p *parser) expr { 148 // Uses the precedence-climbing algorithm: 149 // https://en.wikipedia.org/wiki/Operator-precedence_parser#Precedence_climbing_method 150 expr := parsePrimaryExpr(p) 151 return parseExprCont(p, expr, 0) 152 } 153 154 func parseExprCont(p *parser, lhs expr, minPrecedence int) expr { 155 for { 156 op, ok := determineBinaryOp(p, minPrecedence) 157 if !ok { 158 break 159 } 160 p.next() 161 162 rhs := parsePrimaryExpr(p) 163 164 for { 165 op2, ok := determineBinaryOp(p, op.precedence+1) 166 if !ok { 167 break 168 } 169 rhs = parseExprCont(p, rhs, op2.precedence) 170 } 171 lhs = binaryExpr{l: lhs, r: rhs, op: op} 172 } 173 return lhs 174 } 175 176 func parsePrimaryExpr(p *parser) expr { 177 x := parseOperand(p) 178 for p.lit == "." { 179 x = parseSelectorExpr(p, x) 180 } 181 return x 182 } 183 184 func parseOperand(p *parser) expr { 185 switch { 186 case p.lit == "(": 187 p.next() 188 expr := parseExpr(p) 189 p.parseLit(")") 190 return parenExpr{inner: expr} 191 case p.tok == tokString: 192 v := valueExpr{typ: p.tok, value: p.lit} 193 p.next() 194 return v 195 case p.tok == tokInteger: 196 // Parse the literal into an integer so that we store the string 197 // representation of the *decimal* value, never the hex. 198 integer, err := strconv.ParseInt(p.lit, 0, 64) 199 if err != nil { 200 // can't happen; scanner guarantees it 201 p.errorf("invalid integer: %q", p.lit) 202 } 203 v := valueExpr{typ: p.tok, value: strconv.Itoa(int(integer))} 204 p.next() 205 return v 206 case p.tok == tokPlaceholder: 207 num, err := strconv.Atoi(p.lit[1:]) 208 if err != nil || num <= 0 { 209 p.errorf("invalid placeholder: %q", p.lit) 210 } 211 v := placeholderExpr{num: num} 212 p.next() 213 214 if num > p.maxPlaceholder { 215 p.maxPlaceholder = num 216 } 217 return v 218 default: 219 return parseEnvironmentExpr(p) 220 } 221 } 222 223 func parseSelectorExpr(p *parser, objExpr expr) expr { 224 p.next() // move past the '.' 225 226 ident := p.lit 227 p.parseTok(tokIdent) 228 return selectorExpr{ 229 ident: ident, 230 objExpr: objExpr, 231 } 232 } 233 234 func parseEnvironmentExpr(p *parser) expr { 235 name := p.lit 236 p.parseTok(tokIdent) 237 if p.lit != "(" { 238 return attrExpr{attr: name} 239 } 240 p.next() 241 expr := parseExpr(p) 242 p.parseLit(")") 243 return envExpr{ 244 ident: name, 245 expr: expr, 246 } 247 } 248 249 type parseError struct { 250 pos int 251 msg string 252 } 253 254 func (err parseError) Error() string { 255 return fmt.Sprintf("col %d: %s", err.pos, err.msg) 256 } 257 258 func (p *parser) errorf(format string, args ...interface{}) { 259 panic(parseError{pos: p.pos, msg: fmt.Sprintf(format, args...)}) 260 }