From 7d51406656327db65e4862fc1c63b824b4004243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8D=BB=E5=8D=87?= <63136897+ongdisheng@users.noreply.github.com> Date: Thu, 5 Feb 2026 09:10:38 +0000 Subject: [PATCH] fix(Postgres Node): Enable non-numeric comparisons for WHERE clause operators (#18544) --- .../nodes/Postgres/test/v2/utils.test.ts | 110 ++++++++++++++++++ .../nodes/Postgres/v2/helpers/utils.ts | 21 +--- 2 files changed, 115 insertions(+), 16 deletions(-) diff --git a/packages/nodes-base/nodes/Postgres/test/v2/utils.test.ts b/packages/nodes-base/nodes/Postgres/test/v2/utils.test.ts index 64505aa46c0..47933473e4d 100644 --- a/packages/nodes-base/nodes/Postgres/test/v2/utils.test.ts +++ b/packages/nodes-base/nodes/Postgres/test/v2/utils.test.ts @@ -217,6 +217,116 @@ describe('Test PostgresV2, addWhereClauses', () => { ); expect(updatedValues).toEqual(['public', 'my_table', 'id', '1', 'foo', 'select 2']); }); + + it('should handle numeric comparison operators', () => { + const query = 'SELECT * FROM $1:name.$2:name'; + const values = ['public', 'my_table']; + const whereClauses = [ + { column: 'age', condition: '>', value: '25' }, + { column: 'salary', condition: '>=', value: '50000' }, + ]; + + const [updatedQuery, updatedValues] = addWhereClauses( + node, + 0, + query, + whereClauses, + values, + 'AND', + ); + + expect(updatedQuery).toEqual( + 'SELECT * FROM $1:name.$2:name WHERE $3:name > $4 AND $5:name >= $6', + ); + // Values should be converted to numbers + expect(updatedValues).toEqual(['public', 'my_table', 'age', 25, 'salary', 50000]); + }); + + it('should handle date comparison operators', () => { + const query = 'SELECT * FROM $1:name.$2:name'; + const values = ['public', 'my_table']; + const whereClauses = [ + { column: 'created_at', condition: '>=', value: '2025-04-28T00:00:00.000Z' }, + { column: 'updated_at', condition: '<', value: '2025-05-01' }, + ]; + + const [updatedQuery, updatedValues] = addWhereClauses( + node, + 0, + query, + whereClauses, + values, + 'AND', + ); + + expect(updatedQuery).toEqual( + 'SELECT * FROM $1:name.$2:name WHERE $3:name >= $4 AND $5:name < $6', + ); + // Date strings should remain as strings + expect(updatedValues).toEqual([ + 'public', + 'my_table', + 'created_at', + '2025-04-28T00:00:00.000Z', + 'updated_at', + '2025-05-01', + ]); + }); + + it('should handle string comparison operators', () => { + const query = 'SELECT * FROM $1:name.$2:name'; + const values = ['public', 'my_table']; + const whereClauses = [ + { column: 'name', condition: '>', value: 'M' }, + { column: 'category', condition: '<=', value: 'Electronics' }, + ]; + + const [updatedQuery, updatedValues] = addWhereClauses( + node, + 0, + query, + whereClauses, + values, + 'AND', + ); + + expect(updatedQuery).toEqual( + 'SELECT * FROM $1:name.$2:name WHERE $3:name > $4 AND $5:name <= $6', + ); + // Text strings should remain as strings + expect(updatedValues).toEqual(['public', 'my_table', 'name', 'M', 'category', 'Electronics']); + }); + + it('should not convert empty strings or whitespace-only strings to numbers', () => { + const query = 'SELECT * FROM $1:name.$2:name'; + const values = ['public', 'my_table']; + const whereClauses = [ + { column: 'empty_field', condition: '>', value: '' }, + { column: 'whitespace_field', condition: '>=', value: ' ' }, + ]; + + const [updatedQuery, updatedValues] = addWhereClauses( + node, + 0, + query, + whereClauses, + values, + 'AND', + ); + + expect(updatedQuery).toEqual( + 'SELECT * FROM $1:name.$2:name WHERE $3:name > $4 AND $5:name >= $6', + ); + // These should NOT be converted to numbers + expect(updatedValues).toEqual([ + 'public', + 'my_table', + 'empty_field', + '', + 'whitespace_field', + ' ', + ]); + }); }); describe('Test PostgresV2, addSortRules', () => { diff --git a/packages/nodes-base/nodes/Postgres/v2/helpers/utils.ts b/packages/nodes-base/nodes/Postgres/v2/helpers/utils.ts index a8554ab879c..a3e1abcf11f 100644 --- a/packages/nodes-base/nodes/Postgres/v2/helpers/utils.ts +++ b/packages/nodes-base/nodes/Postgres/v2/helpers/utils.ts @@ -128,8 +128,8 @@ export function parsePostgresError( } export function addWhereClauses( - node: INode, - itemIndex: number, + _node: INode, + _itemIndex: number, query: string, clauses: WhereClause[], replacements: QueryValues, @@ -153,21 +153,10 @@ export function addWhereClauses( clause.condition = '='; } if (['>', '<', '>=', '<='].includes(clause.condition)) { - const value = Number(clause.value); - - if (Number.isNaN(value)) { - throw new NodeOperationError( - node, - `Operator in entry ${index + 1} of 'Select Rows' works with numbers, but value ${ - clause.value - } is not a number`, - { - itemIndex, - }, - ); + const numericValue = Number(clause.value); + if (String(clause.value).trim() !== '' && !Number.isNaN(numericValue)) { + clause.value = numericValue; } - - clause.value = value; } const columnReplacement = `$${replacementIndex}:name`; values.push(clause.column);