diff --git a/packages/nc-gui/components/project/spreadsheet/components/editColumn/formulaOptions.vue b/packages/nc-gui/components/project/spreadsheet/components/editColumn/formulaOptions.vue index 66431a4ff2..d5af9bc103 100644 --- a/packages/nc-gui/components/project/spreadsheet/components/editColumn/formulaOptions.vue +++ b/packages/nc-gui/components/project/spreadsheet/components/editColumn/formulaOptions.vue @@ -20,7 +20,7 @@ hide-details="auto" label="Formula" persistent-hint - hint="Available formulas are ADD, AVG, CONCAT, +, -, /" + hint="Hint: If you reference columns, use '$' to wrap the column name, e.g: $column_name$." :rules="[v => !!v || 'Required', v => parseAndValidateFormula(v)]" autocomplete="off" @input="handleInputDeb" @@ -165,7 +165,6 @@ export default { this.$toast.error(e.message).goAway(3000) } }, - // todo: validate formula based on meta parseAndValidateFormula(formula) { try { const pt = jsep(formula) @@ -195,8 +194,12 @@ export default { } pt.arguments.map(arg => this.validateAgainstMeta(arg, arr)) } else if (pt.type === 'Identifier') { - if (this.meta.columns.filter(c => !this.column || this.column.id !== c.id).every(c => c.title !== pt.name)) { - arr.push(`Column with name '${pt.name}' is not available`) + // $column_name$ -> column_name + const sanitizedPtName = pt.name.substring(1, pt.name.length - 1) + if (this.meta.columns.filter(c => !this.column || this.column.id !== c.id).find(c => c.title === pt.name)) { + arr.push(`Column '${pt.name}' needs to be wrapped by $. Try $${pt.name}$ instead`) + } else if (this.meta.columns.filter(c => !this.column || this.column.id !== c.id).every(c => c.title !== sanitizedPtName)) { + arr.push(`Column '${pt.name}' is not available`) } } else if (pt.type === 'BinaryExpression') { if (!this.availableBinOps.includes(pt.operator)) { diff --git a/packages/nocodb-sdk/src/lib/formulaHelpers.ts b/packages/nocodb-sdk/src/lib/formulaHelpers.ts index 492b362ecd..a1f97b20a3 100644 --- a/packages/nocodb-sdk/src/lib/formulaHelpers.ts +++ b/packages/nocodb-sdk/src/lib/formulaHelpers.ts @@ -15,7 +15,7 @@ export function substituteColumnIdWithAliasInFormula( } else if (pt.type === 'Literal') { return; } else if (pt.type === 'Identifier') { - const colNameOrId = pt.name; + const colNameOrId = pt?.name; const column = columns.find( (c) => c.id === colNameOrId || @@ -23,6 +23,9 @@ export function substituteColumnIdWithAliasInFormula( c.title === colNameOrId ); pt.name = column?.title || ptRaw?.name || pt?.name; + if (pt.name[0] != '$' && pt.name[pt.name.length - 1] != '$') { + pt.name = '$' + pt.name + '$'; + } } else if (pt.type === 'BinaryExpression') { substituteId(pt.left, ptRaw?.left); substituteId(pt.right, ptRaw?.right); diff --git a/packages/nocodb/src/lib/noco/meta/helpers/formulaHelpers.ts b/packages/nocodb/src/lib/noco/meta/helpers/formulaHelpers.ts index 8bc4159710..f49927f09c 100644 --- a/packages/nocodb/src/lib/noco/meta/helpers/formulaHelpers.ts +++ b/packages/nocodb/src/lib/noco/meta/helpers/formulaHelpers.ts @@ -14,7 +14,8 @@ export async function substituteColumnAliasWithIdInFormula( } else if (pt.type === 'Literal') { return; } else if (pt.type === 'Identifier') { - const colNameOrId = pt.name; + const sanitizedPtName = pt.name.substring(1, pt.name.length - 1); + const colNameOrId = sanitizedPtName; const column = columns.find( c => c.id === colNameOrId ||