(q, join *sql.Selector, ts []sql.OrderTerm)
| 436 | } |
| 437 | |
| 438 | func orderTerms(q, join *sql.Selector, ts []sql.OrderTerm) { |
| 439 | for _, t := range ts { |
| 440 | t := t |
| 441 | var ( |
| 442 | // Order by column or expression. |
| 443 | orderC string |
| 444 | orderX func(*sql.Selector) sql.Querier |
| 445 | // Order by options. |
| 446 | desc, nullsfirst, nullslast bool |
| 447 | ) |
| 448 | switch t := t.(type) { |
| 449 | case *sql.OrderFieldTerm: |
| 450 | f := t.Field |
| 451 | if t.As != "" { |
| 452 | f = t.As |
| 453 | } |
| 454 | orderC = join.C(f) |
| 455 | if t.Selected { |
| 456 | q.AppendSelect(orderC) |
| 457 | } |
| 458 | desc = t.Desc |
| 459 | nullsfirst = t.NullsFirst |
| 460 | nullslast = t.NullsLast |
| 461 | case *sql.OrderExprTerm: |
| 462 | if t.As != "" { |
| 463 | orderC = join.C(t.As) |
| 464 | if t.Selected { |
| 465 | q.AppendSelect(orderC) |
| 466 | } |
| 467 | } else { |
| 468 | orderX = t.Expr |
| 469 | } |
| 470 | desc = t.Desc |
| 471 | nullsfirst = t.NullsFirst |
| 472 | nullslast = t.NullsLast |
| 473 | default: |
| 474 | continue |
| 475 | } |
| 476 | q.OrderExprFunc(func(b *sql.Builder) { |
| 477 | // Write the ORDER BY term. |
| 478 | switch { |
| 479 | case orderC != "": |
| 480 | b.WriteString(orderC) |
| 481 | case orderX != nil: |
| 482 | b.Join(orderX(join)) |
| 483 | } |
| 484 | // Unlike MySQL and SQLite, NULL values sort as if larger than any other value. Therefore, |
| 485 | // we need to explicitly order NULLs first on ASC and last on DESC unless specified otherwise. |
| 486 | switch normalizePG := b.Dialect() == dialect.Postgres && !nullsfirst && !nullslast; { |
| 487 | case normalizePG && desc: |
| 488 | b.WriteString(" DESC NULLS LAST") |
| 489 | case normalizePG: |
| 490 | b.WriteString(" NULLS FIRST") |
| 491 | case desc: |
| 492 | b.WriteString(" DESC") |
| 493 | } |
| 494 | if nullsfirst { |
| 495 | b.WriteString(" NULLS FIRST") |
no test coverage detected
searching dependent graphs…