formatExprQuoteAware formats an expression with quote-aware column name handling. This walks the AST and uses escapeSQLIdent for column names to preserve quoting.
(expr parser.Expr)
| 5085 | // formatExprQuoteAware formats an expression with quote-aware column name handling. |
| 5086 | // This walks the AST and uses escapeSQLIdent for column names to preserve quoting. |
| 5087 | func (g *Generator) formatExprQuoteAware(expr parser.Expr) string { |
| 5088 | if expr == nil { |
| 5089 | return "" |
| 5090 | } |
| 5091 | |
| 5092 | switch e := expr.(type) { |
| 5093 | case *parser.ColName: |
| 5094 | var result string |
| 5095 | if !e.Qualifier.IsEmpty() { |
| 5096 | result = parser.String(e.Qualifier) + "." |
| 5097 | } |
| 5098 | result += g.escapeSQLIdent(e.Name) |
| 5099 | return result |
| 5100 | case *parser.ParenExpr: |
| 5101 | return "(" + g.formatExprQuoteAware(e.Expr) + ")" |
| 5102 | case *parser.ComparisonExpr: |
| 5103 | return g.formatExprQuoteAware(e.Left) + " " + e.Operator + " " + g.formatExprQuoteAware(e.Right) |
| 5104 | case *parser.AndExpr: |
| 5105 | return g.formatExprQuoteAware(e.Left) + " AND " + g.formatExprQuoteAware(e.Right) |
| 5106 | case *parser.OrExpr: |
| 5107 | return g.formatExprQuoteAware(e.Left) + " OR " + g.formatExprQuoteAware(e.Right) |
| 5108 | case *parser.ConcatExpr: |
| 5109 | return g.formatExprQuoteAware(e.Left) + " || " + g.formatExprQuoteAware(e.Right) |
| 5110 | case *parser.NotExpr: |
| 5111 | return "NOT " + g.formatExprQuoteAware(e.Expr) |
| 5112 | case *parser.BinaryExpr: |
| 5113 | return g.formatExprQuoteAware(e.Left) + " " + e.Operator + " " + g.formatExprQuoteAware(e.Right) |
| 5114 | case *parser.UnaryExpr: |
| 5115 | return e.Operator + g.formatExprQuoteAware(e.Expr) |
| 5116 | case *parser.IsExpr: |
| 5117 | // IsExpr has Operator (e.g., "is null", "is not null") and Expr |
| 5118 | return g.formatExprQuoteAware(e.Expr) + " " + e.Operator |
| 5119 | case *parser.CastExpr: |
| 5120 | return g.formatExprQuoteAware(e.Expr) + "::" + parser.String(e.Type) |
| 5121 | case *parser.AtTimeZoneExpr: |
| 5122 | return "(" + g.formatExprQuoteAware(e.Expr) + " at time zone " + g.formatExprQuoteAware(e.Zone) + ")" |
| 5123 | case *parser.FuncExpr: |
| 5124 | // For function expressions, format arguments with quote awareness |
| 5125 | // Normalize function name to lowercase (PostgreSQL convention) |
| 5126 | args := make([]string, len(e.Exprs)) |
| 5127 | for i, arg := range e.Exprs { |
| 5128 | args[i] = g.formatSelectExprQuoteAware(arg) |
| 5129 | } |
| 5130 | funcName := strings.ToLower(e.Name.Name) |
| 5131 | return funcName + "(" + strings.Join(args, ", ") + ")" |
| 5132 | case *parser.RangeCond: |
| 5133 | return g.formatExprQuoteAware(e.Left) + " BETWEEN " + g.formatExprQuoteAware(e.From) + " AND " + g.formatExprQuoteAware(e.To) |
| 5134 | case *parser.CaseExpr: |
| 5135 | var result string |
| 5136 | result = "CASE" |
| 5137 | if e.Expr != nil { |
| 5138 | result += " " + g.formatExprQuoteAware(e.Expr) |
| 5139 | } |
| 5140 | for _, when := range e.Whens { |
| 5141 | result += " WHEN " + g.formatExprQuoteAware(when.Cond) + " THEN " + g.formatExprQuoteAware(when.Val) |
| 5142 | } |
| 5143 | if e.Else != nil { |
| 5144 | result += " ELSE " + g.formatExprQuoteAware(e.Else) |