func (plan *Plan) getTableIndexByBoolExpr(node sqlparser.BoolExpr) ([]int, error) { switch node := node.(type) { case *sqlparser.AndExpr: left, err := plan.getTableIndexByBoolExpr(node.Left) if err != nil { return nil, err } right, err := plan.getTableIndexByBoolExpr(node.Right) if err != nil { return nil, err } return interList(left, right), nil case *sqlparser.OrExpr: left, err := plan.getTableIndexByBoolExpr(node.Left) if err != nil { return nil, err } right, err := plan.getTableIndexByBoolExpr(node.Right) if err != nil { return nil, err } return unionList(left, right), nil case *sqlparser.ParenBoolExpr: //加上括号的BoolExpr,node.Expr去掉了括号 return plan.getTableIndexByBoolExpr(node.Expr) case *sqlparser.ComparisonExpr: switch { case sqlparser.StringIn(node.Operator, "=", "<", ">", "<=", ">=", "<=>"): left := plan.getValueType(node.Left) right := plan.getValueType(node.Right) if (left == EID_NODE && right == VALUE_NODE) || (left == VALUE_NODE && right == EID_NODE) { return plan.getTableIndexs(node) } case sqlparser.StringIn(node.Operator, "in", "not in"): left := plan.getValueType(node.Left) right := plan.getValueType(node.Right) if left == EID_NODE && right == LIST_NODE { if strings.EqualFold(node.Operator, "in") { //only deal with in expr, it's impossible to process not in here. plan.InRightToReplace = node } return plan.getTableIndexs(node) } } case *sqlparser.RangeCond: left := plan.getValueType(node.Left) from := plan.getValueType(node.From) to := plan.getValueType(node.To) if left == EID_NODE && from == VALUE_NODE && to == VALUE_NODE { return plan.getTableIndexs(node) } } return plan.Rule.SubTableIndexs, nil }
func (plan *Plan) getTableIndexByBoolExpr(node sqlparser.BoolExpr) ([]int, error) { switch node := node.(type) { case *sqlparser.AndExpr: left, err := plan.getTableIndexByBoolExpr(node.Left) if err != nil { return nil, err } right, err := plan.getTableIndexByBoolExpr(node.Right) if err != nil { return nil, err } return interList(left, right), nil case *sqlparser.OrExpr: left, err := plan.getTableIndexByBoolExpr(node.Left) if err != nil { return nil, err } right, err := plan.getTableIndexByBoolExpr(node.Right) if err != nil { return nil, err } return unionList(left, right), nil case *sqlparser.ParenBoolExpr: //加上括号的BoolExpr,node.Expr去掉了括号 return plan.getTableIndexByBoolExpr(node.Expr) case *sqlparser.ComparisonExpr: switch { case sqlparser.StringIn(node.Operator, "=", "<", ">", "<=", ">=", "<=>"): left := plan.getValueType(node.Left) right := plan.getValueType(node.Right) if (left == EID_NODE && right == VALUE_NODE) || (left == VALUE_NODE && right == EID_NODE) { return plan.getTableIndexs(node) } case sqlparser.StringIn(node.Operator, "in", "not in"): left := plan.getValueType(node.Left) right := plan.getValueType(node.Right) if left == EID_NODE && right == LIST_NODE { return plan.getTableIndexs(node) } } case *sqlparser.RangeCond: left := plan.getValueType(node.Left) from := plan.getValueType(node.From) to := plan.getValueType(node.To) if left == EID_NODE && from == VALUE_NODE && to == VALUE_NODE { return plan.getTableIndexs(node) } } return plan.TableIndexs, nil }
//bool表达式类型的分表规则,返回bool表达式对应的shard list func (plan *Plan) routingAnalyzeBoolean(node sqlparser.BoolExpr) []int { switch node := node.(type) { case *sqlparser.AndExpr: left := plan.routingAnalyzeBoolean(node.Left) right := plan.routingAnalyzeBoolean(node.Right) return interList(left, right) case *sqlparser.OrExpr: left := plan.routingAnalyzeBoolean(node.Left) right := plan.routingAnalyzeBoolean(node.Right) return unionList(left, right) case *sqlparser.ParenBoolExpr: return plan.routingAnalyzeBoolean(node.Expr) case *sqlparser.ComparisonExpr: switch { case sqlparser.StringIn(node.Operator, "=", "<", ">", "<=", ">=", "<=>"): left := plan.routingAnalyzeValue(node.Left) right := plan.routingAnalyzeValue(node.Right) if (left == EID_NODE && right == VALUE_NODE) || (left == VALUE_NODE && right == EID_NODE) { return plan.findConditionShard(node) } case sqlparser.StringIn(node.Operator, "in", "not in"): left := plan.routingAnalyzeValue(node.Left) right := plan.routingAnalyzeValue(node.Right) if left == EID_NODE && right == LIST_NODE { return plan.findConditionShard(node) } } case *sqlparser.RangeCond: left := plan.routingAnalyzeValue(node.Left) from := plan.routingAnalyzeValue(node.From) to := plan.routingAnalyzeValue(node.To) if left == EID_NODE && from == VALUE_NODE && to == VALUE_NODE { return plan.findConditionShard(node) } } return plan.fullList }