func (r *Router) buildInsertPlan(statement sqlparser.Statement) (*Plan, error) { plan := &Plan{} stmt := statement.(*sqlparser.Insert) if _, ok := stmt.Rows.(sqlparser.SelectStatement); ok { return nil, errors.ErrSelectInInsert } /*根据sql语句的表,获得对应的分片规则*/ plan.Rule = r.GetRule(sqlparser.String(stmt.Table)) if stmt.OnDup != nil { err := plan.Rule.checkUpdateExprs(sqlparser.UpdateExprs(stmt.OnDup)) if err != nil { return nil, err } } plan.Criteria = plan.checkValuesType(stmt.Rows.(sqlparser.Values)) plan.TableIndexs = makeList(0, len(plan.Rule.TableToNode)) err := plan.calRouteIndexs() if err != nil { golog.Error("Route", "BuildInsertPlan", err.Error(), 0) return nil, err } err = r.generateInsertSql(plan, stmt) if err != nil { return nil, err } return plan, nil }
/*生成一个route plan*/ func (r *Router) GetPlan(statement sqlparser.Statement) (plan *Plan) { plan = &Plan{} var where *sqlparser.Where //因为实现Statement接口的方法都是指针类型,所以type对应类型也是指针类型 switch stmt := statement.(type) { case *sqlparser.Insert: if _, ok := stmt.Rows.(sqlparser.SelectStatement); ok { panic(sqlparser.NewParserError("select in insert not allowed")) } /*根据sql语句的表,获得对应的分片规则*/ plan.rule = r.GetRule(sqlparser.String(stmt.Table)) if stmt.OnDup != nil { plan.rule.checkUpdateExprs(sqlparser.UpdateExprs(stmt.OnDup)) } plan.criteria = plan.routingAnalyzeValues(stmt.Rows.(sqlparser.Values)) plan.fullList = makeList(0, len(plan.rule.Nodes)) return plan case *sqlparser.Replace: if _, ok := stmt.Rows.(sqlparser.SelectStatement); ok { panic(sqlparser.NewParserError("select in replace not allowed")) } plan.rule = r.GetRule(sqlparser.String(stmt.Table)) plan.criteria = plan.routingAnalyzeValues(stmt.Rows.(sqlparser.Values)) plan.fullList = makeList(0, len(plan.rule.Nodes)) return plan case *sqlparser.Select: plan.rule = r.GetRule(sqlparser.String(stmt.From[0])) //根据表名获得分表规则 where = stmt.Where case *sqlparser.Update: plan.rule = r.GetRule(sqlparser.String(stmt.Table)) plan.rule.checkUpdateExprs(stmt.Exprs) where = stmt.Where case *sqlparser.Delete: plan.rule = r.GetRule(sqlparser.String(stmt.Table)) where = stmt.Where } if where != nil { plan.criteria = where.Expr /*路由条件*/ } else { plan.rule = r.DefaultRule } plan.fullList = makeList(0, len(plan.rule.Nodes)) return plan }
func (r *Router) buildInsertPlan(db string, statement sqlparser.Statement) (*Plan, error) { plan := &Plan{} plan.Rows = make(map[int]sqlparser.Values) stmt := statement.(*sqlparser.Insert) if _, ok := stmt.Rows.(sqlparser.SelectStatement); ok { return nil, errors.ErrSelectInInsert } if stmt.Columns == nil { return nil, errors.ErrIRNoColumns } //根据sql语句的表,获得对应的分片规则 plan.Rule = r.GetRule(db, sqlparser.String(stmt.Table)) err := plan.GetIRKeyIndex(stmt.Columns) if err != nil { return nil, err } if stmt.OnDup != nil { err := plan.Rule.checkUpdateExprs(sqlparser.UpdateExprs(stmt.OnDup)) if err != nil { return nil, err } } plan.Criteria = plan.checkValuesType(stmt.Rows.(sqlparser.Values)) err = plan.calRouteIndexs() if err != nil { golog.Error("Route", "BuildInsertPlan", err.Error(), 0) return nil, err } err = r.generateInsertSql(plan, stmt) if err != nil { return nil, err } return plan, nil }