Example #1
0
func (e *Evaluator) between(v *ast.BetweenExpr) bool {
	var l, r ast.ExprNode
	op := opcode.AndAnd

	if v.Not {
		// v < lv || v > rv
		op = opcode.OrOr
		l = &ast.BinaryOperationExpr{Op: opcode.LT, L: v.Expr, R: v.Left}
		r = &ast.BinaryOperationExpr{Op: opcode.GT, L: v.Expr, R: v.Right}
	} else {
		// v >= lv && v <= rv
		l = &ast.BinaryOperationExpr{Op: opcode.GE, L: v.Expr, R: v.Left}
		r = &ast.BinaryOperationExpr{Op: opcode.LE, L: v.Expr, R: v.Right}
	}
	ast.MergeChildrenFlags(l, v.Expr, v.Left)
	ast.MergeChildrenFlags(l, v.Expr, v.Right)
	ret := &ast.BinaryOperationExpr{Op: op, L: l, R: r}
	ast.MergeChildrenFlags(ret, l, r)
	ret.Accept(e)
	if e.err != nil {
		return false
	}
	v.SetDatum(*ret.GetDatum())
	return true
}
Example #2
0
func (b *planBuilder) buildTablePlanFromJoinPath(path *joinPath) Plan {
	for _, equiv := range path.eqConds {
		columnNameExpr := &ast.ColumnNameExpr{}
		columnNameExpr.Name = &ast.ColumnName{}
		columnNameExpr.Name.Name = equiv.left.Column.Name
		columnNameExpr.Name.Table = equiv.left.Table.Name
		columnNameExpr.Refer = equiv.left
		columnNameExpr.Type = equiv.left.Expr.GetType()
		ast.SetFlag(columnNameExpr)
		condition := &ast.BinaryOperationExpr{L: columnNameExpr, R: equiv.right.Expr, Op: opcode.EQ}
		ast.MergeChildrenFlags(condition, columnNameExpr, equiv.right.Expr)
		path.conditions = append(path.conditions, condition)
	}
	candidates := b.buildAllAccessMethodsPlan(path)
	var p Plan
	var lowestCost float64
	for _, can := range candidates {
		cost := EstimateCost(can)
		if p == nil {
			p = can
			lowestCost = cost
		}
		if cost < lowestCost {
			p = can
			lowestCost = cost
		}
	}
	return p
}
Example #3
0
func (b *executorBuilder) joinConditions(conditions []ast.ExprNode) ast.ExprNode {
	if len(conditions) == 0 {
		return nil
	}
	if len(conditions) == 1 {
		return conditions[0]
	}
	condition := &ast.BinaryOperationExpr{
		Op: opcode.AndAnd,
		L:  conditions[0],
		R:  b.joinConditions(conditions[1:]),
	}
	ast.MergeChildrenFlags(condition, condition.L, condition.R)
	return condition
}
Example #4
0
func (b *planBuilder) buildPlanFromJoinPath(path *joinPath) Plan {
	if path.table != nil {
		return b.buildTablePlanFromJoinPath(path)
	}
	if path.subquery != nil {
		return b.buildSubqueryJoinPath(path)
	}
	if path.outer != nil {
		join := &JoinOuter{
			Outer: b.buildPlanFromJoinPath(path.outer),
			Inner: b.buildPlanFromJoinPath(path.inner),
		}
		addChild(join, join.Outer)
		addChild(join, join.Inner)
		if path.rightJoin {
			join.SetFields(append(join.Inner.Fields(), join.Outer.Fields()...))
		} else {
			join.SetFields(append(join.Outer.Fields(), join.Inner.Fields()...))
		}
		return join
	}
	join := &JoinInner{}
	for _, in := range path.inners {
		inPlan := b.buildPlanFromJoinPath(in)
		join.Inners = append(join.Inners, inPlan)
		join.fields = append(join.fields, in.resultFields()...)
		addChild(join, inPlan)
	}
	join.Conditions = path.conditions
	for _, equiv := range path.eqConds {
		columnNameExpr := &ast.ColumnNameExpr{}
		columnNameExpr.Name = &ast.ColumnName{}
		columnNameExpr.Name.Name = equiv.left.Column.Name
		columnNameExpr.Name.Table = equiv.left.Table.Name
		columnNameExpr.Refer = equiv.left
		ast.SetFlag(columnNameExpr)
		cond := &ast.BinaryOperationExpr{L: columnNameExpr, R: equiv.right.Expr, Op: opcode.EQ}
		ast.MergeChildrenFlags(cond, columnNameExpr, equiv.right.Expr)
		join.Conditions = append(join.Conditions, cond)
	}
	return join
}
Example #5
0
// Build subquery join path plan
func (b *planBuilder) buildSubqueryJoinPath(path *joinPath) Plan {
	for _, equiv := range path.eqConds {
		columnNameExpr := &ast.ColumnNameExpr{}
		columnNameExpr.Name = &ast.ColumnName{}
		columnNameExpr.Name.Name = equiv.left.Column.Name
		columnNameExpr.Name.Table = equiv.left.Table.Name
		columnNameExpr.Refer = equiv.left
		columnNameExpr.Type = equiv.left.Expr.GetType()
		ast.SetFlag(columnNameExpr)
		condition := &ast.BinaryOperationExpr{L: columnNameExpr, R: equiv.right.Expr, Op: opcode.EQ}
		ast.MergeChildrenFlags(condition, columnNameExpr, equiv.right.Expr)
		path.conditions = append(path.conditions, condition)
	}
	p := b.build(path.subquery)
	if len(path.conditions) == 0 {
		return p
	}
	filterPlan := &Filter{Conditions: path.conditions}
	addChild(filterPlan, p)
	filterPlan.SetFields(p.Fields())
	return filterPlan
}