// MultiplicativeExpr ::= UnaryExpr	| MultiplicativeExpr MultiplyOperator(*) UnaryExpr
//						| MultiplicativeExpr 'div' UnaryExpr | MultiplicativeExpr 'mod' UnaryExpr
542788
func (p *parser) parseMultiplicativeExpr(n node) node {
	opnd := p.parseUnaryExpr(n)
Loop:
	for {
		var op string
		if p.r.typ == itemStar {
			op = "*"
		} else if testOp(p.r, "div") || testOp(p.r, "mod") {
			op = p.r.name
		} else {
			break Loop
		}
		p.next()
		opnd = newOperatorNode(op, opnd, p.parseUnaryExpr(n))
	}
	return opnd
}
829568
func MultiplierCross(vars ...int) featureCross {
	name := ""
	for i, v := range vars {
		name += strconv.Itoa(v)
		if i < (len(vars) - 1) {
			name += "*"
		}
	}

	return &functionalCross{
		functionName: name,
		boundVars:    vars,
		crossFn: func(input []float64) []float64 {
			var output float64 = 1
			for _, variableIndex := range vars {
				output *= input[variableIndex]
			}
			return []float64{output}
		},
	}
}
263340
func (pc PbConverter) ExprToPB(expr Expression) *tipb.Expr {
	switch x := expr.(type) {
	case *Constant, *CorrelatedColumn:
		return pc.conOrCorColToPBExpr(expr)
	case *Column:
		return pc.columnToPBExpr(x)
	case *ScalarFunction:
		return pc.scalarFuncToPBExpr(x)
	}
	return nil
}
20788
func (p *parser) parseFilterExpr(n node) node {
	opnd := p.parsePrimaryExpr(n)
	if p.r.typ == itemLBracket {
		opnd = newFilterNode(opnd, p.parsePredicate(opnd))
	}
	return opnd
}
1169264
func SplitExtension(name string) (
	assertions, extensionSuffix string, err error) {
	names := strings.SplitN(name, HandleExtensionSep, 2)
	if len(names) > 2 {
		return "", "", BadNameError{name}
	}
	if len(names) > 1 {
		extensionSuffix = names[1]
	}
	return names[0], extensionSuffix, nil
}
762683
func ProductConstraint(attr ...IntegerAttribute) ArithmeticConstraint {
	attribute := make([]Attribute, len(attr))
	for i, a := range attr {
		attribute[i] = Attribute(a)
	}
	return NewArithmeticConstraint(MULT_OP, attribute, nil)
}
315480
func (b ValExprBuilder) NotRegExp(val interface{}) BoolExprBuilder {
	return b.makeComparisonExpr(astNotRegExp, makeValExpr(val))
}
1153521
func sumUntilIndex(s []uint32, idx int) uint64 {
	var cumSum uint64
	var i int
	for i = idx - 1; i >= 3; i -= 4 {
		cumSum += uint64(s[i])
		cumSum += uint64(s[i-1])
		cumSum += uint64(s[i-2])
		cumSum += uint64(s[i-3])
	}
	for ; i >= 0; i-- {
		cumSum += uint64(s[i])
	}
	return cumSum
}
1290593
func (fcomp *fcomp) plus(e *syntax.BinaryExpr) {
	// Gather all the right operands of the left tree of plusses.
	// A tree (((a+b)+c)+d) becomes args=[a +b +c +d].
	args := make([]summand, 0, 2) // common case: 2 operands
	for plus := e; ; {
		args = append(args, summand{unparen(plus.Y), plus.OpPos})
		left := unparen(plus.X)
		x, ok := left.(*syntax.BinaryExpr)
		if !ok || x.Op != syntax.PLUS {
			args = append(args, summand{x: left})
			break
		}
		plus = x
	}
	// Reverse args to syntactic order.
	for i, n := 0, len(args)/2; i < n; i++ {
		j := len(args) - 1 - i
		args[i], args[j] = args[j], args[i]
	}

	// Fold sums of adjacent literals of the same type: ""+"", []+[], ()+().
	out := args[:0] // compact in situ
	for i := 0; i < len(args); {
		j := i + 1
		if code := addable(args[i].x); code != 0 {
			for j < len(args) && addable(args[j].x) == code {
				j++
			}
			if j > i+1 {
				args[i].x = add(code, args[i:j])
			}
		}
		out = append(out, args[i])
		i = j
	}
	args = out

	// Emit code for an n-ary sum (n > 0).
	fcomp.expr(args[0].x)
	for _, summand := range args[1:] {
		fcomp.expr(summand.x)
		fcomp.setPos(summand.plusPos)
		fcomp.emit(PLUS)
	}

	// If len(args) > 2, use of an accumulator instead of a chain of
	// PLUS operations may be more efficient.
	// However, no gain was measured on a workload analogous to Bazel loading;
	// TODO(adonovan): opt: re-evaluate on a Bazel analysis-like workload.
	//
	// We cannot use a single n-ary SUM operation
	//    a b c SUM<3>
	// because we need to report a distinct error for each
	// individual '+' operation, so three additional operations are
	// needed:
	//
	//   ACCSTART => create buffer and append to it
	//   ACCUM    => append to buffer
	//   ACCEND   => get contents of buffer
	//
	// For string, list, and tuple values, the interpreter can
	// optimize these operations by using a mutable buffer.
	// For all other types, ACCSTART and ACCEND would behave like
	// the identity function and ACCUM behaves like PLUS.
	// ACCUM must correctly support user-defined operations
	// such as list+foo.
	//
	// fcomp.emit(ACCSTART)
	// for _, summand := range args[1:] {
	// 	fcomp.expr(summand.x)
	// 	fcomp.setPos(summand.plusPos)
	// 	fcomp.emit(ACCUM)
	// }
	// fcomp.emit(ACCEND)
}
127264
func unaryOpExp(rate int8, in Input, numOutputs int) Input {
	CheckRate(rate)
	return NewInput(UnaryOpUgenName, rate, UnaryOpExp, numOutputs, in)
}
1360225
func (e BoolExprBuilder) Or(expr BoolExpr) BoolExprBuilder {
	var conditions []BoolExpr

	if orExpr, ok := e.BoolExpr.(*OrExpr); ok {
		conditions = append(conditions, orExpr.Exprs...)
	} else {
		conditions = append(conditions, e.BoolExpr)
	}

	unwrapped := unwrapBoolExpr(expr)
	if orExpr, ok := unwrapped.(*OrExpr); ok {
		conditions = append(conditions, orExpr.Exprs...)
	} else {
		conditions = append(conditions, unwrapped)
	}

	return BoolExprBuilder{
		&OrExpr{
			Op:    astOrExpr,
			Exprs: conditions,
		}}
}
788796
func (v *evalVisitor) popExpr() *ast.Expression {
	if len(v.exprs) == 0 {
		return nil
	}

	var result *ast.Expression
	result, v.exprs = v.exprs[len(v.exprs)-1], v.exprs[:len(v.exprs)-1]

	return result
}
674072
func RemoveDupExprs(ctx sessionctx.Context, exprs []Expression) []Expression {
	res := make([]Expression, 0, len(exprs))
	exists := make(map[string]struct{}, len(exprs))
	sc := ctx.GetSessionVars().StmtCtx
	for _, expr := range exprs {
		key := string(expr.HashCode(sc))
		if _, ok := exists[key]; !ok || isMutableEffectsExpr(expr) {
			res = append(res, expr)
			exists[key] = struct{}{}
		}
	}
	return res
}
1360209
func (f *extFloat) Multiply(g extFloat) {
	fhi, flo := f.mant>>32, uint64(uint32(f.mant))
	ghi, glo := g.mant>>32, uint64(uint32(g.mant))

	// Cross products.
	cross1 := fhi * glo
	cross2 := flo * ghi

	// f.mant*g.mant is fhi*ghi << 64 + (cross1+cross2) << 32 + flo*glo
	f.mant = fhi*ghi + (cross1 >> 32) + (cross2 >> 32)
	rem := uint64(uint32(cross1)) + uint64(uint32(cross2)) + ((flo * glo) >> 32)
	// Round up.
	rem += (1 << 31)

	f.mant += (rem >> 32)
	f.exp = f.exp + g.exp + 64
}
804026
func Expr(query string, value ...interface{}) Builder {
	return &raw{Query: query, Value: value}
}
1185293
func (a *aggregationEliminateChecker) rewriteExpr(ctx sessionctx.Context, aggFunc *aggregation.AggFuncDesc) expression.Expression {
	switch aggFunc.Name {
	case ast.AggFuncCount:
		if aggFunc.Mode == aggregation.FinalMode {
			return a.wrapCastFunction(ctx, aggFunc.Args[0], aggFunc.RetTp)
		}
		return a.rewriteCount(ctx, aggFunc.Args, aggFunc.RetTp)
	case ast.AggFuncSum, ast.AggFuncAvg, ast.AggFuncFirstRow, ast.AggFuncMax, ast.AggFuncMin, ast.AggFuncGroupConcat:
		return a.wrapCastFunction(ctx, aggFunc.Args[0], aggFunc.RetTp)
	case ast.AggFuncBitAnd, ast.AggFuncBitOr, ast.AggFuncBitXor:
		return a.rewriteBitFunc(ctx, aggFunc.Name, aggFunc.Args[0], aggFunc.RetTp)
	default:
		panic("Unsupported function")
	}
}
324652
func compileExpression(s string) (expr Expression, err error) {
	tokens := tokenize(s)
	if contains(tokens, "?") {
		return ternaryToken.compile(tokens)
	}
	return constToken.compile(tokens)
}