// maybeRewrite rewrites q to use op if it is possible to do so
// without changing the meaning.  It also simplifies if the node
// is an empty OR or AND.
177732
func (q *Query) maybeRewrite(op QueryOp) {
	if q.Op != QAnd && q.Op != QOr {
		return
	}

	// AND/OR doing real work?  Can't rewrite.
	n := len(q.Sub) + len(q.Trigram)
	if n > 1 {
		return
	}

	// Nothing left in the AND/OR?
	if n == 0 {
		if q.Op == QAnd {
			q.Op = QAll
		} else {
			q.Op = QNone
		}
		return
	}

	// Just a sub-node: throw away wrapper.
	if len(q.Sub) == 1 {
		*q = *q.Sub[0]
	}

	// Just a trigram: can use either op.
	q.Op = op
}
1368975
func (notNull NotNull) Or(conds ...Cond) Cond {
	return Or(notNull, Or(conds...))
}
191881
func rewriteSyntax(prog *cc.Prog) {
	cc.Preorder(prog, func(x cc.Syntax) {
		switch x := x.(type) {
		case *cc.Stmt:
			rewriteStmt(x)

		case *cc.Expr:
			switch x.Op {
			case cc.Number:
				// Rewrite char literal.
				// In general we'd need to rewrite all string and char literals
				// but these are the only forms that comes up.
				switch x.Text {
				case `'\0'`:
					x.Text = `'\x00'`
				case `'\"'`:
					x.Text = `'"'`
				}

			case cc.Paren:
				switch x.Left.Op {
				case cc.Number, cc.Name:
					fixMerge(x, x.Left)
				}

			case cc.OrEq, cc.AndEq, cc.Or, cc.Eq, cc.EqEq, cc.NotEq, cc.LtEq, cc.GtEq, cc.Lt, cc.Gt:
				cutParen(x, cc.Or, cc.And, cc.Lsh, cc.Rsh)
			}

		case *cc.Type:
			// Rewrite int f(void) to int f().
			if x.Kind == cc.Func && len(x.Decls) == 1 && x.Decls[0].Name == "" && x.Decls[0].Type.Is(cc.Void) {
				x.Decls = nil
			}
		}
	})

	// Apply changed struct tags to typedefs.
	// Excise dead pieces.
	cc.Postorder(prog, func(x cc.Syntax) {
		switch x := x.(type) {
		case *cc.Type:
			if x.Kind == cc.TypedefType && x.Base != nil && x.Base.Tag != "" {
				x.Name = x.Base.Tag
			}

		case *cc.Stmt:
			if x.Op == cc.StmtExpr && x.Expr.Op == cc.Comma && len(x.Expr.List) == 0 {
				x.Op = cc.Empty
			}
			x.Block = filterBlock(x.Block)

		case *cc.Expr:
			if x.Op == c2go.ExprBlock {
				x.Block = filterBlock(x.Block)
			}

			switch x.Op {
			case cc.Add, cc.Sub:
				// Turn p + y - z, which is really (p + y) - z, into p + (y - z),
				// so that there is only one pointer addition (which will turn into
				// a slice operation using y-z as the index).
				if x.XType != nil && x.XType.Kind == cc.Ptr {
					switch x.Left.Op {
					case cc.Add, cc.Sub:
						if x.Left.XType != nil && x.Left.XType.Kind == cc.Ptr {
							p, op1, y, op2, z := x.Left.Left, x.Left.Op, x.Left.Right, x.Op, x.Right
							if op1 == cc.Sub {
								y = &cc.Expr{Op: cc.Minus, Left: y, XType: y.XType}
							}
							x.Op = cc.Add
							x.Left = p
							x.Right = &cc.Expr{Op: op2, Left: y, Right: z, XType: x.XType}
						}
					}
				}
			}

			// Turn c + p - q, which is really (c + p) - q, into c + (p - q),
			// so that there is no int + ptr addition, only a ptr - ptr subtraction.
			if x.Op == cc.Sub && x.Left.Op == cc.Add && !isPtrOrArray(x.XType) && isPtrOrArray(x.Left.XType) && !isPtrOrArray(x.Left.Left.XType) {
				c, p, q := x.Left.Left, x.Left.Right, x.Right
				expr := x.Left
				expr.Left = p
				expr.Right = q
				expr.Op = cc.Sub
				x.Op = cc.Add
				x.Left = c
				x.Right = expr
				expr.XType = x.XType
			}
		}
	})
}
334980
func (rw *HeaderRewriter) Rewrite(req *http.Request) {
	if !rw.TrustForwardHeader {
		utils.RemoveHeaders(req.Header, XHeaders...)
	}

	if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
		clientIP = ipv6fix(clientIP)
		// If not websocket, done in http.ReverseProxy
		if IsWebsocketRequest(req) {
			if prior, ok := req.Header[XForwardedFor]; ok {
				req.Header.Set(XForwardedFor, strings.Join(prior, ", ")+", "+clientIP)
			} else {
				req.Header.Set(XForwardedFor, clientIP)
			}
		}

		if req.Header.Get(XRealIp) == "" {
			req.Header.Set(XRealIp, clientIP)
		}
	}

	xfProto := req.Header.Get(XForwardedProto)
	if xfProto == "" {
		if req.TLS != nil {
			req.Header.Set(XForwardedProto, "https")
		} else {
			req.Header.Set(XForwardedProto, "http")
		}
	}

	if IsWebsocketRequest(req) {
		if req.Header.Get(XForwardedProto) == "https" {
			req.Header.Set(XForwardedProto, "wss")
		} else {
			req.Header.Set(XForwardedProto, "ws")
		}
	}

	if xfPort := req.Header.Get(XForwardedPort); xfPort == "" {
		req.Header.Set(XForwardedPort, forwardedPort(req))
	}

	if xfHost := req.Header.Get(XForwardedHost); xfHost == "" && req.Host != "" {
		req.Header.Set(XForwardedHost, req.Host)
	}

	if rw.Hostname != "" {
		req.Header.Set(XForwardedServer, rw.Hostname)
	}
}
207560
func (rule *classRule) Rewrite(w dns.ResponseWriter, r *dns.Msg) Result {
	if rule.fromClass > 0 && rule.toClass > 0 {
		if r.Question[0].Qclass == rule.fromClass {
			r.Question[0].Qclass = rule.toClass
			return RewriteDone
		}
	}
	return RewriteIgnored
}
1210138
func RewriteSimpleExprWithTableInfo(ctx sessionctx.Context, tbl *model.TableInfo, expr ast.ExprNode) (Expression, error) {
	dbName := model.NewCIStr(ctx.GetSessionVars().CurrentDB)
	columns := ColumnInfos2ColumnsWithDBName(ctx, dbName, tbl.Name, tbl.Columns)
	rewriter := &simpleRewriter{ctx: ctx, schema: NewSchema(columns...)}
	expr.Accept(rewriter)
	if rewriter.err != nil {
		return nil, rewriter.err
	}
	return rewriter.pop(), nil
}
1240186
func (ar *ar_DZ) OrdinalPluralRule(num float64, v uint64) locales.PluralRule {
	return locales.PluralRuleOther
}
282955
func Rewrite(r Rewriter, node Node) Node {
	switch n := node.(type) {
	case *Query:
		n.Statements = Rewrite(r, n.Statements).(Statements)

	case Statements:
		for i, s := range n {
			n[i] = Rewrite(r, s).(Statement)
		}

	case *SelectStatement:
		n.Fields = Rewrite(r, n.Fields).(Fields)
		n.Dimensions = Rewrite(r, n.Dimensions).(Dimensions)
		n.Sources = Rewrite(r, n.Sources).(Sources)

		// Rewrite may return nil. Nil does not satisfy the Expr
		// interface. We only assert the rewritten result to be an
		// Expr if it is not nil:
		if cond := Rewrite(r, n.Condition); cond != nil {
			n.Condition = cond.(Expr)
		} else {
			n.Condition = nil
		}

	case *SubQuery:
		n.Statement = Rewrite(r, n.Statement).(*SelectStatement)

	case Fields:
		for i, f := range n {
			n[i] = Rewrite(r, f).(*Field)
		}

	case *Field:
		n.Expr = Rewrite(r, n.Expr).(Expr)

	case Dimensions:
		for i, d := range n {
			n[i] = Rewrite(r, d).(*Dimension)
		}

	case *Dimension:
		n.Expr = Rewrite(r, n.Expr).(Expr)

	case *BinaryExpr:
		n.LHS = Rewrite(r, n.LHS).(Expr)
		n.RHS = Rewrite(r, n.RHS).(Expr)

	case *ParenExpr:
		n.Expr = Rewrite(r, n.Expr).(Expr)

	case *Call:
		for i, expr := range n.Args {
			n.Args[i] = Rewrite(r, expr).(Expr)
		}
	}

	return r.Rewrite(node)
}
364625
func (ha *ha_NE) OrdinalPluralRule(num float64, v uint64) locales.PluralRule {
	return locales.PluralRuleUnknown
}
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")
	}
}
1262468
func (s *SelectStatement) RewriteDistinct() {
	WalkFunc(s.Fields, func(n Node) {
		switch n := n.(type) {
		case *Field:
			if expr, ok := n.Expr.(*Distinct); ok {
				n.Expr = expr.NewCall()
				s.IsRawQuery = false
			}
		case *Call:
			for i, arg := range n.Args {
				if arg, ok := arg.(*Distinct); ok {
					n.Args[i] = arg.NewCall()
				}
			}
		}
	})
}
742002
func (rule *edns0VariableRule) Rewrite(ctx context.Context, state request.Request) Result {
	data, err := rule.ruleData(ctx, state)
	if err != nil || data == nil {
		return RewriteIgnored
	}

	o := setupEdns0Opt(state.Req)
	for _, s := range o.Option {
		if e, ok := s.(*dns.EDNS0_LOCAL); ok {
			if rule.code == e.Code {
				if rule.action == Replace || rule.action == Set {
					e.Data = data
					return RewriteDone
				}
				return RewriteIgnored
			}
		}
	}

	// add option if not found
	if rule.action == Append || rule.action == Set {
		o.Option = append(o.Option, &dns.EDNS0_LOCAL{Code: rule.code, Data: data})
		return RewriteDone
	}

	return RewriteIgnored
}
774753
func (rule *edns0SubnetRule) Rewrite(ctx context.Context, state request.Request) Result {
	o := setupEdns0Opt(state.Req)

	for _, s := range o.Option {
		if e, ok := s.(*dns.EDNS0_SUBNET); ok {
			if rule.action == Replace || rule.action == Set {
				if rule.fillEcsData(state, e) == nil {
					return RewriteDone
				}
			}
			return RewriteIgnored
		}
	}

	// add option if not found
	if rule.action == Append || rule.action == Set {
		opt := &dns.EDNS0_SUBNET{Code: dns.EDNS0SUBNET}
		if rule.fillEcsData(state, opt) == nil {
			o.Option = append(o.Option, opt)
			return RewriteDone
		}
	}

	return RewriteIgnored
}
209813
func (khq *khq) OrdinalPluralRule(num float64, v uint64) locales.PluralRule {
	return locales.PluralRuleUnknown
}
986761
func NewRewriter(db *gitobj.ObjectDatabase, opts ...rewriterOption) *Rewriter {
	rewriter := &Rewriter{
		mu:      new(sync.Mutex),
		entries: make(map[string]*gitobj.TreeEntry),
		commits: make(map[string][]byte),

		db: db,
	}

	for _, opt := range opts {
		opt(rewriter)
	}
	return rewriter
}
85537
func RewriteFunc(node Node, fn func(Node) Node) Node {
	return Rewrite(rewriterFunc(fn), node)
}
1154732
func rewriteTypes(prog cc.Syntax) {
	// Assign overrides to groups.
	cc.Postorder(prog, func(x cc.Syntax) {
		if d, ok := x.(*cc.Decl); ok {
			key := declKey(d)
			t := override[key]
			if t == nil {
				return
			}
			if t.Kind == cc.Array {
				// Override only applies to specific decl. Skip for now.
				return
			}
			f := flowCache[d]
			if f == nil {
				return
			}
			g := f.group
			if g.goKind != 0 || g.goType != nil {
				fmt.Fprintf(os.Stderr, "multiple overrides: %v (%p) and %v (%p)\n", key, f.group, g.goKey, g.goFlow.group)
			}
			g.goKey = key
			g.goFlow = f
			if t.Kind <= cc.Enum {
				panic("bad go type override")
			}
			if (t.Kind == cc.Ptr || t.Kind == c2go.Slice) && t.Base == nil {
				g.goKind = t.Kind
			} else {
				g.goType = t
			}
		}
	})

	// Process overrides.
	cache := make(map[*cc.Type]*cc.Type)
	for _, g := range flowGroups {
		if g.goType != nil {
			continue
		}
		if c2go.Int8 <= g.goKind && g.goKind <= c2go.Float64 {
			g.goType = &cc.Type{Kind: g.goKind}
			continue
		}
		if g.goKind == cc.Ptr || g.goKind == c2go.Slice {
			t := g.decls[0].Type
			if t == nil || t.Base == nil {
				fmt.Printf("%s: expected ptr/array/slice for %s\n", g.decls[0].Span, declKey(g.decls[0]))
				continue
			}
			g.goType = &cc.Type{Kind: g.goKind, Base: toGoType(nil, nil, t.Base, cache)}
			continue
		}
		if g.goKind != 0 {
			fmt.Printf("%s: unexpected go kind %v\n", g.goKey, g.goKind)
			continue
		}
	}

	// Process defaults.
	// Each group has a 'canonical' instance of the type
	// that we can use as the initial hint.
	for _, g := range flowGroups {
		if g.goType != nil {
			continue
		}
		if g.canon == nil {
			fmt.Printf("group missing canonical\n")
			continue
		}
		if g.isBool {
			g.goType = boolType
			continue
		}
		t := g.canon.Def()
		if cc.Char <= t.Kind && t.Kind <= cc.Enum {
			// Convert to an appropriately sized number.
			// Canon is largest rank from C; convert to Go.
			g.goType = &cc.Type{Kind: c2goKind[t.Kind]}
			continue
		}

		if t.Kind == cc.Ptr || t.Kind == cc.Array {
			// Default is convert to pointer.
			// If there are any arrays or any pointer arithmetic, convert to slice instead.
			k := cc.Ptr
			for _, d := range g.decls {
				if d.Type != nil && d.Type.Kind == cc.Array {
					k = c2go.Slice
				}
			}
			for _, f := range g.syntax {
				if f.ptrAdd {
					k = c2go.Slice
				}
			}
			if t.Base.Kind == cc.Char {
				g.goType = &cc.Type{Kind: c2go.String}
				continue
			}
			g.goType = &cc.Type{Kind: k, Base: toGoType(nil, nil, t.Base, cache)}
			continue
		}
	}

	if *showGroups {
		fmt.Printf("%d groups\n", len(flowGroups))
		for _, g := range flowGroups {
			suffix := ""
			if g.isBool {
				suffix = " [bool]"
			}
			fmt.Printf("group(%d): %v (canon %v)%s\n", len(g.decls), c2go.GoString(g.goType), c2go.GoString(g.canon), suffix)
			for i := 0; i < 2; i++ {
				for _, f := range g.syntax {
					if d, ok := f.syntax.(*cc.Decl); ok == (i == 0) {
						suffix := ""
						if ok {
							suffix = ": " + declKey(d) + " " + c2go.GoString(d.Type)
						}
						if f.ptrAdd {
							suffix += " (ptradd)"
						}
						if f.usedAsBool {
							suffix += " (bool)"
						}
						fmt.Printf("\t%s %v%s\n", f.syntax.GetSpan(), f.syntax, suffix)
					}
				}
			}
		}
	}

	// Apply grouped decisions to individual declarations.
	cc.Postorder(prog, func(x cc.Syntax) {
		switch x := x.(type) {
		case *cc.Decl:
			d := x
			if d.Name == "..." || d.Type == nil {
				return
			}
			if d.Name == "" && d.Type.Is(cc.Enum) && len(d.Type.Decls) > 0 {
				for _, dd := range d.Type.Decls {
					dd.Type = idealType
				}
				return
			}
			t := override[declKey(d)]
			if t != nil && t.Kind == cc.Array {
				d.Type = t
				return
			}
			f := flowCache[d]
			if f == nil {
				d.Type = toGoType(nil, d, d.Type, cache)
				if declKey(d) != "tmp" {
					fprintf(d.Span, "missing flow group for %s", d.Span, declKey(d))
				}
				return
			}
			g := f.group
			if d.Init != nil && len(d.Init.Braced) > 0 && d.Type != nil && d.Type.Kind == cc.Array {
				// Initialization of array - do not override type.
				// But if size is not given explicitly, change to slice.
				d.Type.Base = toGoType(nil, nil, d.Type.Base, cache)
				if d.Type.Width == nil {
					d.Type.Kind = c2go.Slice
				}
				return
			}
			d.Type = toGoType(g, d, d.Type, cache)
			if d.Type != nil && d.Type.Kind == cc.Func && d.Type.Base.Kind != cc.Void {
				if f != nil && f.returnValue != nil && f.returnValue.group != nil && f.returnValue.group.goType != nil {
					d.Type.Base = f.returnValue.group.goType
				}
			}

		case *cc.Expr:
			if x.Type != nil {
				t := toGoType(nil, nil, x.Type, cache)
				if t == nil {
					fprintf(x.Span, "cannot convert %v to go type\n", c2go.GoString(x.Type))
				}
				x.Type = t
			}
		}
	})
}