applyTiDBLineTracking sets OriginTextPosition on a freshly-parsed pingcap node and walks CREATE TABLE columns to set their per-column line numbers via SetLineForMySQLCreateTableStmt. Used by both ParseTiDBForSyntaxCheck (the canonical pre-flip parsing path) and OmniAST.AsPingCapAST (the post-flip br
(node ast.StmtNode, baseLine int, originalText string)
| 71 | // Returns the 1-based actualStartLine (`baseLine + leadingNewlinesStripped + |
| 72 | // 1`) so callers can use it for *AST.StartPosition. |
| 73 | func applyTiDBLineTracking(node ast.StmtNode, baseLine int, originalText string) (int, error) { |
| 74 | // The statement's absolute start line is baseLine plus the number of |
| 75 | // newlines in its leading whitespace (the blank lines before the first |
| 76 | // token). Counting the leading newlines of originalText directly is robust; |
| 77 | // the native parser's node.Text() does not reliably strip ALL leading |
| 78 | // newlines, so diffing original-vs-native newline counts under-counts when |
| 79 | // more than one blank line precedes the statement (BYT-9381). This keeps the |
| 80 | // pingcap-bridge line in step with the omni path's FirstTokenLine. |
| 81 | leadingWhitespace := originalText[:len(originalText)-len(strings.TrimLeft(originalText, " \t\r\n"))] |
| 82 | actualStartLine := baseLine + strings.Count(leadingWhitespace, "\n") + 1 |
| 83 | |
| 84 | node.SetOriginTextPosition(actualStartLine) |
| 85 | if n, ok := node.(*ast.CreateTableStmt); ok { |
| 86 | if err := SetLineForMySQLCreateTableStmt(n); err != nil { |
| 87 | return actualStartLine, errors.Wrapf(err, "failed to set line for create table statement at line %d", actualStartLine) |
| 88 | } |
| 89 | } |
| 90 | return actualStartLine, nil |
| 91 | } |
| 92 | |
| 93 | func newTiDBParser() *tidbparser.Parser { |
| 94 | p := tidbparser.New() |