MCPcopy
hub / github.com/sqldef/sqldef / parsePgquery

Method parsePgquery

database/postgres/parser.go:100–163  ·  view source on GitHub ↗

parsePgquery parses SQL using the pgquery parser

(sql string)

Source from the content-addressed store, hash-verified

98
99// parsePgquery parses SQL using the pgquery parser
100func (p PostgresParser) parsePgquery(sql string) ([]database.DDLStatement, error) {
101 result, err := go_pgquery.Parse(sql)
102 if err != nil {
103 return nil, err
104 }
105
106 var statements []database.DDLStatement
107 for _, rawStmt := range result.Stmts {
108 var ddl string
109 if rawStmt.StmtLen == 0 {
110 ddl = sql[rawStmt.StmtLocation:]
111 } else {
112 ddl = sql[rawStmt.StmtLocation : rawStmt.StmtLocation+rawStmt.StmtLen]
113 }
114 ddl = strings.TrimSpace(ddl)
115
116 // Attempt to convert pgquery AST to our generic AST format
117 stmt, err := p.parseStmt(rawStmt.Stmt)
118 if err != nil {
119 // Check if this is a validation error (should not fallback)
120 if _, ok := err.(validationError); ok {
121 return nil, err
122 }
123
124 // In Auto mode, if we can't convert the pgquery AST to generic AST,
125 // try parsing this individual statement with the generic parser directly.
126 // This handles cases where the generic parser can parse the statement
127 // but we haven't implemented the AST conversion from pgquery yet.
128 var stmts []database.DDLStatement
129 if p.mode == PsqldefParserModeAuto {
130 slog.Debug("pgquery AST conversion failed, trying generic parser for this statement", "error", err.Error())
131 stmts, err = p.parser.Parse(ddl)
132 }
133 if err != nil {
134 return nil, err
135 }
136
137 statements = append(statements, stmts...)
138 continue
139 }
140
141 // In Auto mode, an Ignore means pgquery has no AST conversion for this node
142 // type (e.g. CREATE FUNCTION). The generic parser does support these, so retry
143 // the single statement before keeping the Ignore. Without this the desired
144 // schema silently loses the statement while the current schema (introspected
145 // from the DB) keeps it, producing a destructive diff such as a spurious
146 // DROP FUNCTION. Pgquery-only mode keeps the Ignore unchanged (PR #1116 intent).
147 if _, isIgnore := stmt.(*parser.Ignore); isIgnore && p.mode == PsqldefParserModeAuto {
148 stmts, retryErr := p.parser.Parse(ddl)
149 if retryErr == nil {
150 statements = append(statements, stmts...)
151 continue
152 }
153 slog.Debug("generic parser also failed for Ignore-d statement, keeping Ignore", "error", retryErr.Error())
154 }
155
156 statements = append(statements, database.DDLStatement{
157 DDL: ddl,

Callers 1

ParseMethod · 0.95

Calls 3

parseStmtMethod · 0.95
ParseMethod · 0.65
ErrorMethod · 0.65

Tested by

no test coverage detected