expandSelectStmt expands * in a SELECT statement including CTEs and subqueries
(ctx context.Context, stmt *ast.SelectStmt)
| 92 | |
| 93 | // expandSelectStmt expands * in a SELECT statement including CTEs and subqueries |
| 94 | func (e *Expander) expandSelectStmt(ctx context.Context, stmt *ast.SelectStmt) error { |
| 95 | // First expand any CTEs - must be done in order since later CTEs may depend on earlier ones |
| 96 | if stmt.WithClause != nil && stmt.WithClause.Ctes != nil { |
| 97 | for _, cteNode := range stmt.WithClause.Ctes.Items { |
| 98 | cte, ok := cteNode.(*ast.CommonTableExpr) |
| 99 | if !ok { |
| 100 | continue |
| 101 | } |
| 102 | cteSelect, ok := cte.Ctequery.(*ast.SelectStmt) |
| 103 | if !ok { |
| 104 | continue |
| 105 | } |
| 106 | if hasStarInList(cteSelect.TargetList) { |
| 107 | // Get column names for this CTE |
| 108 | columns, err := e.getCTEColumnNames(ctx, stmt, cte) |
| 109 | if err != nil { |
| 110 | return err |
| 111 | } |
| 112 | cteSelect.TargetList = rewriteTargetList(cteSelect.TargetList, columns) |
| 113 | } |
| 114 | // Recursively handle nested CTEs/subqueries in this CTE |
| 115 | if err := e.expandSelectStmtInner(ctx, cteSelect); err != nil { |
| 116 | return err |
| 117 | } |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | // Expand subqueries in FROM clause |
| 122 | if stmt.FromClause != nil { |
| 123 | for _, fromItem := range stmt.FromClause.Items { |
| 124 | if err := e.expandFromClause(ctx, fromItem); err != nil { |
| 125 | return err |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | // Expand the target list if it has stars |
| 131 | if hasStarInList(stmt.TargetList) { |
| 132 | // Format the current state to get columns |
| 133 | tempRaw := &ast.RawStmt{Stmt: stmt} |
| 134 | tempQuery := ast.Format(tempRaw, e.dialect) |
| 135 | columns, err := e.getColumnNames(ctx, tempQuery) |
| 136 | if err != nil { |
| 137 | return fmt.Errorf("failed to get column names: %w", err) |
| 138 | } |
| 139 | stmt.TargetList = rewriteTargetList(stmt.TargetList, columns) |
| 140 | } |
| 141 | |
| 142 | return nil |
| 143 | } |
| 144 | |
| 145 | // expandSelectStmtInner expands nested structures without re-processing the target list |
| 146 | func (e *Expander) expandSelectStmtInner(ctx context.Context, stmt *ast.SelectStmt) error { |
no test coverage detected