From 443c76bd9c1686f5d61a57173032b0e4088d5462 Mon Sep 17 00:00:00 2001 From: Ryan Kotzen Date: Tue, 14 Jan 2025 16:30:24 +0200 Subject: [PATCH 1/3] adding extra logging when pipeline.findLastIndex is not a function --- lib/make/makeAggregatePipeline.js | 21 ++- test/bug-fix-tests/bug-fix.json | 31 +--- test/bug-fix-tests/bug-fix.test.js | 261 +++++++++++++++++++++++++---- 3 files changed, 249 insertions(+), 64 deletions(-) diff --git a/lib/make/makeAggregatePipeline.js b/lib/make/makeAggregatePipeline.js index 5d5188d..d9749b2 100644 --- a/lib/make/makeAggregatePipeline.js +++ b/lib/make/makeAggregatePipeline.js @@ -20,6 +20,7 @@ const $json = require('@synatic/json-magic'); const projectIsSimple = require('../projectIsSimple'); const lodash = require('lodash'); const projectIsRoot = require('../projectIsRoot'); +const $check = require('check-types'); exports.makeAggregatePipeline = makeAggregatePipeline; exports.stripJoinHints = stripJoinHints; @@ -264,12 +265,18 @@ function makeAggregatePipeline(ast, context = {}) { $json.set(preprocessedWhere, subQueryQuery.path + '$expr', { $eq: [{$size: `$${tempTableField}`}, 0], }); - $json.remove(preprocessedWhere, subQueryQuery.path + '$$$SubQuery$$$'); + $json.remove( + preprocessedWhere, + subQueryQuery.path + '$$$SubQuery$$$' + ); } else if (subQueryQuery.operator === 'IN') { $json.set(preprocessedWhere, subQueryQuery.path + '$expr', { $gt: [{$size: `$${tempTableField}`}, 0], }); - $json.remove(preprocessedWhere, subQueryQuery.path + '$$$SubQuery$$$'); + $json.remove( + preprocessedWhere, + subQueryQuery.path + '$$$SubQuery$$$' + ); } else { throw new Error( `Sub query operations not supported: ${subQueryQuery.operator}` @@ -569,6 +576,16 @@ function makeAggregatePipeline(ast, context = {}) { } // check if sortKeys exists, otherwise insert the source before the last project + if ( + !pipeline.findLastIndex || + !$check.function(pipeline.findLastIndex) + ) { + console.log( + `findLastIndex was not a function, typeof pipeline: ${typeof pipeline}, ${pipeline}, ${JSON.stringify( + pipeline + )}` + ); + } const previousProjectIndex = pipeline.findLastIndex( (p) => !!p.$project ); diff --git a/test/bug-fix-tests/bug-fix.json b/test/bug-fix-tests/bug-fix.json index a6565bd..e0ca5ec 100644 --- a/test/bug-fix-tests/bug-fix.json +++ b/test/bug-fix-tests/bug-fix.json @@ -1277,33 +1277,10 @@ "nested-case": { "case-1": {}, "case-2": { - "expectedResults": [ - { - "id": 1, - "item": "almonds", - "category": "nut" - }, - { - "id": 2, - "item": "pecans", - "category": "nut" - }, - { - "id": 3, - "item": "almonds", - "category": "nut" - }, - { - "id": 4, - "item": "almonds", - "category": "nut" - }, - { - "id": 5, - "item": "potatoes", - "category": "starch" - } - ] + "expectedResults": [] } + }, + "sort-after-project": { + "case-1": {} } } \ No newline at end of file diff --git a/test/bug-fix-tests/bug-fix.test.js b/test/bug-fix-tests/bug-fix.test.js index e068a9b..222879f 100644 --- a/test/bug-fix-tests/bug-fix.test.js +++ b/test/bug-fix-tests/bug-fix.test.js @@ -2342,34 +2342,30 @@ describe('bug-fixes', function () { { pipeline: [ { - "$project": { - "u": "$$ROOT" - } + $project: { + u: '$$ROOT', + }, }, { - "$project": { - "full_name": { - "$toLower": "$u.name" + $project: { + full_name: { + $toLower: '$u.name', }, - "u.first_name": 1 - } + 'u.first_name': 1, + }, }, { - "$sort": { - "full_name": 1, - "u.first_name": 1 - } + $sort: { + full_name: 1, + 'u.first_name': 1, + }, }, { - "$unset": [ - "u.first_name" - ] + $unset: ['u.first_name'], }, { - "$unset": [ - "u" - ] - } + $unset: ['u'], + }, ], collections: ['users'], type: 'aggregate', @@ -2391,29 +2387,27 @@ describe('bug-fixes', function () { { pipeline: [ { - "$project": { - "u": "$$ROOT" - } + $project: { + u: '$$ROOT', + }, }, { - "$project": { - "u.full_name": { - "$toLower": "$u.name" + $project: { + 'u.full_name': { + $toLower: '$u.name', }, - "u.first_name": 1 - } + 'u.first_name': 1, + }, }, { - "$sort": { - "u.full_name": 1, - "u.first_name": 1 - } + $sort: { + 'u.full_name': 1, + 'u.first_name': 1, + }, }, { - "$unset": [ - "u.first_name" - ] - } + $unset: ['u.first_name'], + }, ], collections: ['users'], type: 'aggregate', @@ -3062,5 +3056,202 @@ describe('bug-fixes', function () { 'Invalid sort order' ); }); + + it('should successfully call findLastIndex if pipeline is empty', async () => { + const sql = ` + select records as \`$$ROOT\` +from (select RecordId, + AncestorInstanceId, + AncestorRecordId, + AncestorRecordNumber, + ChecklistStatusId, + CurrentDv, + InsertDv, + InstanceId, + IsInUseByOtherRecords, + ModuleId, + ProcessFlowId, + RecordNumber, + RecordStatus, + SQ, + CreatedByUserId, + LatestModifiedByUserId, + DeletedByUserId + from \`global-list-module-records--vbfr-std-glb-module-record\` + where RecordStatus in ('active') + and InstanceId in ('19F881AA-94BA-4F9A-8E04-C37B172AF652' ) + ) as records +where 1=1 +order by CurrentDv asc , SQ asc`; + await queryResultTester({ + queryString: sql, + casePath: 'nested-case.case-2', + mode: 'write', + outputPipeline: false, + skipDbQuery: true, + optimizeJoins: false, + unsetId: true, + schemas: { + // 'global-list-module-records--vbfr-std-glb-module-record': { + // type: 'object', + // properties: { + // _id: { + // type: 'string', + // format: 'mongoid', + // }, + // RecordId: { + // type: 'string', + // stringLength: 36, + // }, + // AncestorInstanceId: { + // type: 'null', + // }, + // AncestorRecordId: { + // type: 'null', + // }, + // AncestorRecordNumber: { + // type: 'null', + // }, + // AuditSQ: { + // type: 'null', + // }, + // ChecklistStatusId: { + // type: ['null', 'string'], + // stringLength: 36, + // }, + // CreatedByUserId: { + // type: 'string', + // stringLength: 36, + // }, + // CurrentDv: { + // type: 'string', + // format: 'date-time', + // }, + // DeletedByUserId: { + // type: 'null', + // }, + // InsertDv: { + // type: 'string', + // format: 'date-time', + // }, + // InstanceId: { + // type: 'string', + // stringLength: 36, + // }, + // IsInUseByOtherRecords: { + // type: 'integer', + // }, + // LatestModifiedByUserId: { + // type: 'string', + // stringLength: 36, + // }, + // ModuleId: { + // type: 'string', + // stringLength: 36, + // }, + // ProcessFlowId: { + // type: 'string', + // stringLength: 36, + // }, + // RecordNumber: { + // type: 'integer', + // }, + // RecordStatus: { + // type: 'string', + // stringLength: 6, + // }, + // SQ: { + // type: 'integer', + // }, + // _dateUpdated: { + // type: 'string', + // format: 'date-time', + // }, + // }, + // }, + }, + }); + const aggr = makeMongoAggregate(sql); + assert.deepStrictEqual( + aggr, + { + pipeline: [ + { + $match: { + $and: [ + { + RecordStatus: { + $in: ['active'], + }, + }, + { + InstanceId: { + $in: [ + '19F881AA-94BA-4F9A-8E04-C37B172AF652', + ], + }, + }, + ], + }, + }, + { + $project: { + RecordId: '$RecordId', + AncestorInstanceId: '$AncestorInstanceId', + AncestorRecordId: '$AncestorRecordId', + AncestorRecordNumber: '$AncestorRecordNumber', + ChecklistStatusId: '$ChecklistStatusId', + CurrentDv: '$CurrentDv', + InsertDv: '$InsertDv', + InstanceId: '$InstanceId', + IsInUseByOtherRecords: '$IsInUseByOtherRecords', + ModuleId: '$ModuleId', + ProcessFlowId: '$ProcessFlowId', + RecordNumber: '$RecordNumber', + RecordStatus: '$RecordStatus', + SQ: '$SQ', + CreatedByUserId: '$CreatedByUserId', + LatestModifiedByUserId: + '$LatestModifiedByUserId', + DeletedByUserId: '$DeletedByUserId', + }, + }, + { + $match: { + $expr: { + $eq: [1, 1], + }, + }, + }, + { + $replaceRoot: { + newRoot: '$records', + }, + }, + { + $project: { + records: '$$ROOT', + CurrentDv: 1, + SQ: 1, + }, + }, + { + $sort: { + CurrentDv: 1, + SQ: 1, + }, + }, + { + $unset: ['CurrentDv', 'SQ'], + }, + ], + collections: [ + 'global-list-module-records--vbfr-std-glb-module-record', + ], + type: 'aggregate', + }, + 'Invalid sort order' + ); + }); }); }); From aa3a061b27e0530a6989dc03369fb97c8b2beb45 Mon Sep 17 00:00:00 2001 From: Ryan Kotzen Date: Tue, 14 Jan 2025 16:30:34 +0200 Subject: [PATCH 2/3] 4.2.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b749522..8cd3adc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@synatic/noql", - "version": "4.2.2", + "version": "4.2.3", "description": "Convert SQL statements to mongo queries or aggregates", "main": "index.js", "files": [ From 5a0242edf2be3398c53fb8aa99fdb71d8bbd7225 Mon Sep 17 00:00:00 2001 From: Ryan Kotzen Date: Tue, 14 Jan 2025 16:35:29 +0200 Subject: [PATCH 3/3] fixing linting error --- lib/make/makeAggregatePipeline.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/make/makeAggregatePipeline.js b/lib/make/makeAggregatePipeline.js index d9749b2..0a4ea2f 100644 --- a/lib/make/makeAggregatePipeline.js +++ b/lib/make/makeAggregatePipeline.js @@ -19,8 +19,7 @@ const { const $json = require('@synatic/json-magic'); const projectIsSimple = require('../projectIsSimple'); const lodash = require('lodash'); -const projectIsRoot = require('../projectIsRoot'); -const $check = require('check-types'); +const projectIsRoot = require('../projectIsRoot'); exports.makeAggregatePipeline = makeAggregatePipeline; exports.stripJoinHints = stripJoinHints;