diff --git a/packages/nodes-base/nodes/MySql/MySql.node.ts b/packages/nodes-base/nodes/MySql/MySql.node.ts index db80bf1ae8..80b8e8ba3d 100644 --- a/packages/nodes-base/nodes/MySql/MySql.node.ts +++ b/packages/nodes-base/nodes/MySql/MySql.node.ts @@ -11,7 +11,7 @@ export class MySql extends VersionedNodeType { name: 'mySql', icon: 'file:mysql.svg', group: ['input'], - defaultVersion: 2.1, + defaultVersion: 2.2, description: 'Get, add and update data in MySQL', }; @@ -19,6 +19,7 @@ export class MySql extends VersionedNodeType { 1: new MySqlV1(baseDescription), 2: new MySqlV2(baseDescription), 2.1: new MySqlV2(baseDescription), + 2.2: new MySqlV2(baseDescription), }; super(nodeVersions, baseDescription); diff --git a/packages/nodes-base/nodes/MySql/test/v2/operations.test.ts b/packages/nodes-base/nodes/MySql/test/v2/operations.test.ts index d79432ac2e..58e011a731 100644 --- a/packages/nodes-base/nodes/MySql/test/v2/operations.test.ts +++ b/packages/nodes-base/nodes/MySql/test/v2/operations.test.ts @@ -305,7 +305,7 @@ describe('Test MySql V2, operations', () => { const runQueries: QueryRunner = configureQueryRunner.call( fakeExecuteFunction, - nodeOptions, + { ...nodeOptions, nodeVersion: 2 }, pool, ); diff --git a/packages/nodes-base/nodes/MySql/test/v2/runQueries.test.ts b/packages/nodes-base/nodes/MySql/test/v2/runQueries.test.ts index 94481afa91..fb3304dbcb 100644 --- a/packages/nodes-base/nodes/MySql/test/v2/runQueries.test.ts +++ b/packages/nodes-base/nodes/MySql/test/v2/runQueries.test.ts @@ -45,7 +45,7 @@ describe('Test MySql V2, runQueries', () => { }); it('should execute in "Single" mode, should return success true', async () => { - const nodeOptions: IDataObject = { queryBatching: BATCH_MODE.SINGLE }; + const nodeOptions: IDataObject = { queryBatching: BATCH_MODE.SINGLE, nodeVersion: 2 }; const pool = createFakePool(fakeConnection); const fakeExecuteFunction = createMockExecuteFunction({}, mySqlMockNode); @@ -81,7 +81,7 @@ describe('Test MySql V2, runQueries', () => { }); it('should execute in "independently" mode, should return success true', async () => { - const nodeOptions: IDataObject = { queryBatching: BATCH_MODE.INDEPENDENTLY }; + const nodeOptions: IDataObject = { queryBatching: BATCH_MODE.INDEPENDENTLY, nodeVersion: 2 }; const pool = createFakePool(fakeConnection); @@ -126,7 +126,7 @@ describe('Test MySql V2, runQueries', () => { }); it('should execute in "transaction" mode, should return success true', async () => { - const nodeOptions: IDataObject = { queryBatching: BATCH_MODE.TRANSACTION }; + const nodeOptions: IDataObject = { queryBatching: BATCH_MODE.TRANSACTION, nodeVersion: 2 }; const pool = createFakePool(fakeConnection); diff --git a/packages/nodes-base/nodes/MySql/v2/actions/versionDescription.ts b/packages/nodes-base/nodes/MySql/v2/actions/versionDescription.ts index 32cd487c7e..366e8fcaa8 100644 --- a/packages/nodes-base/nodes/MySql/v2/actions/versionDescription.ts +++ b/packages/nodes-base/nodes/MySql/v2/actions/versionDescription.ts @@ -8,7 +8,7 @@ export const versionDescription: INodeTypeDescription = { name: 'mySql', icon: 'file:mysql.svg', group: ['input'], - version: [2, 2.1], + version: [2, 2.1, 2.2], subtitle: '={{ $parameter["operation"] }}', description: 'Get, add and update data in MySQL', defaults: { diff --git a/packages/nodes-base/nodes/MySql/v2/helpers/utils.ts b/packages/nodes-base/nodes/MySql/v2/helpers/utils.ts index 7c72e47332..e2b5e5fbde 100644 --- a/packages/nodes-base/nodes/MySql/v2/helpers/utils.ts +++ b/packages/nodes-base/nodes/MySql/v2/helpers/utils.ts @@ -167,7 +167,23 @@ export function prepareOutput( } if (!returnData.length) { - returnData.push({ json: { success: true } }); + if ((options?.nodeVersion as number) < 2.2) { + returnData.push({ json: { success: true } }); + } else { + const isSelectQuery = statements + .filter((statement) => !statement.startsWith('--')) + .every((statement) => + statement + .replace(/\/\*.*?\*\//g, '') // remove multiline comments + .replace(/\n/g, '') + .toLowerCase() + .startsWith('select'), + ); + + if (!isSelectQuery) { + returnData.push({ json: { success: true } }); + } + } } return returnData; diff --git a/packages/nodes-base/nodes/Postgres/Postgres.node.ts b/packages/nodes-base/nodes/Postgres/Postgres.node.ts index d2a06fd890..fae684f450 100644 --- a/packages/nodes-base/nodes/Postgres/Postgres.node.ts +++ b/packages/nodes-base/nodes/Postgres/Postgres.node.ts @@ -11,7 +11,7 @@ export class Postgres extends VersionedNodeType { name: 'postgres', icon: 'file:postgres.svg', group: ['input'], - defaultVersion: 2.2, + defaultVersion: 2.3, description: 'Get, add and update data in Postgres', }; @@ -20,6 +20,7 @@ export class Postgres extends VersionedNodeType { 2: new PostgresV2(baseDescription), 2.1: new PostgresV2(baseDescription), 2.2: new PostgresV2(baseDescription), + 2.3: new PostgresV2(baseDescription), }; super(nodeVersions, baseDescription); diff --git a/packages/nodes-base/nodes/Postgres/test/v2/runQueries.test.ts b/packages/nodes-base/nodes/Postgres/test/v2/runQueries.test.ts index 769569ac57..4297924fe9 100644 --- a/packages/nodes-base/nodes/Postgres/test/v2/runQueries.test.ts +++ b/packages/nodes-base/nodes/Postgres/test/v2/runQueries.test.ts @@ -44,7 +44,9 @@ describe('Test PostgresV2, runQueries', () => { const thisArg = mock(); const runQueries = configureQueryRunner.call(thisArg, node, false, pgp, db); - const result = await runQueries([{ query: 'SELECT * FROM table', values: [] }], [], {}); + const result = await runQueries([{ query: 'SELECT * FROM table', values: [] }], [], { + nodeVersion: 2.2, + }); expect(result).toBeDefined(); expect(result).toHaveLength(1); diff --git a/packages/nodes-base/nodes/Postgres/v2/actions/versionDescription.ts b/packages/nodes-base/nodes/Postgres/v2/actions/versionDescription.ts index dc200de53c..722473f43a 100644 --- a/packages/nodes-base/nodes/Postgres/v2/actions/versionDescription.ts +++ b/packages/nodes-base/nodes/Postgres/v2/actions/versionDescription.ts @@ -8,7 +8,7 @@ export const versionDescription: INodeTypeDescription = { name: 'postgres', icon: 'file:postgres.svg', group: ['input'], - version: [2, 2.1, 2.2], + version: [2, 2.1, 2.2, 2.3], subtitle: '={{ $parameter["operation"] }}', description: 'Get, add and update data in Postgres', defaults: { diff --git a/packages/nodes-base/nodes/Postgres/v2/helpers/utils.ts b/packages/nodes-base/nodes/Postgres/v2/helpers/utils.ts index 86a5cda18e..a800ee044b 100644 --- a/packages/nodes-base/nodes/Postgres/v2/helpers/utils.ts +++ b/packages/nodes-base/nodes/Postgres/v2/helpers/utils.ts @@ -199,6 +199,15 @@ export function addReturning( return [`${query} RETURNING $${replacementIndex}:name`, [...replacements, outputColumns]]; } +const isSelectQuery = (query: string) => { + return query + .replace(/\/\*.*?\*\//g, '') // remove multiline comments + .replace(/\n/g, '') + .split(';') + .filter((statement) => statement && !statement.startsWith('--')) // remove comments and empty statements + .every((statement) => statement.trim().toLowerCase().startsWith('select')); +}; + export function configureQueryRunner( this: IExecuteFunctions, node: INode, @@ -221,7 +230,16 @@ export function configureQueryRunner( }); }) .flat(); - returnData = returnData.length ? returnData : emptyReturnData; + + if (!returnData.length) { + if ((options?.nodeVersion as number) < 2.3) { + returnData = emptyReturnData; + } else { + returnData = queries.every((query) => isSelectQuery(query.query)) + ? [] + : [{ json: { success: true } }]; + } + } } catch (err) { const error = parsePostgresError(node, err, queries); if (!continueOnFail) throw error; @@ -242,13 +260,26 @@ export function configureQueryRunner( const result: INodeExecutionData[] = []; for (let i = 0; i < queries.length; i++) { try { - const transactionResult: IDataObject[] = await transaction.any( - queries[i].query, - queries[i].values, - ); + const query = queries[i].query; + const values = queries[i].values; + + let transactionResults; + if ((options?.nodeVersion as number) < 2.3) { + transactionResults = await transaction.any(query, values); + } else { + transactionResults = (await transaction.multi(query, values)).flat(); + } + + if (!transactionResults.length) { + if ((options?.nodeVersion as number) < 2.3) { + transactionResults = emptyReturnData; + } else { + transactionResults = isSelectQuery(query) ? [] : [{ success: true }]; + } + } const executionData = this.helpers.constructExecutionMetaData( - wrapData(transactionResult.length ? transactionResult : emptyReturnData), + wrapData(transactionResults), { itemData: { item: i } }, ); @@ -265,17 +296,30 @@ export function configureQueryRunner( } if (queryBatching === 'independently') { - returnData = await db.task(async (t) => { + returnData = await db.task(async (task) => { const result: INodeExecutionData[] = []; for (let i = 0; i < queries.length; i++) { try { - const transactionResult: IDataObject[] = await t.any( - queries[i].query, - queries[i].values, - ); + const query = queries[i].query; + const values = queries[i].values; + + let transactionResults; + if ((options?.nodeVersion as number) < 2.3) { + transactionResults = await task.any(query, values); + } else { + transactionResults = (await task.multi(query, values)).flat(); + } + + if (!transactionResults.length) { + if ((options?.nodeVersion as number) < 2.3) { + transactionResults = emptyReturnData; + } else { + transactionResults = isSelectQuery(query) ? [] : [{ success: true }]; + } + } const executionData = this.helpers.constructExecutionMetaData( - wrapData(transactionResult.length ? transactionResult : emptyReturnData), + wrapData(transactionResults), { itemData: { item: i } }, );