Skip to content

Commit

Permalink
dialect/sql: support for order by expressions in window functions (en…
Browse files Browse the repository at this point in the history
  • Loading branch information
a8m authored and gitlawr committed Apr 13, 2022
1 parent 60c5407 commit 6fa380d
Show file tree
Hide file tree
Showing 20 changed files with 39 additions and 31 deletions.
30 changes: 19 additions & 11 deletions dialect/sql/builder.go
Expand Up @@ -2711,7 +2711,7 @@ func (s *Selector) Query() (string, []interface{}) {
s.joinUnion(&b)
}
if len(s.order) > 0 {
s.joinOrder(&b)
joinOrder(s.order, &b)
}
if s.limit != nil {
b.WriteString(" LIMIT ")
Expand Down Expand Up @@ -2773,17 +2773,17 @@ func (s *Selector) joinUnion(b *Builder) {
}
}

func (s *Selector) joinOrder(b *Builder) {
func joinOrder(order []interface{}, b *Builder) {
b.WriteString(" ORDER BY ")
for i := range s.order {
for i := range order {
if i > 0 {
b.Comma()
}
switch order := s.order[i].(type) {
switch r := order[i].(type) {
case string:
b.Ident(order)
b.Ident(r)
case Querier:
b.Join(order)
b.Join(r)
}
}
}
Expand Down Expand Up @@ -2908,7 +2908,7 @@ type WindowBuilder struct {
Builder
fn string // e.g. ROW_NUMBER(), RANK().
partition func(*Builder)
order func(*Builder)
order []interface{}
}

// RowNumber returns a new window clause with the ROW_NUMBER() as a function.
Expand Down Expand Up @@ -2938,8 +2938,17 @@ func (w *WindowBuilder) PartitionExpr(x Querier) *WindowBuilder {

// OrderBy indicates how to sort rows in each partition.
func (w *WindowBuilder) OrderBy(columns ...string) *WindowBuilder {
w.order = func(b *Builder) {
b.IdentComma(columns...)
for i := range columns {
w.order = append(w.order, columns[i])
}
return w
}

// OrderExpr appends the `ORDER BY` clause to the window
// partition with custom list of expressions.
func (w *WindowBuilder) OrderExpr(exprs ...Querier) *WindowBuilder {
for i := range exprs {
w.order = append(w.order, exprs[i])
}
return w
}
Expand All @@ -2954,8 +2963,7 @@ func (w *WindowBuilder) Query() (string, []interface{}) {
w.partition(b)
}
if w.order != nil {
b.WriteString(" ORDER BY ")
w.order(b)
joinOrder(w.order, b)
}
})
return w.Builder.String(), w.args
Expand Down
4 changes: 2 additions & 2 deletions dialect/sql/builder_test.go
Expand Up @@ -2039,13 +2039,13 @@ func TestWindowFunction(t *testing.T) {
Select().
AppendSelect("*").
AppendSelectExprAs(
RowNumber().PartitionBy("author_id").OrderBy("id"),
RowNumber().PartitionBy("author_id").OrderBy("id").OrderExpr(Expr("f(`s`)")),
"row_number",
).
From(Table("active_posts")),
)
query, args := Select("*").From(Table("selected_posts")).Where(LTE("row_number", 2)).Prefix(with).Query()
require.Equal(t, "WITH `active_posts` AS (SELECT `posts`.`id`, `posts`.`content`, `posts`.`author_id` FROM `posts` WHERE `active`), `selected_posts` AS (SELECT *, (ROW_NUMBER() OVER (PARTITION BY `author_id` ORDER BY `id`)) AS `row_number` FROM `active_posts`) SELECT * FROM `selected_posts` WHERE `row_number` <= ?", query)
require.Equal(t, "WITH `active_posts` AS (SELECT `posts`.`id`, `posts`.`content`, `posts`.`author_id` FROM `posts` WHERE `active`), `selected_posts` AS (SELECT *, (ROW_NUMBER() OVER (PARTITION BY `author_id` ORDER BY `id`, f(`s`))) AS `row_number` FROM `active_posts`) SELECT * FROM `selected_posts` WHERE `row_number` <= ?", query)
require.Equal(t, []interface{}{2}, args)
}

Expand Down
2 changes: 1 addition & 1 deletion entc/gen/template/dialect/sql/feature/modifier.tmpl
Expand Up @@ -11,7 +11,7 @@ in the LICENSE file in the root directory of this source tree.
{{/* Template for adding the "modifiers" field to the query builder. */}}
{{ define "dialect/sql/query/fields/additional/modify" -}}
{{- if or ($.FeatureEnabled "sql/lock") ($.FeatureEnabled "sql/modifier") }}
modifiers []func(s *sql.Selector)
modifiers []func(*sql.Selector)
{{- end }}
{{- end -}}

Expand Down
2 changes: 1 addition & 1 deletion entc/integration/ent/card_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/ent/comment_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/ent/fieldtype_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/ent/file_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/ent/filetype_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/ent/goods_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/ent/group_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/ent/groupinfo_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/ent/item_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/ent/node_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/ent/pet_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/ent/spec_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/ent/task_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/ent/user_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/multischema/ent/group_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/multischema/ent/pet_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion entc/integration/multischema/ent/user_query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6fa380d

Please sign in to comment.