Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions lib/make/makeJoinForPipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ function makeJoinPart(join, previousJoin, aliases, pipeline, context, ast) {
pipeline: lookupPipeline,
},
});
if (joinHints && joinHints.length > 0) {

if ((joinHints && joinHints.length > 0) || context.unwindJoins) {
if (joinHints.includes('first')) {
pipeline.push({
$set: {
Expand All @@ -197,7 +198,7 @@ function makeJoinPart(join, previousJoin, aliases, pipeline, context, ast) {
[toAs || toTable]: {$last: `$${toAs || toTable}`},
},
});
} else if (joinHints.includes('unwind')) {
} else if (joinHints.includes('unwind') || context.unwindJoins) {
pipeline.push({
$unwind: {
path: `$${toAs || toTable}`,
Expand Down Expand Up @@ -331,7 +332,7 @@ function tableJoin(
foreignField: foreignField,
},
});
if (joinHints && joinHints.length > 0) {
if ((joinHints && joinHints.length > 0) || context.unwindJoins) {
if (joinHints.includes('first')) {
pipeline.push({
$set: {
Expand All @@ -344,7 +345,7 @@ function tableJoin(
[toAs || toTable]: {$last: `$${toAs || toTable}`},
},
});
} else if (joinHints.includes('unwind')) {
} else if (joinHints.includes('unwind') || context.unwindJoins) {
pipeline.push({
$unwind: {
path: `$${toAs || toTable}`,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@synatic/noql",
"version": "4.1.7",
"version": "4.1.8",
"description": "Convert SQL statements to mongo queries or aggregates",
"main": "index.js",
"files": [
Expand Down
5 changes: 4 additions & 1 deletion test/bug-fix-tests/bug-fix.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ describe('bug-fixes', function () {
await queryResultTester({
queryString: queryString,
casePath: 'bugfix.to_objectid.case1',
unsetId: false,
});
});
});
Expand All @@ -430,6 +431,7 @@ describe('bug-fixes', function () {
await queryResultTester({
queryString: queryString,
casePath: 'bugfix.object_to_array.case1',
unsetId: false,
});
});
});
Expand Down Expand Up @@ -1019,8 +1021,9 @@ describe('bug-fixes', function () {
await queryResultTester({
queryString: queryString,
casePath: 'post-optimization.case1',
mode: 'test',
mode,
outputPipeline: false,
unsetId: false,
});
});
});
Expand Down
25 changes: 25 additions & 0 deletions test/joins/join-cases.json
Original file line number Diff line number Diff line change
Expand Up @@ -1850,5 +1850,30 @@
}
]
}
},
"auto-unwind": {
"left": {
"case1": {
"expectedResults": [
{
"o": {
"id": 1,
"item": "almonds",
"price": 12,
"quantity": 2,
"customerId": 1,
"specialChars": "^^^"
},
"i": {
"id": 1,
"sku": "almonds",
"description": "product 1",
"instock": 120,
"specialChars": "^^^"
}
}
]
}
}
}
}
14 changes: 14 additions & 0 deletions test/joins/joins.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe('joins', function () {
after(function (done) {
disconnect().then(done).catch(done);
});

describe('regression tests', () => {
it('should work for case 1', async () => {
await queryResultTester({
Expand Down Expand Up @@ -674,6 +675,7 @@ describe('joins', function () {
queryString,
casePath: 'optimize.explicit',
mode: 'write',
unsetId: false,
});

assert.deepStrictEqual(pipeline, expectedPipeline);
Expand Down Expand Up @@ -747,4 +749,16 @@ describe('joins', function () {
});
});
});

describe('Automatic Unwinding of joins', () => {
it('should be able to automatically unwind a left join', async () => {
await queryResultTester({
queryString:
'select *, unset(_id,o._id,o.orderDate,i._id) from orders as o left join `inventory` as i on o.item=i.sku limit 1',
casePath: 'auto-unwind.left.case1',
mode,
unwindJoins: true,
});
});
});
});
4 changes: 4 additions & 0 deletions test/utils/query-tester/query-tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,16 @@ async function queryResultTester(options) {
ignoreDateValues = false,
outputPipeline = false,
schemas,
unwindJoins = false,
unsetId = true,
} = options;
if (!fileName.endsWith('.json')) {
fileName = fileName + '.json';
}
const {collections, pipeline} = SQLParser.makeMongoAggregate(queryString, {
schemas,
unwindJoins,
unsetId,
});
const filePath = $path.resolve(dirName, fileName);
/** @type {import("mongodb").Document[]} */
Expand Down
6 changes: 2 additions & 4 deletions test/utils/query-tester/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {MongoClient, Document} from 'mongodb';
import {PipelineFn, Schemas} from '../../../lib/types';
import {PipelineFn, Schemas, ParserOptions} from '../../../lib/types';

/** Options to use when running the function to test/generate test outputs */
export interface BuildQueryResultOptions {
Expand All @@ -13,7 +13,7 @@ export interface BuildQueryResultOptions {
mode?: 'write' | 'test';
}
/** Options to use when running the function to test/generate test outputs */
export interface QueryResultOptions {
export interface QueryResultOptions extends ParserOptions {
/** The query string to run against the db */
queryString: string;
/** The JSON path in the target file at which to store the results */
Expand All @@ -26,8 +26,6 @@ export interface QueryResultOptions {
ignoreDateValues?: boolean;
/** Specifies if the pipeline should be written to the file, useful for debugging */
outputPipeline?: boolean;
/** Specifies a map of schemas the library should use that to produce better queries */
schemas?: Schemas;
}

export type AllQueryResultOptions = BuildQueryResultOptions &
Expand Down
Loading