Skip to content
This repository was archived by the owner on Jan 28, 2021. It is now read-only.

Commit 7ce74fb

Browse files
authored
Merge pull request #525 from kuba--/tableau-520/group-by
Implement group by index
2 parents 5749664 + 7581128 commit 7ce74fb

File tree

6 files changed

+135
-3
lines changed

6 files changed

+135
-3
lines changed

engine_test.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ var queries = []struct {
113113
"SELECT i FROM mytable WHERE i NOT BETWEEN 1 AND 2",
114114
[]sql.Row{{int64(3)}},
115115
},
116+
{
117+
"SELECT substring(mytable.s, 1, 5) as s FROM mytable INNER JOIN othertable ON (substring(mytable.s, 1, 5) = SUBSTRING(othertable.s2, 1, 5)) GROUP BY 1",
118+
[]sql.Row{
119+
{"third"},
120+
{"secon"},
121+
{"first"},
122+
},
123+
},
116124
{
117125
"SELECT i, i2, s2 FROM mytable INNER JOIN othertable ON i = i2",
118126
[]sql.Row{
@@ -159,6 +167,18 @@ var queries = []struct {
159167
{int32(1), "third row"},
160168
},
161169
},
170+
{
171+
`SELECT COUNT(*) as cnt, fi FROM (
172+
SELECT tbl.s AS fi
173+
FROM mytable tbl
174+
) t
175+
GROUP BY 2`,
176+
[]sql.Row{
177+
{int32(1), "first row"},
178+
{int32(1), "second row"},
179+
{int32(1), "third row"},
180+
},
181+
},
162182
{
163183
`SELECT COUNT(*) as cnt, s as fi FROM mytable GROUP BY fi`,
164184
[]sql.Row{
@@ -167,6 +187,14 @@ var queries = []struct {
167187
{int32(1), "third row"},
168188
},
169189
},
190+
{
191+
`SELECT COUNT(*) as cnt, s as fi FROM mytable GROUP BY 2`,
192+
[]sql.Row{
193+
{int32(1), "first row"},
194+
{int32(1), "second row"},
195+
{int32(1), "third row"},
196+
},
197+
},
170198
{
171199
"SELECT CAST(-3 AS UNSIGNED) FROM mytable",
172200
[]sql.Row{
@@ -296,6 +324,14 @@ var queries = []struct {
296324
{int32(1), int64(1)},
297325
},
298326
},
327+
{
328+
`SELECT COUNT(*) c, i as foo FROM mytable GROUP BY 2 ORDER BY 2 DESC`,
329+
[]sql.Row{
330+
{int32(1), int64(3)},
331+
{int32(1), int64(2)},
332+
{int32(1), int64(1)},
333+
},
334+
},
299335
{
300336
`SELECT COUNT(*) c, i as foo FROM mytable GROUP BY i ORDER BY foo, i DESC`,
301337
[]sql.Row{
@@ -304,6 +340,30 @@ var queries = []struct {
304340
{int32(1), int64(1)},
305341
},
306342
},
343+
{
344+
`SELECT COUNT(*) c, i as foo FROM mytable GROUP BY 2 ORDER BY foo, i DESC`,
345+
[]sql.Row{
346+
{int32(1), int64(3)},
347+
{int32(1), int64(2)},
348+
{int32(1), int64(1)},
349+
},
350+
},
351+
{
352+
`SELECT COUNT(*) c, i as i FROM mytable GROUP BY 2`,
353+
[]sql.Row{
354+
{int32(1), int64(3)},
355+
{int32(1), int64(2)},
356+
{int32(1), int64(1)},
357+
},
358+
},
359+
{
360+
`SELECT i as i FROM mytable GROUP BY 1`,
361+
[]sql.Row{
362+
{int64(3)},
363+
{int64(2)},
364+
{int64(1)},
365+
},
366+
},
307367
{
308368
`SELECT CONCAT("a", "b", "c")`,
309369
[]sql.Row{
@@ -370,6 +430,12 @@ var queries = []struct {
370430
{"third row"},
371431
},
372432
},
433+
{
434+
`SELECT SUBSTRING(s, -3, 3) as s FROM mytable WHERE s LIKE '%d row' GROUP BY 1`,
435+
[]sql.Row{
436+
{"row"},
437+
},
438+
},
373439
{
374440
`SELECT s FROM mytable WHERE s NOT LIKE '%d row'`,
375441
[]sql.Row{
@@ -560,6 +626,32 @@ var queries = []struct {
560626
{"i2"},
561627
},
562628
},
629+
{
630+
`
631+
SELECT COLUMN_NAME FROM information_schema.COLUMNS
632+
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME LIKE '%table'
633+
GROUP BY 1
634+
`,
635+
[]sql.Row{
636+
{"s"},
637+
{"i"},
638+
{"s2"},
639+
{"i2"},
640+
},
641+
},
642+
{
643+
`
644+
SELECT COLUMN_NAME as COLUMN_NAME FROM information_schema.COLUMNS
645+
WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME LIKE '%table'
646+
GROUP BY 1
647+
`,
648+
[]sql.Row{
649+
{"s"},
650+
{"i"},
651+
{"s2"},
652+
{"i2"},
653+
},
654+
},
563655
{
564656
`SHOW CREATE DATABASE mydb`,
565657
[]sql.Row{{
@@ -1491,6 +1583,17 @@ func TestOrderByGroupBy(t *testing.T) {
14911583
}
14921584

14931585
require.Equal(expected, rows)
1586+
1587+
_, iter, err = e.Query(
1588+
newCtx(),
1589+
"SELECT team, COUNT(*) FROM members GROUP BY 1 ORDER BY 2",
1590+
)
1591+
require.NoError(err)
1592+
1593+
rows, err = sql.RowIterToRows(iter)
1594+
require.NoError(err)
1595+
1596+
require.Equal(expected, rows)
14941597
}
14951598

14961599
func TestTracing(t *testing.T) {

sql/analyzer/resolve_columns.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ func qualifyColumns(ctx *sql.Context, a *Analyzer, n sql.Node) (sql.Node, error)
104104
col.Name(),
105105
)
106106
default:
107+
if _, ok := n.(*plan.GroupBy); ok {
108+
return expression.NewUnresolvedColumn(col.Name()), nil
109+
}
107110
return nil, ErrAmbiguousColumnName.New(col.Name(), strings.Join(tables, ", "))
108111
}
109112
} else {
@@ -303,7 +306,8 @@ func resolveColumns(ctx *sql.Context, a *Analyzer, n sql.Node) (sql.Node, error)
303306
var col *sql.Column
304307
var found bool
305308
for _, c := range columns {
306-
if strings.ToLower(c.Source) == table {
309+
_, ok := n.(*plan.GroupBy)
310+
if ok || (strings.ToLower(c.Source) == table) {
307311
col = c
308312
found = true
309313
break

sql/analyzer/validation_rules.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func validateOrderBy(ctx *sql.Context, a *Analyzer, n sql.Node) (sql.Node, error
7777
}
7878

7979
func validateGroupBy(ctx *sql.Context, a *Analyzer, n sql.Node) (sql.Node, error) {
80-
span, ctx := ctx.Span("validate_order_by")
80+
span, ctx := ctx.Span("validate_group_by")
8181
defer span.Finish()
8282

8383
switch n := n.(type) {

sql/expression/function/time_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ func TestTime_DayOfWeek(t *testing.T) {
243243
{"null date", sql.NewRow(nil), nil, false},
244244
{"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false},
245245
{"date as string", sql.NewRow(stringDate), int32(3), false},
246-
{"date as time", sql.NewRow(time.Now()), int32(time.Now().UTC().Weekday()+1) % 7, false},
246+
{"date as time", sql.NewRow(time.Now()), int32(time.Now().UTC().Weekday() + 1), false},
247247
{"date as unix timestamp", sql.NewRow(int64(tsDate)), int32(1), false},
248248
}
249249

sql/parse/parse.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,20 @@ func selectToProjectOrGroupBy(se sqlparser.SelectExprs, g sqlparser.GroupBy, chi
615615
return nil, err
616616
}
617617

618+
agglen := int64(len(selectExprs))
619+
for i, ge := range groupingExprs {
620+
// if GROUP BY index
621+
if l, ok := ge.(*expression.Literal); ok && sql.IsNumber(l.Type()) {
622+
if idx, ok := l.Value().(int64); ok && idx > 0 && idx <= agglen {
623+
aggexpr := selectExprs[idx-1]
624+
if alias, ok := aggexpr.(*expression.Alias); ok {
625+
aggexpr = expression.NewUnresolvedColumn(alias.Name())
626+
}
627+
groupingExprs[i] = aggexpr
628+
}
629+
}
630+
}
631+
618632
return plan.NewGroupBy(selectExprs, groupingExprs, child), nil
619633
}
620634

sql/parse/parse_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,17 @@ var fixtures = map[string]sql.Node{
193193
},
194194
plan.NewUnresolvedTable("t1", ""),
195195
),
196+
`SELECT foo, bar FROM t1 GROUP BY 1, 2;`: plan.NewGroupBy(
197+
[]sql.Expression{
198+
expression.NewUnresolvedColumn("foo"),
199+
expression.NewUnresolvedColumn("bar"),
200+
},
201+
[]sql.Expression{
202+
expression.NewUnresolvedColumn("foo"),
203+
expression.NewUnresolvedColumn("bar"),
204+
},
205+
plan.NewUnresolvedTable("t1", ""),
206+
),
196207
`SELECT COUNT(*) FROM t1;`: plan.NewGroupBy(
197208
[]sql.Expression{
198209
expression.NewUnresolvedFunction("count", true,

0 commit comments

Comments
 (0)