isNumericValue checks if a string represents a valid number Handles: integers, floats, scientific notation, negative numbers
(s string)
| 617 | // isNumericValue checks if a string represents a valid number |
| 618 | // Handles: integers, floats, scientific notation, negative numbers |
| 619 | func isNumericValue(s string) bool { |
| 620 | if len(s) == 0 { |
| 621 | return false |
| 622 | } |
| 623 | |
| 624 | // Quick check for common patterns |
| 625 | hasDigit := false |
| 626 | hasDot := false |
| 627 | hasE := false |
| 628 | i := 0 |
| 629 | |
| 630 | // Handle sign |
| 631 | if s[i] == '+' || s[i] == '-' { |
| 632 | i++ |
| 633 | if i >= len(s) { |
| 634 | return false |
| 635 | } |
| 636 | } |
| 637 | |
| 638 | // Parse number |
| 639 | for i < len(s) { |
| 640 | c := s[i] |
| 641 | |
| 642 | if c >= '0' && c <= '9' { |
| 643 | hasDigit = true |
| 644 | } else if c == '.' { |
| 645 | if hasDot || hasE { |
| 646 | return false // Multiple dots or dot after E |
| 647 | } |
| 648 | hasDot = true |
| 649 | } else if c == 'e' || c == 'E' { |
| 650 | if !hasDigit || hasE { |
| 651 | return false // E without digits or multiple E |
| 652 | } |
| 653 | hasE = true |
| 654 | hasDigit = false // Reset for exponent part |
| 655 | |
| 656 | // Check for sign after E |
| 657 | if i+1 < len(s) && (s[i+1] == '+' || s[i+1] == '-') { |
| 658 | i++ |
| 659 | } |
| 660 | } else if c == '_' || c == ',' { |
| 661 | // Allow thousand separators (common in data files) |
| 662 | // Skip validation, just continue |
| 663 | } else { |
| 664 | return false // Invalid character |
| 665 | } |
| 666 | i++ |
| 667 | } |
| 668 | |
| 669 | return hasDigit |
| 670 | } |
| 671 | |
| 672 | // detectAllColumnTypes automatically detects types for all columns in parallel |
| 673 | func (b *Buffer) detectAllColumnTypes() { |
no outgoing calls