From f8660204f0388a394772f4df5c48049b0c64a759 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Mon, 15 Jan 2024 20:51:36 +0000 Subject: [PATCH 1/3] fix: wrap with boolean function if type is boolean to avoid any issue while comparing --- .../nocodb/src/db/formulav2/formulaQueryBuilderv2.ts | 11 +++++++++++ packages/nocodb/src/db/functionMappings/commonFns.ts | 3 +++ packages/nocodb/src/db/functionMappings/pg.ts | 9 +++++++++ 3 files changed, 23 insertions(+) diff --git a/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts b/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts index bbabc72357..739832e412 100644 --- a/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts +++ b/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts @@ -892,6 +892,17 @@ async function _formulaQueryBuilder( if (pt.left.callee?.name !== pt.right.callee?.name) { // if left/right is BLANK, accept both NULL and empty string for (const operand of ['left', 'right']) { + if (pt[operand].type === FormulaDataTypes.BOOLEAN) { + pt[operand] = { + type: 'CallExpression', + arguments: [pt[operand]], + callee: { + type: 'Identifier', + name: 'BOOLEAN', + }, + }; + } + if ( pt[operand].type === 'CallExpression' && pt[operand].callee.name === 'BLANK' diff --git a/packages/nocodb/src/db/functionMappings/commonFns.ts b/packages/nocodb/src/db/functionMappings/commonFns.ts index 376086d65c..3a1c267075 100644 --- a/packages/nocodb/src/db/functionMappings/commonFns.ts +++ b/packages/nocodb/src/db/functionMappings/commonFns.ts @@ -184,6 +184,9 @@ export default { STRING(args: MapFnArgs) { return args.fn(args.pt?.arguments?.[0]); }, + BOOLEAN(args: MapFnArgs) { + return args.fn(args.pt?.arguments?.[0]); + }, AND: async (args: MapFnArgs) => { return { builder: args.knex.raw( diff --git a/packages/nocodb/src/db/functionMappings/pg.ts b/packages/nocodb/src/db/functionMappings/pg.ts index f6fa76b3da..9ee7f2ba9b 100644 --- a/packages/nocodb/src/db/functionMappings/pg.ts +++ b/packages/nocodb/src/db/functionMappings/pg.ts @@ -348,6 +348,15 @@ END ${colAlias}`, ), }; }, + BOOLEAN: async (args: MapFnArgs) => { + return { + builder: args.knex.raw( + `(${(await args.fn(args.pt.arguments[0])).builder})::boolean ${ + args.colAlias + }`, + ), + }; + }, }; export default pg; From fe748106dfdab626ee20be296ffc714f8677b911 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Mon, 15 Jan 2024 20:51:36 +0000 Subject: [PATCH 2/3] fix: wrap with boolean function if type is boolean to avoid any issue while comparing --- packages/nocodb-sdk/src/lib/formulaHelpers.ts | 6 +++- .../src/db/formulav2/formulaQueryBuilderv2.ts | 28 +++++++++++-------- packages/nocodb/src/db/functionMappings/pg.ts | 2 +- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/packages/nocodb-sdk/src/lib/formulaHelpers.ts b/packages/nocodb-sdk/src/lib/formulaHelpers.ts index 89479a121c..b3cc06d364 100644 --- a/packages/nocodb-sdk/src/lib/formulaHelpers.ts +++ b/packages/nocodb-sdk/src/lib/formulaHelpers.ts @@ -1594,7 +1594,11 @@ async function extractColumnIdentifierType({ res.dataType = FormulaDataTypes.STRING; break; case UITypes.Checkbox: - res.dataType = FormulaDataTypes.NUMERIC; + if (col.dt === 'boolean' || col.dt === 'bool') { + res.dataType = FormulaDataTypes.BOOLEAN; + } else { + res.dataType = FormulaDataTypes.NUMERIC; + } break; case UITypes.ID: case UITypes.ForeignKey: diff --git a/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts b/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts index 739832e412..5a1884891a 100644 --- a/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts +++ b/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts @@ -889,20 +889,26 @@ async function _formulaQueryBuilder( // if operator is == or !=, then handle comparison with BLANK which should accept NULL and empty string if (pt.operator === '==' || pt.operator === '!=') { + for (const operand of ['left', 'right']) { + if ( + pt[operand].dataType === FormulaDataTypes.BOOLEAN && + pt[operand === 'left' ? 'right' : 'left'].dataType === + FormulaDataTypes.NUMERIC + ) { + pt[operand === 'left' ? 'right' : 'left'] = { + type: 'CallExpression', + arguments: [pt[operand === 'left' ? 'right' : 'left']], + callee: { + type: 'Identifier', + name: 'BOOLEAN', + }, + dataType: FormulaDataTypes.BOOLEAN, + }; + } + } if (pt.left.callee?.name !== pt.right.callee?.name) { // if left/right is BLANK, accept both NULL and empty string for (const operand of ['left', 'right']) { - if (pt[operand].type === FormulaDataTypes.BOOLEAN) { - pt[operand] = { - type: 'CallExpression', - arguments: [pt[operand]], - callee: { - type: 'Identifier', - name: 'BOOLEAN', - }, - }; - } - if ( pt[operand].type === 'CallExpression' && pt[operand].callee.name === 'BLANK' diff --git a/packages/nocodb/src/db/functionMappings/pg.ts b/packages/nocodb/src/db/functionMappings/pg.ts index 9ee7f2ba9b..5b36f24282 100644 --- a/packages/nocodb/src/db/functionMappings/pg.ts +++ b/packages/nocodb/src/db/functionMappings/pg.ts @@ -351,7 +351,7 @@ END ${colAlias}`, BOOLEAN: async (args: MapFnArgs) => { return { builder: args.knex.raw( - `(${(await args.fn(args.pt.arguments[0])).builder})::boolean ${ + `(${(await args.fn(args.pt.arguments[0])).builder})::boolean${ args.colAlias }`, ), From 1204bfced95b0ab004efdb9cf61c5b6a0e146113 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Mon, 15 Jan 2024 20:51:36 +0000 Subject: [PATCH 3/3] fix: use column id for updating colOptions --- packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts | 5 ++--- packages/nocodb/src/models/FormulaColumn.ts | 8 +++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts b/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts index 5a1884891a..81534e6f9c 100644 --- a/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts +++ b/packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts @@ -1169,7 +1169,7 @@ export default async function formulaQueryBuilderv2( const formula = await column.getColOptions(); // clean the previous formula error if the formula works this time if (formula.error) { - await FormulaColumn.update(formula.id, { + await FormulaColumn.update(column.id, { error: null, }); } @@ -1179,9 +1179,8 @@ export default async function formulaQueryBuilderv2( console.error(e); if (column) { - const formula = await column.getColOptions(); // add formula error to show in UI - await FormulaColumn.update(formula.id, { + await FormulaColumn.update(column.id, { error: e.message, }); // update cache to reflect the error in UI diff --git a/packages/nocodb/src/models/FormulaColumn.ts b/packages/nocodb/src/models/FormulaColumn.ts index c9bd744f73..f073f69cd8 100644 --- a/packages/nocodb/src/models/FormulaColumn.ts +++ b/packages/nocodb/src/models/FormulaColumn.ts @@ -62,7 +62,7 @@ export default class FormulaColumn { id: string; static async update( - id: string, + columnId: string, formula: Partial & { parsed_tree?: any }, ncMeta = Noco.ncMeta, ) { @@ -75,7 +75,7 @@ export default class FormulaColumn { ]); // get existing cache - const key = `${CacheScope.COL_FORMULA}:${id}`; + const key = `${CacheScope.COL_FORMULA}:${columnId}`; let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT); if (o) { o = { ...o, ...updateObj }; @@ -85,7 +85,9 @@ export default class FormulaColumn { if ('parsed_tree' in updateObj) updateObj.parsed_tree = stringifyMetaProp(updateObj, 'parsed_tree'); // set meta - await ncMeta.metaUpdate(null, null, MetaTable.COL_FORMULA, updateObj, id); + await ncMeta.metaUpdate(null, null, MetaTable.COL_FORMULA, updateObj, { + fk_column_id: columnId, + }); } public getParsedTree() {