fix(Postgres Node): Arrays in query replacement fix (#6718)

This commit is contained in:
Michael Kret 2023-07-25 15:34:45 +03:00 committed by GitHub
parent ed09e9c695
commit 4cae091cfb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 30 deletions

View file

@ -1,4 +1,10 @@
import type { IDataObject, IExecuteFunctions, IGetNodeParameterOptions, INode } from 'n8n-workflow'; import type {
IDataObject,
IExecuteFunctions,
IGetNodeParameterOptions,
INode,
INodeParameters,
} from 'n8n-workflow';
import type { ColumnInfo, PgpDatabase, QueriesRunner } from '../../v2/helpers/interfaces'; import type { ColumnInfo, PgpDatabase, QueriesRunner } from '../../v2/helpers/interfaces';
@ -38,6 +44,7 @@ const createMockExecuteFunction = (nodeParameters: IDataObject) => {
return get(nodeParameters, parameter, fallbackValue); return get(nodeParameters, parameter, fallbackValue);
}, },
getNode() { getNode() {
node.parameters = { ...node.parameters, ...(nodeParameters as INodeParameters) };
return node; return node;
}, },
} as unknown as IExecuteFunctions; } as unknown as IExecuteFunctions;
@ -252,9 +259,9 @@ describe('Test PostgresV2, insert operation', () => {
options: {}, options: {},
}; };
const columnsInfo: ColumnInfo[] = [ const columnsInfo: ColumnInfo[] = [
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO' }, { column_name: 'id', data_type: 'integer', is_nullable: 'NO', udt_name: '' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO' }, { column_name: 'json', data_type: 'json', is_nullable: 'NO', udt_name: '' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO' }, { column_name: 'foo', data_type: 'text', is_nullable: 'NO', udt_name: '' },
]; ];
const nodeOptions = nodeParameters.options as IDataObject; const nodeOptions = nodeParameters.options as IDataObject;
@ -295,9 +302,9 @@ describe('Test PostgresV2, insert operation', () => {
options: {}, options: {},
}; };
const columnsInfo: ColumnInfo[] = [ const columnsInfo: ColumnInfo[] = [
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO' }, { column_name: 'id', data_type: 'integer', is_nullable: 'NO', udt_name: '' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO' }, { column_name: 'json', data_type: 'json', is_nullable: 'NO', udt_name: '' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO' }, { column_name: 'foo', data_type: 'text', is_nullable: 'NO', udt_name: '' },
]; ];
const inputItems = [ const inputItems = [
@ -505,9 +512,9 @@ describe('Test PostgresV2, update operation', () => {
}, },
}; };
const columnsInfo: ColumnInfo[] = [ const columnsInfo: ColumnInfo[] = [
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO' }, { column_name: 'id', data_type: 'integer', is_nullable: 'NO', udt_name: '' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO' }, { column_name: 'json', data_type: 'json', is_nullable: 'NO', udt_name: '' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO' }, { column_name: 'foo', data_type: 'text', is_nullable: 'NO', udt_name: '' },
]; ];
const nodeOptions = nodeParameters.options as IDataObject; const nodeOptions = nodeParameters.options as IDataObject;
@ -561,9 +568,9 @@ describe('Test PostgresV2, update operation', () => {
options: {}, options: {},
}; };
const columnsInfo: ColumnInfo[] = [ const columnsInfo: ColumnInfo[] = [
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO' }, { column_name: 'id', data_type: 'integer', is_nullable: 'NO', udt_name: '' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO' }, { column_name: 'json', data_type: 'json', is_nullable: 'NO', udt_name: '' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO' }, { column_name: 'foo', data_type: 'text', is_nullable: 'NO', udt_name: '' },
]; ];
const inputItems = [ const inputItems = [
@ -664,9 +671,9 @@ describe('Test PostgresV2, upsert operation', () => {
}, },
}; };
const columnsInfo: ColumnInfo[] = [ const columnsInfo: ColumnInfo[] = [
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO' }, { column_name: 'id', data_type: 'integer', is_nullable: 'NO', udt_name: '' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO' }, { column_name: 'json', data_type: 'json', is_nullable: 'NO', udt_name: '' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO' }, { column_name: 'foo', data_type: 'text', is_nullable: 'NO', udt_name: '' },
]; ];
const nodeOptions = nodeParameters.options as IDataObject; const nodeOptions = nodeParameters.options as IDataObject;
@ -720,9 +727,9 @@ describe('Test PostgresV2, upsert operation', () => {
options: {}, options: {},
}; };
const columnsInfo: ColumnInfo[] = [ const columnsInfo: ColumnInfo[] = [
{ column_name: 'id', data_type: 'integer', is_nullable: 'NO' }, { column_name: 'id', data_type: 'integer', is_nullable: 'NO', udt_name: '' },
{ column_name: 'json', data_type: 'json', is_nullable: 'NO' }, { column_name: 'json', data_type: 'json', is_nullable: 'NO', udt_name: '' },
{ column_name: 'foo', data_type: 'text', is_nullable: 'NO' }, { column_name: 'foo', data_type: 'text', is_nullable: 'NO', udt_name: '' },
]; ];
const inputItems = [ const inputItems = [

View file

@ -61,22 +61,44 @@ export async function execute(
query = query.replace(resolvable, this.evaluateExpression(resolvable, i) as string); query = query.replace(resolvable, this.evaluateExpression(resolvable, i) as string);
} }
let values: IDataObject[] = []; let values: Array<IDataObject | string> = [];
let queryReplacement = this.getNodeParameter('options.queryReplacement', i, ''); const queryReplacement = this.getNodeParameter('options.queryReplacement', i, '');
if (typeof queryReplacement === 'string') { if (typeof queryReplacement === 'string') {
queryReplacement = queryReplacement.split(',').map((entry) => entry.trim()); const node = this.getNode();
}
if (Array.isArray(queryReplacement)) { const rawReplacements = (node.parameters.options as IDataObject)?.queryReplacement as string;
values = queryReplacement as IDataObject[];
if (rawReplacements) {
const rawValues = rawReplacements
.replace(/^=+/, '')
.split(',')
.filter((entry) => entry)
.map((entry) => entry.trim());
for (const rawValue of rawValues) {
const resolvables = getResolvables(rawValue);
if (resolvables.length) {
for (const resolvable of resolvables) {
values.push(this.evaluateExpression(`${resolvable}`, i) as IDataObject);
}
} else {
values.push(rawValue);
}
}
}
} else { } else {
throw new NodeOperationError( if (Array.isArray(queryReplacement)) {
this.getNode(), values = queryReplacement as IDataObject[];
'Query Replacement must be a string of comma-separated values, or an array of values', } else {
{ itemIndex: i }, throw new NodeOperationError(
); this.getNode(),
'Query Parameters must be a string of comma-separated values or an array of values',
{ itemIndex: i },
);
}
} }
queries.push({ query, values }); queries.push({ query, values });