func (plan *Plan) checkValuesType(vals sqlparser.Values) sqlparser.Values { // Analyze first value of every item in the list for i := 0; i < len(vals); i++ { switch tuple := vals[i].(type) { case sqlparser.ValTuple: result := plan.getValueType(tuple[0]) if result != VALUE_NODE { panic(sqlparser.NewParserError("insert is too complex")) } default: panic(sqlparser.NewParserError("insert is too complex")) } } return vals }
func (r *Router) buildReplacePlan(statement sqlparser.Statement) (*Plan, error) { plan := &Plan{} stmt := statement.(*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.checkValuesType(stmt.Rows.(sqlparser.Values)) plan.TableIndexs = makeList(0, len(plan.Rule.TableToNode)) err := plan.calRouteIndexs() if err != nil { golog.Error("Route", "BuildReplacePlan", err.Error(), 0) return nil, err } err = r.generateReplaceSql(plan, stmt) if err != nil { return nil, err } return plan, nil }
/*获得valExpr对应的值*/ func (plan *Plan) getBoundValue(valExpr sqlparser.ValExpr) interface{} { switch node := valExpr.(type) { case sqlparser.ValTuple: //ValTuple可以是一个slice if len(node) != 1 { panic(sqlparser.NewParserError("tuples not allowed as insert values")) } // TODO: Change parser to create single value tuples into non-tuples. return plan.getBoundValue(node[0]) case sqlparser.StrVal: return string(node) case sqlparser.NumVal: val, err := strconv.ParseInt(string(node), 10, 64) if err != nil { panic(sqlparser.NewParserError("%s", err.Error())) } return val case sqlparser.ValArg: panic("Unexpected token") } panic("Unexpected token") }
func (plan *Plan) getInsertTableIndex(vals sqlparser.Values) int { index := -1 for i := 0; i < len(vals); i++ { first_value_expression := vals[i].(sqlparser.ValTuple)[0] newIndex := plan.getTableIndexByValue(first_value_expression) if index == -1 { index = newIndex } else if index != newIndex { panic(sqlparser.NewParserError("insert or replace has multiple shard targets")) } } return index }
func (plan *Plan) adjustShardIndex(valExpr sqlparser.ValExpr, index int) int { value := plan.getBoundValue(valExpr) //生成一个范围的接口,[100,120) s, ok := plan.Rule.Shard.(RangeShard) if !ok { return index } //value是否和shard[index].Start相等 if s.EqualStart(value, index) { index-- if index < 0 { panic(sqlparser.NewParserError("invalid range sharding")) } } return index }