//
// Expressions stack
//
// pushExpr pushes new expression to stack
359488
func (v *evalVisitor) pushExpr(expression *ast.Expression) {
	v.exprs = append(v.exprs, expression)
}
220435
func ReplaceExpr(root, from, to Expr) Expr {
	if root == from {
		return to
	}
	root.replace(from, to)
	return root
}
985949
func (ctx *Context) PushType(s interface{}) int {
	return ctx.PushGoFunction(func() {
		value := reflect.New(reflect.TypeOf(s))
		ctx.PushProxy(value.Interface())
	})
}
1064008
func (pb *primitiveBuilder) pushFilter(boolExpr sqlparser.Expr, whereType string) error {
	filters := splitAndExpression(nil, boolExpr)
	reorderBySubquery(filters)
	for _, filter := range filters {
		pullouts, origin, expr, err := pb.findOrigin(filter)
		if err != nil {
			return err
		}
		// The returned expression may be complex. Resplit before pushing.
		for _, subexpr := range splitAndExpression(nil, expr) {
			if err := pb.bldr.PushFilter(pb, subexpr, whereType, origin); err != nil {
				return err
			}
		}
		pb.addPullouts(pullouts)
	}
	return nil
}
1006448
func (l *Logger) PushPrefix(format string, a ...interface{}) {
	l.prefixStack = append(l.prefixStack, fmt.Sprintf(format, a...))
}
681770
func ConstructPositionExpr(p *driver.ParamMarkerExpr) *ast.PositionExpr {
	return &ast.PositionExpr{P: p}
}
217926
func (p *parser) pushRecovery(labels []string, expr interface{}) {
	if cap(p.recoveryStack) == len(p.recoveryStack) {
		// create new empty slot in the stack
		p.recoveryStack = append(p.recoveryStack, nil)
	} else {
		// slice to 1 more
		p.recoveryStack = p.recoveryStack[:len(p.recoveryStack)+1]
	}

	m := make(map[string]interface{}, len(labels))
	for _, fl := range labels {
		m[fl] = expr
	}
	p.recoveryStack[len(p.recoveryStack)-1] = m
}
405662
func (l *Lexer) Push(name string, state StateFn) {
	debugf("push %d %v", len(l.stack)+1, name)
	if len(l.stack) < 500 {
		l.stack = append(l.stack, NamedStateFn{name, state})
	} else {
		out := ""
		if len(l.input) > 200 {
			out = strings.Replace(l.input[0:199], "\n", " ", -1)
		} else {
			out = strings.Replace(l.input, "\n", " ", -1)
		}
		u.LogThrottle(u.WARN, 10, "Gracefully refusing to add more LexExpression: %s", out)
	}
}
1110068
func callExpr(fset *token.FileSet, nodes []ast.Node) *ast.CallExpr {
	for _, node := range nodes {
		callExpr, ok := node.(*ast.CallExpr)
		if ok {
			return callExpr
		}
	}
	return nil
}
804026
func Expr(query string, value ...interface{}) Builder {
	return &raw{Query: query, Value: value}
}
299910
func GenerateExpressionSequence(command string) (expressionSequence, error) {
	seq := expressionSequence{}
	if command == "" {
		return seq, nil
	}
	got, err := ParseReader("", strings.NewReader(command))
	if err != nil {
		return nil, err
	}
	for _, exp := range got.([]interface{}) {
		seq = append(seq, exp.(expression))
	}
	return seq, nil
}
89077
func NewKeyValueExpr(k, v Expr, pos Pos) *KeyValueExpr {
	return &KeyValueExpr{pos, k, v}
}
1112791
func (g *Generator) ExpressionType(e ast.Expr) (types.Type, error) {
	for _, info := range g.Program.AllPackages {
		if typesType := info.TypeOf(e); typesType != nil {
			return typesType, nil
		}
	}

	return nil, fmt.Errorf("expression not found: %+v", e)
}
601697
func (s *stack) Push(vs ...interface{}) {
	s.values = append(s.values, vs...)
}
1091007
func (la *LogicalAggregation) PredicatePushDown(predicates []expression.Expression) (ret []expression.Expression, retPlan LogicalPlan) {
	var condsToPush []expression.Expression
	exprsOriginal := make([]expression.Expression, 0, len(la.AggFuncs))
	for _, fun := range la.AggFuncs {
		exprsOriginal = append(exprsOriginal, fun.Args[0])
	}
	for _, cond := range predicates {
		switch cond.(type) {
		case *expression.Constant:
			condsToPush = append(condsToPush, cond)
			// Consider SQL list "select sum(b) from t group by a having 1=0". "1=0" is a constant predicate which should be
			// retained and pushed down at the same time. Because we will get a wrong query result that contains one column
			// with value 0 rather than an empty query result.
			ret = append(ret, cond)
		case *expression.ScalarFunction:
			extractedCols := expression.ExtractColumns(cond)
			ok := true
			for _, col := range extractedCols {
				if la.getGbyColIndex(col) == -1 {
					ok = false
					break
				}
			}
			if ok {
				newFunc := expression.ColumnSubstitute(cond, la.Schema(), exprsOriginal)
				condsToPush = append(condsToPush, newFunc)
			} else {
				ret = append(ret, cond)
			}
		default:
			ret = append(ret, cond)
		}
	}
	la.baseLogicalPlan.PredicatePushDown(condsToPush)
	return ret, la
}
1174144
func isPushableExpr(paramName string, expr semantic.Expression) (bool, error) {
	switch e := expr.(type) {
	case *semantic.LogicalExpression:
		b, err := isPushableExpr(paramName, e.Left)
		if err != nil {
			return false, err
		}

		if !b {
			return false, nil
		}

		return isPushableExpr(paramName, e.Right)

	case *semantic.BinaryExpression:
		if isPushablePredicate(paramName, e) {
			return true, nil
		}
	}

	return false, nil
}
1188886
func NewExpr(terms interface{}) *Expr {
	return &Expr{
		Negated: false,
		Terms:   terms,
		Index:   0,
		With:    nil,
	}
}