From 71fa1e5c883326ca90d94061b6509c02f7c42304 Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Mon, 12 Apr 2021 19:15:53 -0300 Subject: [PATCH] Creating .fromRaw api & its tests --- lib/query/method-constants.js | 1 + lib/query/querybuilder.js | 11 ++++++++ test/unit/query/builder.js | 48 +++++++++++++++++++++++++++++++++++ types/index.d.ts | 1 + 4 files changed, 61 insertions(+) diff --git a/lib/query/method-constants.js b/lib/query/method-constants.js index 2b939d5b3e..1a75295ad2 100644 --- a/lib/query/method-constants.js +++ b/lib/query/method-constants.js @@ -8,6 +8,7 @@ module.exports = [ 'columns', 'column', 'from', + 'fromRaw', 'fromJS', 'into', 'withSchema', diff --git a/lib/query/querybuilder.js b/lib/query/querybuilder.js index 70fceb6737..9b46266a85 100644 --- a/lib/query/querybuilder.js +++ b/lib/query/querybuilder.js @@ -203,6 +203,17 @@ class Builder extends EventEmitter { return this; } + fromRaw(sql, bindings) { + //Verify if is rawInstance + const raw = sql.isRawInstance ? sql : this.client.raw(sql, bindings); + + //Add wrapper to fromRaw function + const wrappedRaw = raw.wrap('(', ')'); + + this._single.table = wrappedRaw; + return this; + } + // Adds a `distinct` clause to the query. distinct(...args) { this._statements.push({ diff --git a/test/unit/query/builder.js b/test/unit/query/builder.js index ccc902b0da..0d28f0388d 100644 --- a/test/unit/query/builder.js +++ b/test/unit/query/builder.js @@ -835,6 +835,54 @@ describe('QueryBuilder', () => { ); }); + it('uses fromRaw api, #1767', () => { + testsql(qb().select('*').fromRaw('select * from users where age > 18'), { + mysql: 'select * from (select * from users where age > 18)', + mssql: 'select * from (select * from users where age > 18)', + pg: 'select * from (select * from users where age > 18)', + 'pg-redshift': 'select * from (select * from users where age > 18)', + }); + }); + + it('uses fromRaw api with a query function, #1767', () => { + const subquery = qb() + .select(raw('? as f', ['inner raw select'])) + .as('g'); + testsql( + qb() + .select(raw('?', ['outer raw select']), 'g.f') + .from(subquery) + .where('g.secret', 123), + { + mysql: { + sql: + 'select ?, `g`.`f` from (select ? as f) as `g` where `g`.`secret` = ?', + bindings: ['outer raw select', 'inner raw select', 123], + }, + mssql: { + sql: + 'select ?, [g].[f] from (select ? as f) as [g] where [g].[secret] = ?', + bindings: ['outer raw select', 'inner raw select', 123], + }, + oracledb: { + sql: + 'select ?, "g"."f" from (select ? as f) "g" where "g"."secret" = ?', + bindings: ['outer raw select', 'inner raw select', 123], + }, + pg: { + sql: + 'select ?, "g"."f" from (select ? as f) as "g" where "g"."secret" = ?', + bindings: ['outer raw select', 'inner raw select', 123], + }, + 'pg-redshift': { + sql: + 'select ?, "g"."f" from (select ? as f) as "g" where "g"."secret" = ?', + bindings: ['outer raw select', 'inner raw select', 123], + }, + } + ); + }); + it('basic wheres', () => { testsql(qb().select('*').from('users').where('id', '=', 1), { mysql: { diff --git a/types/index.d.ts b/types/index.d.ts index 1be18138fa..72b0979cc7 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -496,6 +496,7 @@ export declare namespace Knex { column: Select; hintComment: HintComment; from: Table; + fromRaw: Table; into: Table; table: Table; distinct: Distinct;