diff --git a/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue b/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue index 6e5039b0f7..45624cf039 100644 --- a/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue +++ b/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue @@ -10,7 +10,7 @@ import { isSystemColumn, jsepCurlyHook, substituteColumnIdWithAliasInFormula, - validateDateWithUnknownFormat, + validateFormulaAndExtractTreeWithType } from 'nocodb-sdk' import { MetaInj, @@ -99,10 +99,15 @@ const validators = { validator: (_: any, formula: any) => { return new Promise((resolve, reject) => { if (!formula?.trim()) return reject(new Error('Required')) - const res = parseAndValidateFormula(formula) - if (res !== true) { - return reject(new Error(res)) + + try { + validateFormulaAndExtractTreeWithType(formula, supportedColumns.value) + } catch (e: any) { + return reject(new Error(e.message)) } + // if (res !== true) { + // return reject(new Error(res)) + // } resolve() }) }, @@ -226,7 +231,7 @@ function validateAgainstMeta(parsedTree: any, errors = new Set(), typeErrors = n return validateAgainstMeta(arg, errors, typeErrors) }) - const argsTypes = validateResult.map((v: any) => v.returnType); + const argsTypes = validateResult.map((v: any) => v.returnType) if (typeof validateResult[0].returnType === 'function') { returnType = formulas[calleeName].returnType(argsTypes) @@ -266,7 +271,9 @@ function validateAgainstMeta(parsedTree: any, errors = new Set(), typeErrors = n typeErrors, ) } else { - parsedTree.arguments.map((arg: Record) => validateAgainstType(arg, expectedType, null, typeErrors, argsTypes)) + parsedTree.arguments.map((arg: Record) => + validateAgainstType(arg, expectedType, null, typeErrors, argsTypes), + ) } } else if (expectedType === formulaTypes.DATE) { if (calleeName === 'DATEADD') { @@ -488,7 +495,13 @@ function validateAgainstMeta(parsedTree: any, errors = new Set(), typeErrors = n return { errors, returnType } } -function validateAgainstType(parsedTree: any, expectedType: string, func: any, typeErrors = new Set(), argTypes: formulaTypes = []) { +function validateAgainstType( + parsedTree: any, + expectedType: string, + func: any, + typeErrors = new Set(), + argTypes: formulaTypes = [], +) { let type if (parsedTree === false || typeof parsedTree === 'undefined') { return typeErrors diff --git a/packages/nocodb-sdk/src/lib/formulaHelpers.ts b/packages/nocodb-sdk/src/lib/formulaHelpers.ts index 6bdabf0dcc..c93a564bb5 100644 --- a/packages/nocodb-sdk/src/lib/formulaHelpers.ts +++ b/packages/nocodb-sdk/src/lib/formulaHelpers.ts @@ -693,7 +693,7 @@ const formulas: Record = { validation: { args: { min: 3, - } + }, }, description: 'Switch case value based on expr output', syntax: 'SWITCH(expr, [pattern, value, ..., default])', @@ -1169,7 +1169,7 @@ export function validateFormulaAndExtractTreeWithType( case UITypes.Collaborator: case UITypes.QrCode: default: - throw new FormulaError(FormulaErrorType.NOT_SUPPORTED, ''); + throw new FormulaError(FormulaErrorType.NOT_SUPPORTED, {}); } } } else if (parsedTree.type === JSEPNode.LITERAL) { @@ -1188,7 +1188,10 @@ export function validateFormulaAndExtractTreeWithType( ) { res.left = validateAndExtract(parsedTree.left); res.right = validateAndExtract(parsedTree.right); - res.dataType = FormulaDataTypes.NUMERIC; + + if (['==', '<', '>', '<=', '>=', '!='].includes(parsedTree.operator)) { + res.dataType = FormulaDataTypes.COND_EXP; + } else res.dataType = FormulaDataTypes.NUMERIC; } return res; diff --git a/packages/nocodb/src/db/functionMappings/commonFns.ts b/packages/nocodb/src/db/functionMappings/commonFns.ts index d8648b954e..ef3f8b5db3 100644 --- a/packages/nocodb/src/db/functionMappings/commonFns.ts +++ b/packages/nocodb/src/db/functionMappings/commonFns.ts @@ -142,7 +142,7 @@ export default { ).builder; } else { thenArg = (await args.fn(args.pt.arguments[1])).builder.toQuery(); - elseArg = (await args.fn(args.pt.arguments[1])).builder.toQuery(); + elseArg = (await args.fn(args.pt.arguments[2])).builder.toQuery(); } let query = args.knex.raw(`\n\tWHEN ${cond} THEN ${thenArg}`).toQuery();