()
| 400 | } |
| 401 | |
| 402 | func (g *ScanQueryGenerator) buildSQL() (string, error) { |
| 403 | if g.limit <= 0 { |
| 404 | return "", errors.Errorf("invalid limit '%d'", g.limit) |
| 405 | } |
| 406 | |
| 407 | if g.exhausted { |
| 408 | return "", nil |
| 409 | } |
| 410 | |
| 411 | b := NewSQLBuilder(g.tbl) |
| 412 | if err := b.WriteSelect(); err != nil { |
| 413 | return "", err |
| 414 | } |
| 415 | if len(g.stack) > 0 { |
| 416 | for i, d := range g.stack[len(g.stack)-1] { |
| 417 | col := []*model.ColumnInfo{g.tbl.KeyColumns[i]} |
| 418 | val := []types.Datum{d} |
| 419 | var err error |
| 420 | if i < len(g.stack)-1 { |
| 421 | err = b.WriteCommonCondition(col, "=", val) |
| 422 | } else if g.firstBuild { |
| 423 | // When `g.firstBuild == true`, that means we are querying rows after range start, because range is defined |
| 424 | // as [start, end), we should use ">=" to find the rows including start key. |
| 425 | err = b.WriteCommonCondition(col, ">=", val) |
| 426 | } else { |
| 427 | // Otherwise when `g.firstBuild != true`, that means we are continuing with the previous result, we should use |
| 428 | // ">" to exclude the previous row. |
| 429 | err = b.WriteCommonCondition(col, ">", val) |
| 430 | } |
| 431 | if err != nil { |
| 432 | return "", err |
| 433 | } |
| 434 | } |
| 435 | } |
| 436 | |
| 437 | if len(g.keyRangeEnd) > 0 { |
| 438 | if err := b.WriteCommonCondition(g.tbl.KeyColumns[0:len(g.keyRangeEnd)], "<", g.keyRangeEnd); err != nil { |
| 439 | return "", err |
| 440 | } |
| 441 | } |
| 442 | |
| 443 | if err := b.WriteExpireCondition(g.expire); err != nil { |
| 444 | return "", err |
| 445 | } |
| 446 | |
| 447 | if err := b.WriteOrderBy(g.tbl.KeyColumns, false); err != nil { |
| 448 | return "", err |
| 449 | } |
| 450 | |
| 451 | if err := b.WriteLimit(g.limit); err != nil { |
| 452 | return "", err |
| 453 | } |
| 454 | |
| 455 | return b.Build() |
| 456 | } |
| 457 | |
| 458 | // BuildDeleteSQL builds a delete SQL |
| 459 | func BuildDeleteSQL(tbl *cache.PhysicalTable, rows [][]types.Datum, expire time.Time) (string, error) { |
no test coverage detected