From a29cd6e05fa3d021c19edbdf422d260a793ff73c Mon Sep 17 00:00:00 2001 From: Pranav C Date: Sat, 23 Dec 2023 08:12:11 +0000 Subject: [PATCH 1/3] fix: repeat method argument validation --- packages/nocodb-sdk/src/lib/formulaHelpers.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/nocodb-sdk/src/lib/formulaHelpers.ts b/packages/nocodb-sdk/src/lib/formulaHelpers.ts index cda0be6a04..b92a15e302 100644 --- a/packages/nocodb-sdk/src/lib/formulaHelpers.ts +++ b/packages/nocodb-sdk/src/lib/formulaHelpers.ts @@ -712,8 +712,18 @@ export const formulas: Record = { validation: { args: { rqd: 2, - - type: FormulaDataTypes.STRING, + }, + custom(argTypes: FormulaDataTypes[], parsedTree) { + if (argTypes[1] !== FormulaDataTypes.NUMERIC) { + throw new FormulaError( + FormulaErrorType.INVALID_ARG, + { + key: 'msg.formula.numericTypeIsExpected', + calleeName: parsedTree.callee?.name?.toUpperCase(), + }, + 'Numeric type is expected' + ); + } }, }, description: From 9c6bb95ce7172da2eab2c841ad6de33fe693b57f Mon Sep 17 00:00:00 2001 From: Pranav C Date: Sat, 23 Dec 2023 08:12:11 +0000 Subject: [PATCH 2/3] fix: add support to negative numbers(- unary operator) --- packages/nocodb-sdk/src/lib/formulaHelpers.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/nocodb-sdk/src/lib/formulaHelpers.ts b/packages/nocodb-sdk/src/lib/formulaHelpers.ts index b92a15e302..97cd9f70e0 100644 --- a/packages/nocodb-sdk/src/lib/formulaHelpers.ts +++ b/packages/nocodb-sdk/src/lib/formulaHelpers.ts @@ -1777,11 +1777,14 @@ export async function validateFormulaAndExtractTreeWithType({ res.dataType = FormulaDataTypes.STRING; } } else if (parsedTree.type === JSEPNode.UNARY_EXP) { - throw new FormulaError( - FormulaErrorType.NOT_SUPPORTED, - {}, - 'Unary expression is not supported' - ); + // only support unary +/- + if (!['-', '+'].includes(parsedTree.operator)) { + throw new FormulaError( + FormulaErrorType.NOT_SUPPORTED, + {}, + `Unary expression '${parsedTree.operator}' is not supported` + ); + } } else if (parsedTree.type === JSEPNode.BINARY_EXP) { res.left = await validateAndExtract(parsedTree.left); res.right = await validateAndExtract(parsedTree.right); From 702051fceda20091c1c7fa215735184554e5d5f9 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Sat, 23 Dec 2023 08:12:11 +0000 Subject: [PATCH 3/3] fix: handle negative values properly --- packages/nocodb-sdk/src/lib/formulaHelpers.ts | 10 +++++++-- .../src/db/formulav2/formulaQueryBuilderv2.ts | 21 ++++++++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/packages/nocodb-sdk/src/lib/formulaHelpers.ts b/packages/nocodb-sdk/src/lib/formulaHelpers.ts index 97cd9f70e0..89689677d0 100644 --- a/packages/nocodb-sdk/src/lib/formulaHelpers.ts +++ b/packages/nocodb-sdk/src/lib/formulaHelpers.ts @@ -1777,8 +1777,14 @@ export async function validateFormulaAndExtractTreeWithType({ res.dataType = FormulaDataTypes.STRING; } } else if (parsedTree.type === JSEPNode.UNARY_EXP) { - // only support unary +/- - if (!['-', '+'].includes(parsedTree.operator)) { + // only support -ve values + if ( + ['-'].includes(parsedTree.operator) && + parsedTree.argument.type === JSEPNode.LITERAL && + typeof parsedTree.argument.value === 'number' + ) { + res.dataType = FormulaDataTypes.NUMERIC; + } else { throw new FormulaError( FormulaErrorType.NOT_SUPPORTED, {}, diff --git a/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts b/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts index 101c4b6161..e36ed59f2c 100644 --- a/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts +++ b/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts @@ -1027,11 +1027,22 @@ async function _formulaQueryBuilder( } return { builder: query }; } else if (pt.type === 'UnaryExpression') { - const query = knex.raw( - `${pt.operator}${( - await fn(pt.argument, null, pt.operator) - ).builder.toQuery()}${colAlias}`, - ); + let query; + if ( + (pt.operator === '-' || pt.operator === '+') && + pt.dataType === FormulaDataTypes.NUMERIC + ) { + query = knex.raw('?', [ + (pt.operator === '-' ? -1 : 1) * pt.argument.value, + ]); + } else { + query = knex.raw( + `${pt.operator}${( + await fn(pt.argument, null, pt.operator) + ).builder.toQuery()}${colAlias}`, + ); + } + if (prevBinaryOp && pt.operator !== prevBinaryOp) { query.wrap('(', ')'); }