Beispiel #1
0
// Optimize does optimization and creates a Plan.
// The node must be prepared first.
func Optimize(ctx context.Context, node ast.Node) (plan.Plan, error) {
	// We have to infer type again because after parameter is set, the expression type may change.
	if err := InferType(node); err != nil {
		return nil, errors.Trace(err)
	}
	if err := logicOptimize(ctx, node); err != nil {
		return nil, errors.Trace(err)
	}
	p, err := plan.BuildPlan(node)
	if err != nil {
		return nil, errors.Trace(err)
	}
	alts, err := plan.Alternatives(p)
	if err != nil {
		return nil, errors.Trace(err)
	}
	err = plan.Refine(p)
	if err != nil {
		return nil, errors.Trace(err)
	}
	bestCost := plan.EstimateCost(p)
	bestPlan := p
	for _, alt := range alts {
		err = plan.Refine(alt)
		if err != nil {
			return nil, errors.Trace(err)
		}
		cost := plan.EstimateCost(alt)
		if cost < bestCost {
			bestCost = cost
			bestPlan = alt
		}
	}
	return bestPlan, nil
}
Beispiel #2
0
// Optimize does optimization and creates a Plan.
// The node must be prepared first.
func Optimize(ctx context.Context, node ast.Node, sb plan.SubQueryBuilder) (plan.Plan, error) {
	// We have to infer type again because after parameter is set, the expression type may change.
	if err := InferType(node); err != nil {
		return nil, errors.Trace(err)
	}
	if err := logicOptimize(ctx, node); err != nil {
		return nil, errors.Trace(err)
	}
	p, err := plan.BuildPlan(node, sb)
	if err != nil {
		return nil, errors.Trace(err)
	}
	err = plan.Refine(p)
	if err != nil {
		return nil, errors.Trace(err)
	}
	return p, nil
}