Skip to content

Commit d67d707

Browse files
feat: increment version to 0.0.16; enhance GROUP BY handling in SQL to MongoDB conversion to support aliases and complex expressions
1 parent 2671a73 commit d67d707

3 files changed

Lines changed: 56 additions & 2 deletions

File tree

internal/converter/converter_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,39 @@ func TestConverter_ConvertSQLToMongo(t *testing.T) {
292292
},
293293
},
294294
},
295+
{
296+
name: "SELECT with CAST and GROUP BY aliases",
297+
sql: "SELECT CAST(strftime(created_at, '%Y') AS INTEGER) as year, COUNT(*) as count FROM orders GROUP BY year",
298+
expected: []map[string]interface{}{
299+
{
300+
"$group": map[string]interface{}{
301+
"_id": map[string]interface{}{
302+
"group_0": map[string]interface{}{
303+
"$dateToString": map[string]interface{}{
304+
"date": "$created_at",
305+
"format": "%Y",
306+
},
307+
},
308+
},
309+
"count": map[string]interface{}{
310+
"$sum": 1,
311+
},
312+
},
313+
},
314+
{
315+
"$project": map[string]interface{}{
316+
"_id": 0,
317+
"count": "$count",
318+
"year": map[string]interface{}{
319+
"$dateToString": map[string]interface{}{
320+
"date": "$created_at",
321+
"format": "%Y",
322+
},
323+
},
324+
},
325+
},
326+
},
327+
},
295328
{
296329
name: "Invalid SQL",
297330
sql: "INVALID SQL QUERY",

internal/converter/parser.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,14 @@ func (c *Converter) BuildGroupStage(groupBy sqlparser.GroupBy, selectExprs sqlpa
12261226
"_id": make(map[string]interface{}),
12271227
}
12281228

1229+
// Build a map of aliases to their expressions from SELECT clause
1230+
aliasMap := make(map[string]sqlparser.Expr)
1231+
for _, selExpr := range selectExprs {
1232+
if aliasedExpr, ok := selExpr.(*sqlparser.AliasedExpr); ok && !aliasedExpr.As.IsEmpty() {
1233+
aliasMap[aliasedExpr.As.String()] = aliasedExpr.Expr
1234+
}
1235+
}
1236+
12291237
// Handle GROUP BY columns
12301238
idGroup := group["_id"].(map[string]interface{})
12311239
for i, expr := range groupBy {
@@ -1234,7 +1242,20 @@ func (c *Converter) BuildGroupStage(groupBy sqlparser.GroupBy, selectExprs sqlpa
12341242
case *sqlparser.ColName:
12351243
colName := c.getFullColumnName(groupExpr)
12361244
fieldName := groupExpr.Name.String()
1237-
idGroup[fieldName] = "$" + colName
1245+
1246+
// Check if this is an alias from the SELECT clause
1247+
if aliasedExpr, isAlias := aliasMap[fieldName]; isAlias {
1248+
// Use the original expression instead of the alias
1249+
fieldName = fmt.Sprintf("group_%d", i)
1250+
aliasExpr, err := c.buildFunctionExpression(aliasedExpr.(*sqlparser.FuncExpr))
1251+
if err != nil {
1252+
return nil, fmt.Errorf("failed to build GROUP BY alias expression: %w", err)
1253+
}
1254+
idGroup[fieldName] = aliasExpr
1255+
} else {
1256+
// Regular column reference
1257+
idGroup[fieldName] = "$" + colName
1258+
}
12381259
case *sqlparser.FuncExpr:
12391260
// Handle function expressions in GROUP BY (like CAST(strftime(...)))
12401261
// Use generic field name for complex expressions

version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
package main
22

3-
var Version = "0.0.15"
3+
var Version = "0.0.16"

0 commit comments

Comments
 (0)