// getDMLRouting updates the route with the necessary routing // info. If it cannot find a unique route, then it returns an error. func getDMLRouting(where *sqlparser.Where, route *engine.Route) error { if where == nil { return errors.New("unsupported: multi-shard where clause in DML") } for _, index := range route.Table.Ordered { if !vindexes.IsUnique(index.Vindex) { continue } if values := getMatch(where.Expr, index.Column); values != nil { route.Vindex = index.Vindex route.Values = values return nil } } return errors.New("unsupported: multi-shard where clause in DML") }
// buildIndexPlan adds the insert value to the Values field for the specified ColVindex. // This value will be used at the time of insert to validate the vindex value. func buildIndexPlan(ins *sqlparser.Insert, colVindex *vindexes.ColVindex, route *engine.Route) error { row, pos := findOrInsertPos(ins, colVindex.Col) val, err := valConvert(row[pos]) if err != nil { return fmt.Errorf("could not convert val: %s, pos: %d: %v", sqlparser.String(row[pos]), pos, err) } route.Values = append(route.Values.([]interface{}), val) row[pos] = sqlparser.ValArg([]byte(":_" + colVindex.Col)) return nil }
func buildAutoincPlan(ins *sqlparser.Insert, autoinc *vindexes.Autoinc, route *engine.Route) error { route.Generate = &engine.Generate{ Opcode: engine.SelectUnsharded, Keyspace: autoinc.Sequence.Keyspace, Query: fmt.Sprintf("select next value from `%s`", autoinc.Sequence.Name), } // If it's also a colvindex, we have to add a redirect from route.Values. // Otherwise, we have to redirect from row[pos]. if autoinc.ColVindexNum >= 0 { route.Generate.Value = route.Values.([]interface{})[autoinc.ColVindexNum] route.Values.([]interface{})[autoinc.ColVindexNum] = ":" + engine.SeqVarName return nil } row, pos := findOrInsertPos(ins, autoinc.Col) val, err := valConvert(row[pos]) if err != nil { return fmt.Errorf("could not convert val: %s, pos: %d: %v", sqlparser.String(row[pos]), pos, err) } route.Generate.Value = val row[pos] = sqlparser.ValArg([]byte(":" + engine.SeqVarName)) return nil }