// SplitQuery splits a query into sub queries by appending keyranges and // primary key range clauses. Rows corresponding to the sub queries // are guaranteed to be non-overlapping and will add up to the rows of // original query. Number of sub queries will be a multiple of N that is // greater than or equal to SplitQueryRequest.SplitCount, where N is the // number of shards. func (vtg *VTGate) SplitQuery(ctx context.Context, req *proto.SplitQueryRequest, reply *proto.SplitQueryResult) error { sc := vtg.resolver.scatterConn keyspace, srvKeyspace, shards, err := getKeyspaceShards(ctx, sc.toposerv, sc.cell, req.Keyspace, topo.TYPE_RDONLY) if err != nil { return err } perShardSplitCount := int(math.Ceil(float64(req.SplitCount) / float64(len(shards)))) if srvKeyspace.ShardingColumnName != "" { // we are using range-based sharding, so the result // will be a list of Splits with KeyRange clauses keyRangeByShard := map[string]kproto.KeyRange{} for _, shard := range shards { keyRangeByShard[shard.Name] = shard.KeyRange } splits, err := vtg.resolver.scatterConn.SplitQueryKeyRange(ctx, req.Query, req.SplitColumn, perShardSplitCount, keyRangeByShard, keyspace) if err != nil { return err } reply.Splits = splits return nil } // we are using custom sharding, so the result // will be a list of Splits with Shard clauses shardNames := make([]string, len(shards)) for i, shard := range shards { shardNames[i] = shard.Name } splits, err := vtg.resolver.scatterConn.SplitQueryCustomSharding(ctx, req.Query, req.SplitColumn, perShardSplitCount, shardNames, keyspace) if err != nil { return err } reply.Splits = splits return nil }
// SplitQuery splits a query into sub queries by appending keyranges and // primary key range clauses. Rows corresponding to the sub queries // are guaranteed to be non-overlapping and will add up to the rows of // original query. Number of sub queries will be a multiple of N that is // greater than or equal to SplitQueryRequest.SplitCount, where N is the // number of shards. func (vtg *VTGate) SplitQuery(ctx context.Context, keyspace string, sql string, bindVariables map[string]interface{}, splitColumn string, splitCount int, reply *proto.SplitQueryResult) error { keyspace, srvKeyspace, shards, err := getKeyspaceShards(ctx, vtg.resolver.toposerv, vtg.resolver.cell, keyspace, pb.TabletType_RDONLY) if err != nil { return err } perShardSplitCount := int(math.Ceil(float64(splitCount) / float64(len(shards)))) if srvKeyspace.ShardingColumnName != "" { // we are using range-based sharding, so the result // will be a list of Splits with KeyRange clauses keyRangeByShard := make(map[string]*pb.KeyRange) for _, shard := range shards { keyRangeByShard[shard.Name] = shard.KeyRange } splits, err := vtg.resolver.scatterConn.SplitQueryKeyRange(ctx, sql, bindVariables, splitColumn, perShardSplitCount, keyRangeByShard, keyspace) if err != nil { return err } reply.Splits = splits return nil } // we are using custom sharding, so the result // will be a list of Splits with Shard clauses shardNames := make([]string, len(shards)) for i, shard := range shards { shardNames[i] = shard.Name } splits, err := vtg.resolver.scatterConn.SplitQueryCustomSharding(ctx, sql, bindVariables, splitColumn, perShardSplitCount, shardNames, keyspace) if err != nil { return err } reply.Splits = splits return nil }
func (c *echoClient) SplitQuery(ctx context.Context, keyspace string, sql string, bindVariables map[string]interface{}, splitColumn string, splitCount int, reply *proto.SplitQueryResult) error { if strings.HasPrefix(sql, EchoPrefix) { reply.Splits = append(reply.Splits, proto.SplitQueryPart{ Query: &proto.KeyRangeQuery{ Sql: fmt.Sprintf("%v:%v:%v", sql, splitColumn, splitCount), BindVariables: bindVariables, Keyspace: keyspace, }, }) return nil } return c.fallback.SplitQuery(ctx, sql, keyspace, bindVariables, splitColumn, splitCount, reply) }
// SplitQuery is the RPC version of vtgateservice.VTGateService method func (vtg *VTGate) SplitQuery(ctx context.Context, request *proto.SplitQueryRequest, reply *proto.SplitQueryResult) (err error) { defer vtg.server.HandlePanic(&err) ctx, cancel := context.WithDeadline(ctx, time.Now().Add(*rpcTimeout)) defer cancel() ctx = callerid.NewContext(ctx, callerid.GoRPCEffectiveCallerID(request.CallerID), callerid.NewImmediateCallerID("gorpc client")) splits, vtgErr := vtg.server.SplitQuery(ctx, request.Keyspace, request.Query.Sql, request.Query.BindVariables, request.SplitColumn, request.SplitCount) reply.Splits = splits vtgate.AddVtGateError(vtgErr, &reply.Err) return nil }
// SplitQuery splits a query into sub queries by appending keyranges and // primary key range clauses. Rows corresponding to the sub queries // are guaranteed to be non-overlapping and will add up to the rows of // original query. Number of sub queries will be a multiple of N that is // greater than or equal to SplitQueryRequest.SplitCount, where N is the // number of shards. func (vtg *VTGate) SplitQuery(context context.Context, req *proto.SplitQueryRequest, reply *proto.SplitQueryResult) (err error) { defer handlePanic(&err) sc := vtg.resolver.scatterConn keyspace, shards, err := getKeyspaceShards(sc.toposerv, sc.cell, req.Keyspace, topo.TYPE_RDONLY) if err != nil { return err } keyRangeByShard := map[string]kproto.KeyRange{} for _, shard := range shards { keyRangeByShard[shard.ShardName()] = shard.KeyRange } perShardSplitCount := int(math.Ceil(float64(req.SplitCount) / float64(len(shards)))) splits, err := vtg.resolver.scatterConn.SplitQuery(context, req.Query, perShardSplitCount, keyRangeByShard, keyspace) if err != nil { return err } reply.Splits = splits return nil }