func createSplitParams( sql string, bindVariables map[string]interface{}, splitColumns []sqlparser.ColIdent, splitCount int64, numRowsPerQueryPart int64, schema map[string]*schema.Table, ) (*splitquery.SplitParams, error) { switch { case numRowsPerQueryPart != 0 && splitCount == 0: splitParams, err := splitquery.NewSplitParamsGivenNumRowsPerQueryPart( sql, bindVariables, splitColumns, numRowsPerQueryPart, schema) return splitParams, splitQueryToTabletError(err) case numRowsPerQueryPart == 0 && splitCount != 0: splitParams, err := splitquery.NewSplitParamsGivenSplitCount( sql, bindVariables, splitColumns, splitCount, schema) return splitParams, splitQueryToTabletError(err) default: panic(fmt.Sprintf("Exactly one of {numRowsPerQueryPart, splitCount} must be"+ " non zero. This should have already been caught by 'validateSplitQueryParameters' and "+ " returned as an error. Got: numRowsPerQueryPart=%v, splitCount=%v. SQL: %v", numRowsPerQueryPart, splitCount, querytypes.QueryAsString(sql, bindVariables))) } }
// SplitQueryV2 splits a query + bind variables into smaller queries that return a // subset of rows from the original query. This is the new version that supports multiple // split columns and multiple split algortihms. // See the documentation of SplitQueryRequest in proto/vtgate.proto for more details. func (tsv *TabletServer) SplitQueryV2( ctx context.Context, target *querypb.Target, sql string, bindVariables map[string]interface{}, splitColumns []string, splitCount int64, numRowsPerQueryPart int64, algorithm querypb.SplitQueryRequest_Algorithm, sessionID int64) (splits []querytypes.QuerySplit, err error) { if err := validateSplitQueryParameters( sql, bindVariables, splitColumns, splitCount, numRowsPerQueryPart, algorithm, sessionID); err != nil { return nil, err } // TODO(erez): ASSERT/Check that we are a rdonly tablet. logStats := newLogStats("SplitQuery", ctx) logStats.OriginalSQL = sql logStats.BindVariables = bindVariables defer handleError(&err, logStats, tsv.qe.queryServiceStats) if err = tsv.startRequest(target, sessionID, false, false); err != nil { return nil, err } ctx, cancel := withTimeout(ctx, tsv.QueryTimeout.Get()) defer func() { cancel() tsv.endRequest(false) }() schema := getSchemaForSplitQuery(tsv.qe.schemaInfo) var splitParams *splitquery.SplitParams switch { case numRowsPerQueryPart != 0 && splitCount == 0: splitParams, err = splitquery.NewSplitParamsGivenNumRowsPerQueryPart( sql, bindVariables, splitColumns, numRowsPerQueryPart, schema) case numRowsPerQueryPart == 0 && splitCount != 0: splitParams, err = splitquery.NewSplitParamsGivenSplitCount( sql, bindVariables, splitColumns, splitCount, schema) default: panic(fmt.Sprintf("Exactly one of {numRowsPerQueryPart, splitCount} must be"+ " non zero. This should have already been caught by 'validateSplitQueryParameters' and "+ " returned as an error. Got: numRowsPerQueryPart=%v, splitCount=%v. SQL: %v", numRowsPerQueryPart, splitCount, querytypes.QueryAsString(sql, bindVariables))) } // TODO(erez): Make the splitquery package return tabletserver errors. if err != nil { return nil, err } defer func(start time.Time) { addUserTableQueryStats( tsv.qe.queryServiceStats, ctx, splitParams.GetSplitTableName(), "SplitQuery", int64(time.Now().Sub(start))) }(time.Now()) sqlExecuter := &splitQuerySQLExecuter{ queryExecutor: &QueryExecutor{ ctx: ctx, logStats: logStats, qe: tsv.qe, }, } algorithmObject, err := createSplitQueryAlgorithmObject(algorithm, splitParams, sqlExecuter) if err != nil { return nil, err } // TODO(erez): Make the splitquery package use Vitess error codes. return splitquery.NewSplitter(splitParams, algorithmObject).Split() }