// Expr convert the FuncNode to Expr
334790
func (m *FuncNode) Expr() *Expr {
	fe := &Expr{Op: lex.TokenUdfExpr.String()}
	if len(m.Args) > 0 {
		fe.Args = []*Expr{{Identity: m.Name}}
		fe.Args = append(fe.Args, ExprsFromNodes(m.Args)...)
	}
	return fe
}
973485
func (p *Parser) ParseExpr() (Expr, error) {
	var err error
	// Dummy root node.
	root := &BinaryExpr{}

	// Parse a non-binary expression type to start.
	// This variable will always be the root of the expression tree.
	root.RHS, err = p.parseUnaryExpr()
	if err != nil {
		return nil, err
	}

	// Loop over operations and unary exprs and build a tree based on precendence.
	for {
		// If the next token is NOT an operator then return the expression.
		op, _, _ := p.ScanIgnoreWhitespace()
		if !op.isOperator() {
			p.Unscan()
			return root.RHS, nil
		}

		// Otherwise parse the next expression.
		var rhs Expr
		if IsRegexOp(op) {
			// RHS of a regex operator must be a regular expression.
			if rhs, err = p.parseRegex(); err != nil {
				return nil, err
			}
			// parseRegex can return an empty type, but we need it to be present
			if rhs.(*RegexLiteral) == nil {
				tok, pos, lit := p.ScanIgnoreWhitespace()
				return nil, newParseError(tokstr(tok, lit), []string{"regex"}, pos)
			}
		} else {
			if rhs, err = p.parseUnaryExpr(); err != nil {
				return nil, err
			}
		}

		// Find the right spot in the tree to add the new expression by
		// descending the RHS of the expression tree until we reach the last
		// BinaryExpr or a BinaryExpr whose RHS has an operator with
		// precedence >= the operator being added.
		for node := root; ; {
			r, ok := node.RHS.(*BinaryExpr)
			if !ok || r.Op.Precedence() >= op.Precedence() {
				// Add the new expression here and break.
				node.RHS = &BinaryExpr{LHS: node.RHS, RHS: rhs, Op: op}
				break
			}
			node = r
		}
	}
}
1183681
func (exp *TernaryIfExpr) All() []Node {
	return []Node{exp.Cond, exp.TrueX, exp.FalseX}
}
1178216
func CloneExpr(expr Expr) Expr {
	if expr == nil {
		return nil
	}
	switch expr := expr.(type) {
	case *BinaryExpr:
		return &BinaryExpr{Op: expr.Op, LHS: CloneExpr(expr.LHS), RHS: CloneExpr(expr.RHS)}
	case *BooleanLiteral:
		return &BooleanLiteral{Val: expr.Val}
	case *Call:
		args := make([]Expr, len(expr.Args))
		for i, arg := range expr.Args {
			args[i] = CloneExpr(arg)
		}
		return &Call{Name: expr.Name, Args: args}
	case *Distinct:
		return &Distinct{Val: expr.Val}
	case *DurationLiteral:
		return &DurationLiteral{Val: expr.Val}
	case *IntegerLiteral:
		return &IntegerLiteral{Val: expr.Val}
	case *UnsignedLiteral:
		return &UnsignedLiteral{Val: expr.Val}
	case *NumberLiteral:
		return &NumberLiteral{Val: expr.Val}
	case *ParenExpr:
		return &ParenExpr{Expr: CloneExpr(expr.Expr)}
	case *RegexLiteral:
		return &RegexLiteral{Val: expr.Val}
	case *StringLiteral:
		return &StringLiteral{Val: expr.Val}
	case *TimeLiteral:
		return &TimeLiteral{Val: expr.Val}
	case *VarRef:
		return &VarRef{Val: expr.Val, Type: expr.Type}
	case *Wildcard:
		return &Wildcard{Type: expr.Type}
	}
	panic("unreachable")
}
147609
func (c Command) Expression() *regexp.Regexp {
	expr := c.Text()

	for _, param := range c.Parameters() {
		expr = strings.Replace(expr, "<"+param.Name()+":"+param.Data()+">", "("+param.Expression().String()+")", -1)
		expr = strings.Replace(expr, "<"+param.Name()+">", "("+param.Expression().String()+")", -1)
	}

	return regexp.MustCompile("^" + expr + "$")
}
1367037
func (node *IsExpr) Format(buf *TrackedBuffer) {
	buf.Myprintf("%v %s", node.Expr, node.Operator)
}
1245967
func (p *parser) parseUnaryExpr(n node) node {
	minus := false
	// ignore '-' sequence
	for p.r.typ == itemMinus {
		p.next()
		minus = !minus
	}
	opnd := p.parseUnionExpr(n)
	if minus {
		opnd = newOperatorNode("*", opnd, newOperandNode(float64(-1)))
	}
	return opnd
}
918757
func EvaluateExprWithNull(ctx sessionctx.Context, schema *Schema, expr Expression) Expression {
	switch x := expr.(type) {
	case *ScalarFunction:
		args := make([]Expression, len(x.GetArgs()))
		for i, arg := range x.GetArgs() {
			args[i] = EvaluateExprWithNull(ctx, schema, arg)
		}
		return NewFunctionInternal(ctx, x.FuncName.L, types.NewFieldType(mysql.TypeTiny), args...)
	case *Column:
		if !schema.Contains(x) {
			return x
		}
		return &Constant{Value: types.Datum{}, RetType: types.NewFieldType(mysql.TypeNull)}
	case *Constant:
		if x.DeferredExpr != nil {
			return FoldConstant(x)
		}
	}
	return expr
}
991268
func NewExpression(Expr node.Node) *Expression {
	return &Expression{
		FreeFloating: nil,
		Expr:         Expr,
	}
}
978160
func (t *Tree) parseExpr() (Expr, error) {
	expr, err := t.parseInnerExpr()
	if err != nil {
		return nil, err
	}

	return t.parseOuterExpr(expr)
}
549815
func (exp *FuncExpr) String() string {
	return fmt.Sprintf("FuncExpr(%s, %s)", exp.Name, exp.Args)
}
504616
func (evt *Event) HasExpr() bool {
	_, ok := evt.Node.(*ast.Expr)
	return ok
}
60648
func unconstNode(expr Expr) Expr {
	// Special case for non-const builtin calls which must have their args unconsted
	if e, ok := expr.(*CallExpr); ok && (e.IsConst() || e.isBuiltin) {
		u := new(CallExpr)
		*u = *e
		u.constValue = constValue{}
		if u.isBuiltin {
			u.CallExpr = new(ast.CallExpr)
			*u.CallExpr = *e.CallExpr
			u.Args = make([]Expr, len(e.Args))
			for i := range e.Args {
				if e.Args[i].IsConst(); ok {
					u.Args[i] = unconstNode(e.Args[i])
				} else {
					u.Args[i] = e.Args[i]
				}
			}
		}
		return u
	}

	if !expr.IsConst() {
		return expr
	}
	switch e := expr.(type) {
	case *Ident:
		u := new(Ident)
		*u = *e
		u.constValue = constValue{}
		return u
	case *BasicLit:
		u := new(BasicLit)
		*u = *e
		u.constValue = constValue{}
		return u
	case *SelectorExpr:
		u := new(SelectorExpr)
		*u = *e
		u.constValue = constValue{}
		return u
	case *IndexExpr:
		u := new(IndexExpr)
		*u = *e
		u.constValue = constValue{}
		return u
	case *UnaryExpr:
		u := new(UnaryExpr)
		*u = *e
		u.constValue = constValue{}
		return u
	case *BinaryExpr:
		u := new(BinaryExpr)
		*u = *e
		u.constValue = constValue{}
		return u
	default:
		panic("eval: impossible. non-const node IsConst() returned true")
	}
}
840219
func Regexp(expr string) (func(string) bool, error) {
	if expr == "" {
		return nil, fmt.Errorf("empty regex expression")
	}

	// add the last $ if missing (and not wildcard(?))
	if i := expr[len(expr)-1]; i != '$' && i != '*' {
		expr += "$"
	}

	r, err := regexp.Compile(expr)
	if err != nil {
		return nil, err
	}

	return r.MatchString, nil
}
256942
func (t *Tree) parseOuterExpr(expr Expr) (Expr, error) {
	switch nt := t.nextNonSpace(); nt.tokenType {
	case tokenParensOpen:
		switch name := expr.(type) {
		case *NameExpr:
			// TODO: This duplicates some code in parseInnerExpr, are both necessary?
			return t.parseFunc(name)
		default:
			return nil, newUnexpectedTokenError(nt)
		}

	case tokenArrayOpen, tokenPunctuation:
		switch nt.value {
		case ".", "[": // Dot or array access
			var args = make([]Expr, 0)
			attr, err := t.parseInnerExpr()
			if err != nil {
				return nil, err
			}

			if nt.value == "[" {
				switch attr.(type) {
				case *NameExpr, *StringExpr, *NumberExpr, *GroupExpr:
					// valid
				default:
					return nil, newUnexpectedTokenError(nt)
				}

				_, err := t.expect(tokenArrayClose)
				if err != nil {
					return nil, err
				}
			} else {
				switch exp := attr.(type) {
				case *NameExpr:
					// valid, but we want to treat the name as a string
					attr = NewStringExpr(exp.Name, exp.Pos)
				case *NumberExpr:
					// Compatibility with Twig: {{ val.0 }}
					attr = NewStringExpr(exp.Value, exp.Pos)
				case *FuncExpr:
					// method call
					for _, v := range exp.Args {
						args = append(args, v)
					}
					attr = NewStringExpr(exp.Name, exp.Pos)
				default:
					return nil, newUnexpectedTokenError(nt)
				}
			}
			return t.parseOuterExpr(NewGetAttrExpr(expr, attr, args, nt.Pos))

		case "|": // Filter application
			nx, err := t.parseExpr()
			if err != nil {
				return nil, err
			}
			switch n := nx.(type) {
			case *NameExpr:
				return NewFilterExpr(n.Name, []Expr{expr}, nt.Pos), nil

			case *FuncExpr:
				n.Args = append([]Expr{expr}, n.Args...)
				return NewFilterExpr(n.Name, n.Args, n.Pos), nil

			default:
				return nil, newUnexpectedTokenError(nt)
			}

		case "?": // Ternary if
			tx, err := t.parseExpr()
			if err != nil {
				return nil, err
			}
			_, err = t.expectValue(tokenPunctuation, ":")
			if err != nil {
				return nil, err
			}
			fx, err := t.parseExpr()
			if err != nil {
				return nil, err
			}
			return NewTernaryIfExpr(expr, tx, fx, expr.Start()), nil

		default:
			t.backup()
			return expr, nil
		}

	case tokenOperator:
		op, ok := binaryOperators[nt.value]
		if !ok {
			return nil, newUnexpectedTokenError(nt)
		}

		var right Node
		var err error
		if op.op == OpBinaryIs || op.op == OpBinaryIsNot {
			right, err = t.parseRightTestOperand(nil)
			if err != nil {
				return nil, err
			}
		} else {
			right, err = t.parseInnerExpr()
			if err != nil {
				return nil, err
			}
		}

		ntt := t.nextNonSpace()
		if ntt.tokenType == tokenOperator {
			nxop, ok := binaryOperators[ntt.value]
			if !ok {
				return nil, newUnexpectedTokenError(ntt)
			}
			if nxop.precedence < op.precedence || (nxop.precedence == op.precedence && op.leftAssoc()) {
				t.backup()
				return t.parseOuterExpr(NewBinaryExpr(expr, op.Operator(), right, expr.Start()))
			}
			t.backup()
			right, err = t.parseOuterExpr(right)
			if err != nil {
				return nil, err
			}
		} else {
			t.backup()
		}
		return NewBinaryExpr(expr, op.Operator(), right, expr.Start()), nil

	default:
		t.backup()
		return expr, nil
	}
}
796846
func (m *rewrite) walkNode(cur expr.Node) (expr.Node, error) {
	//u.Debugf("WalkNode: %#v", cur)
	switch curNode := cur.(type) {
	case *expr.NumberNode, *expr.StringNode:
		return curNode, nil
	case *expr.BinaryNode:
		return m.walkFilterBinary(curNode)
	case *expr.TriNode: // Between
		return m.walkFilterTri(curNode)
	case *expr.UnaryNode:
		//return m.walkUnary(curNode)
		u.Warnf("not implemented: %#v", curNode)
		return nil, fmt.Errorf("Not implemented urnary function: %v", curNode.String())
	case *expr.FuncNode:
		return m.walkFilterFunc(curNode)
	case *expr.IdentityNode:
		u.Warnf("we are trying to project?   %v", curNode.String())
		return curNode, nil
	case *expr.ArrayNode:
		return m.walkArrayNode(curNode)
	default:
		u.Debugf("unrecognized T:%T  %v", cur, cur)
	}

	return cur, nil
}
510429
func (expr *Expr) Complement() *Expr {
	cpy := *expr
	cpy.Negated = !cpy.Negated
	return &cpy
}