Skip to content

Commit

Permalink
fix(MySQL Node): Query to statements splitting fix (#9207)
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-radency authored Apr 25, 2024
1 parent 093dcef commit dc84452
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 8 deletions.
3 changes: 2 additions & 1 deletion packages/nodes-base/nodes/MySql/MySql.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class MySql extends VersionedNodeType {
name: 'mySql',
icon: 'file:mysql.svg',
group: ['input'],
defaultVersion: 2.3,
defaultVersion: 2.4,
description: 'Get, add and update data in MySQL',
parameterPane: 'wide',
};
Expand All @@ -22,6 +22,7 @@ export class MySql extends VersionedNodeType {
2.1: new MySqlV2(baseDescription),
2.2: new MySqlV2(baseDescription),
2.3: new MySqlV2(baseDescription),
2.4: new MySqlV2(baseDescription),
};

super(nodeVersions, baseDescription);
Expand Down
27 changes: 27 additions & 0 deletions packages/nodes-base/nodes/MySql/test/v2/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
addSortRules,
replaceEmptyStringsByNulls,
escapeSqlIdentifier,
splitQueryToStatements,
} from '../../v2/helpers/utils';

const mySqlMockNode: INode = {
Expand Down Expand Up @@ -175,3 +176,29 @@ describe('Test MySql V2, escapeSqlIdentifier', () => {
expect(escapedIdentifier).toEqual('`db_name`.`some.dotted.tbl_name`');
});
});

describe('Test MySql V2, splitQueryToStatements', () => {
it('should split query into statements', () => {
const query =
"insert into models (`created_at`, custom_ship_time, id) values ('2023-09-07 10:26:20', 'some random; data with a semicolon', 1); insert into models (`created_at`, custom_ship_time, id) values ('2023-09-07 10:27:55', 'random data without semicolon\n', 2);";

const statements = splitQueryToStatements(query);

expect(statements).toBeDefined();
expect(statements).toEqual([
"insert into models (`created_at`, custom_ship_time, id) values ('2023-09-07 10:26:20', 'some random; data with a semicolon', 1)",
"insert into models (`created_at`, custom_ship_time, id) values ('2023-09-07 10:27:55', 'random data without semicolon', 2)",
]);
});
it('should not split by ; inside string literal', () => {
const query =
"SELECT custom_ship_time FROM models WHERE models.custom_ship_time LIKE CONCAT('%', ';', '%') LIMIT 10";

const statements = splitQueryToStatements(query);

expect(statements).toBeDefined();
expect(statements).toEqual([
"SELECT custom_ship_time FROM models WHERE models.custom_ship_time LIKE CONCAT('%', ';', '%') LIMIT 10",
]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const versionDescription: INodeTypeDescription = {
name: 'mySql',
icon: 'file:mysql.svg',
group: ['input'],
version: [2, 2.1, 2.2, 2.3],
version: [2, 2.1, 2.2, 2.3, 2.4],
subtitle: '={{ $parameter["operation"] }}',
description: 'Get, add and update data in MySQL',
defaults: {
Expand Down
37 changes: 31 additions & 6 deletions packages/nodes-base/nodes/MySql/v2/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,14 @@ export function prepareOutput(

return returnData;
}
const END_OF_STATEMENT = /;(?=(?:[^'\\]|'[^']*?'|\\[\s\S])*?$)/g;
export const splitQueryToStatements = (query: string, filterOutEmpty = true) => {
const statements = query
.replace(/\n/g, '')
.split(END_OF_STATEMENT)
.map((statement) => statement.trim());
return filterOutEmpty ? statements.filter((statement) => statement !== '') : statements;
};

export function configureQueryRunner(
this: IExecuteFunctions,
Expand Down Expand Up @@ -225,10 +233,15 @@ export function configureQueryRunner(

if (!response) return [];

const statements = singleQuery
.replace(/\n/g, '')
.split(';')
.filter((statement) => statement !== '');
let statements;
if ((options?.nodeVersion as number) <= 2.3) {
statements = singleQuery
.replace(/\n/g, '')
.split(';')
.filter((statement) => statement !== '');
} else {
statements = splitQueryToStatements(singleQuery);
}

if (Array.isArray(response)) {
if (statements.length === 1) response = [response];
Expand Down Expand Up @@ -261,7 +274,13 @@ export function configureQueryRunner(
try {
const { query, values } = queryWithValues;
formatedQuery = connection.format(query, values);
const statements = formatedQuery.split(';').map((q) => q.trim());

let statements;
if ((options?.nodeVersion as number) <= 2.3) {
statements = formatedQuery.split(';').map((q) => q.trim());
} else {
statements = splitQueryToStatements(formatedQuery, false);
}

const responses: IDataObject[] = [];
for (const statement of statements) {
Expand Down Expand Up @@ -300,7 +319,13 @@ export function configureQueryRunner(
try {
const { query, values } = queryWithValues;
formatedQuery = connection.format(query, values);
const statements = formatedQuery.split(';').map((q) => q.trim());

let statements;
if ((options?.nodeVersion as number) <= 2.3) {
statements = formatedQuery.split(';').map((q) => q.trim());
} else {
statements = splitQueryToStatements(formatedQuery, false);
}

const responses: IDataObject[] = [];
for (const statement of statements) {
Expand Down

0 comments on commit dc84452

Please sign in to comment.