From 13507a59eeb12abeb9e896ee5033231b2bd316aa Mon Sep 17 00:00:00 2001 From: Ethan Hur Date: Sat, 19 Oct 2019 19:54:15 +0900 Subject: [PATCH 1/3] orderBy accepts QueryBuilder correctly --- lib/query/compiler.js | 17 +++++++++++++---- test/unit/query/builder.js | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/lib/query/compiler.js b/lib/query/compiler.js index f31de0af04..89170cb1ee 100644 --- a/lib/query/compiler.js +++ b/lib/query/compiler.js @@ -2,6 +2,7 @@ // ------- const helpers = require('../helpers'); const Raw = require('../raw'); +const QueryBuilder = require('./builder'); const JoinClause = require('./joinclause'); const debug = require('debug'); @@ -823,16 +824,24 @@ assign(QueryCompiler.prototype, { return vals; }, + _formatGroupsItemValue(value) { + const { formatter } = this; + if (value instanceof Raw) { + return formatter.unwrapRaw(value); + } else if (value instanceof QueryBuilder) { + return '(' + formatter.columnize(value) + ')'; + } else { + return formatter.columnize(value); + } + }, + // Compiles the `order by` statements. _groupsOrders(type) { const items = this.grouped[type]; if (!items) return ''; const { formatter } = this; const sql = items.map((item) => { - const column = - item.value instanceof Raw - ? formatter.unwrapRaw(item.value) - : formatter.columnize(item.value); + const column = this._formatGroupsItemValue(item.value); const direction = type === 'order' && item.type !== 'orderByRaw' ? ` ${formatter.direction(item.direction)}` diff --git a/test/unit/query/builder.js b/test/unit/query/builder.js index eba8f0867d..2f91e1bcfc 100644 --- a/test/unit/query/builder.js +++ b/test/unit/query/builder.js @@ -3176,6 +3176,43 @@ describe('QueryBuilder', () => { ); }); + it('order by accepts query builder', () => { + testsql( + qb() + .select() + .from('persons') + .orderBy( + qb() + .select() + .from('persons as p') + .whereColumn('persons.id', 'p.id') + .select('p.id') + ), + { + mysql: { + sql: + 'select * from `persons` order by (select `p`.`id` from `persons` as `p` where `persons`.`id` = `p`.`id`) asc', + bindings: [], + }, + mssql: { + sql: + 'select * from [persons] order by (select [p].[id] from [persons] as [p] where [persons].[id] = [p].[id]) asc', + bindings: [], + }, + pg: { + sql: + 'select * from "persons" order by (select "p"."id" from "persons" as "p" where "persons"."id" = "p"."id") asc', + bindings: [], + }, + sqlite3: { + sql: + 'select * from `persons` order by (select `p`.`id` from `persons` as `p` where `persons`.`id` = `p`.`id`) asc', + bindings: [], + }, + } + ); + }); + it('raw group bys', () => { testsql( qb() From 696274c5f4addde6c097da8ee1140f21115f853e Mon Sep 17 00:00:00 2001 From: Ethan Hur Date: Thu, 24 Oct 2019 21:12:45 +0900 Subject: [PATCH 2/3] add orderBy types --- types/index.d.ts | 3 +++ types/test.ts | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/types/index.d.ts b/types/index.d.ts index bcabbbf7bc..8b512faf27 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1197,6 +1197,9 @@ declare namespace Knex { ( columnDefs: Array ): QueryBuilder; + ( + subQueryBuilder: QueryBuilder + ): QueryBuilder; } interface Intersect { diff --git a/types/test.ts b/types/test.ts index 024fea4f00..b981813b44 100644 --- a/types/test.ts +++ b/types/test.ts @@ -492,6 +492,17 @@ const main = async () => { .orderBy('name', 'desc') .havingRaw('age > ?', [10]); + // $ExpectType User[] + await knex('users') + .select() + .from('persons') + .orderBy( + knex('users') + .select('u.id') + .from('users as u') + .where('users.id', 'u.id') + ); + // $ExpectType Dict[] await knex('users').count(); From 2fa6291c4d0c8a566f337ab8ac1a72e2e296e8c3 Mon Sep 17 00:00:00 2001 From: Ethan Hur Date: Thu, 24 Oct 2019 21:15:30 +0900 Subject: [PATCH 3/3] fix typo --- types/test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/types/test.ts b/types/test.ts index b981813b44..44fe5aa366 100644 --- a/types/test.ts +++ b/types/test.ts @@ -495,7 +495,6 @@ const main = async () => { // $ExpectType User[] await knex('users') .select() - .from('persons') .orderBy( knex('users') .select('u.id')