(tree *pg_query.ParseResult, result *Result)
| 20 | } |
| 21 | |
| 22 | func (t *OperatorTransform) Transform(tree *pg_query.ParseResult, result *Result) (bool, error) { |
| 23 | changed := false |
| 24 | |
| 25 | for _, stmt := range tree.Stmts { |
| 26 | if stmt.Stmt == nil { |
| 27 | continue |
| 28 | } |
| 29 | |
| 30 | if selectStmt := stmt.Stmt.GetSelectStmt(); selectStmt != nil { |
| 31 | if t.transformSelectStmt(selectStmt) { |
| 32 | changed = true |
| 33 | } |
| 34 | } else if insertStmt := stmt.Stmt.GetInsertStmt(); insertStmt != nil { |
| 35 | if t.transformInsertStmt(insertStmt) { |
| 36 | changed = true |
| 37 | } |
| 38 | } else if updateStmt := stmt.Stmt.GetUpdateStmt(); updateStmt != nil { |
| 39 | if t.transformUpdateStmt(updateStmt) { |
| 40 | changed = true |
| 41 | } |
| 42 | } else if deleteStmt := stmt.Stmt.GetDeleteStmt(); deleteStmt != nil { |
| 43 | if t.transformDeleteStmt(deleteStmt) { |
| 44 | changed = true |
| 45 | } |
| 46 | } else if ctasStmt := stmt.Stmt.GetCreateTableAsStmt(); ctasStmt != nil { |
| 47 | // CREATE TABLE AS SELECT (and CREATE OR REPLACE TABLE AS, which the |
| 48 | // transpiler routes here after stripping OR REPLACE; also CREATE |
| 49 | // MATERIALIZED VIEW AS / SELECT INTO). Without descending into the |
| 50 | // AS-SELECT body, a chained JSON arrow there is left as a raw |
| 51 | // operator and hits DuckDB's ->> precedence bug once the parens are |
| 52 | // normalized away by the pg_query round-trip — e.g. a SQLMesh |
| 53 | // `CREATE OR REPLACE TABLE ... AS ... CASE WHEN x AND (j -> 'a') ->> |
| 54 | // 'b' LIKE ... ` materialization fails with a spurious numeric cast. |
| 55 | // Query is usually a SelectStmt; for `CREATE TABLE t AS EXECUTE plan` |
| 56 | // it's an ExecuteStmt (no arrows to rewrite), so the nil-check below |
| 57 | // intentionally skips it. |
| 58 | if ctasStmt.Query != nil { |
| 59 | if ctasSelect := ctasStmt.Query.GetSelectStmt(); ctasSelect != nil { |
| 60 | if t.transformSelectStmt(ctasSelect) { |
| 61 | changed = true |
| 62 | } |
| 63 | } |
| 64 | } |
| 65 | } else if viewStmt := stmt.Stmt.GetViewStmt(); viewStmt != nil { |
| 66 | // CREATE [OR REPLACE] VIEW ... AS SELECT ... — the view body carries |
| 67 | // the same arrow-precedence risk as a CTAS body. |
| 68 | if viewStmt.Query != nil { |
| 69 | if viewSelect := viewStmt.Query.GetSelectStmt(); viewSelect != nil { |
| 70 | if t.transformSelectStmt(viewSelect) { |
| 71 | changed = true |
| 72 | } |
| 73 | } |
| 74 | } |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | return changed, nil |
| 79 | } |
nothing calls this directly
no test coverage detected