(selectQuery string)
| 565 | } |
| 566 | |
| 567 | func (p *identifiersParser) parse(selectQuery string) error { |
| 568 | str := strings.Trim(strings.TrimSpace(selectQuery), ";") |
| 569 | str = commentsReplaceRegex.ReplaceAllString(str, " ") |
| 570 | str = joinReplaceRegex.ReplaceAllString(str, " __pb_join__ ") |
| 571 | str = discardReplaceRegex.ReplaceAllString(str, " __pb_discard__ ") |
| 572 | |
| 573 | tk := tokenizer.NewFromString(str) |
| 574 | tk.Separators(',', ' ', '\n', '\t') |
| 575 | tk.KeepSeparator(true) |
| 576 | |
| 577 | var skip bool |
| 578 | var partType string |
| 579 | var activeBuilder *strings.Builder |
| 580 | var selectParts strings.Builder |
| 581 | var fromParts strings.Builder |
| 582 | var joinParts strings.Builder |
| 583 | |
| 584 | for { |
| 585 | token, err := tk.Scan() |
| 586 | if err != nil { |
| 587 | if err != io.EOF { |
| 588 | return err |
| 589 | } |
| 590 | break |
| 591 | } |
| 592 | |
| 593 | trimmed := strings.ToLower(strings.TrimSpace(token)) |
| 594 | |
| 595 | switch trimmed { |
| 596 | case "select": |
| 597 | skip = false |
| 598 | partType = "select" |
| 599 | activeBuilder = &selectParts |
| 600 | case "distinct": |
| 601 | continue // ignore as it is not important for the identifiers parsing |
| 602 | case "from": |
| 603 | skip = false |
| 604 | partType = "from" |
| 605 | activeBuilder = &fromParts |
| 606 | case "__pb_join__": |
| 607 | skip = false |
| 608 | |
| 609 | // the previous part was also a join |
| 610 | if partType == "join" { |
| 611 | joinParts.WriteString(",") |
| 612 | } |
| 613 | |
| 614 | partType = "join" |
| 615 | activeBuilder = &joinParts |
| 616 | case "__pb_discard__": |
| 617 | // skip following tokens |
| 618 | skip = true |
| 619 | default: |
| 620 | isJoin := partType == "join" |
| 621 | |
| 622 | if isJoin && trimmed == "on" { |
| 623 | skip = true |
| 624 | } |
nothing calls this directly
no test coverage detected