| 194 | } |
| 195 | |
| 196 | func TestExpressionSQL(t *testing.T) { |
| 197 | tests := []struct { |
| 198 | name string |
| 199 | expr Expression |
| 200 | want string |
| 201 | }{ |
| 202 | {"between", &BetweenExpression{Expr: &Identifier{Name: "age"}, Lower: &LiteralValue{Value: 18, Type: "INTEGER"}, Upper: &LiteralValue{Value: 65, Type: "INTEGER"}}, "age BETWEEN 18 AND 65"}, |
| 203 | {"not between", &BetweenExpression{Expr: &Identifier{Name: "age"}, Lower: &LiteralValue{Value: 18, Type: "INTEGER"}, Upper: &LiteralValue{Value: 65, Type: "INTEGER"}, Not: true}, "age NOT BETWEEN 18 AND 65"}, |
| 204 | {"in list", &InExpression{Expr: &Identifier{Name: "status"}, List: []Expression{&LiteralValue{Value: "active", Type: "STRING"}, &LiteralValue{Value: "pending", Type: "STRING"}}}, "status IN ('active', 'pending')"}, |
| 205 | {"case", &CaseExpression{WhenClauses: []WhenClause{{Condition: &BinaryExpression{Left: &Identifier{Name: "x"}, Operator: ">", Right: &LiteralValue{Value: 0, Type: "INTEGER"}}, Result: &LiteralValue{Value: "positive", Type: "STRING"}}}, ElseClause: &LiteralValue{Value: "non-positive", Type: "STRING"}}, "CASE WHEN x > 0 THEN 'positive' ELSE 'non-positive' END"}, |
| 206 | {"cast", &CastExpression{Expr: &Identifier{Name: "price"}, Type: "INTEGER"}, "CAST(price AS INTEGER)"}, |
| 207 | {"extract", &ExtractExpression{Field: "YEAR", Source: &Identifier{Name: "created_at"}}, "EXTRACT(YEAR FROM created_at)"}, |
| 208 | {"interval", &IntervalExpression{Value: "1 day"}, "INTERVAL '1 day'"}, |
| 209 | {"array", &ArrayConstructorExpression{Elements: []Expression{&LiteralValue{Value: 1, Type: "INTEGER"}, &LiteralValue{Value: 2, Type: "INTEGER"}}}, "ARRAY[1, 2]"}, |
| 210 | {"unary not", &UnaryExpression{Operator: Not, Expr: &Identifier{Name: "active"}}, "NOT active"}, |
| 211 | {"null", &LiteralValue{Value: nil, Type: "NULL"}, "NULL"}, |
| 212 | {"is null", &BinaryExpression{Left: &Identifier{Name: "email"}, Operator: "IS NULL", Right: &LiteralValue{Value: nil, Type: "null"}}, "email IS NULL"}, |
| 213 | {"tuple", &TupleExpression{Expressions: []Expression{&LiteralValue{Value: 1, Type: "INTEGER"}, &LiteralValue{Value: "a", Type: "STRING"}}}, "(1, 'a')"}, |
| 214 | } |
| 215 | for _, tt := range tests { |
| 216 | t.Run(tt.name, func(t *testing.T) { |
| 217 | if got := exprSQL(tt.expr); got != tt.want { |
| 218 | t.Errorf("SQL() = %s, want %s", got, tt.want) |
| 219 | } |
| 220 | }) |
| 221 | } |
| 222 | } |
| 223 | |
| 224 | func TestWindowFunctionSQL(t *testing.T) { |
| 225 | stmt := &SelectStatement{ |