Browse Source

Merge pull request #7437 from nocodb/nc-fix/formula-improvements

fix: formula improvements
pull/7443/head
Mert E 11 months ago committed by GitHub
parent
commit
897876a9a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      packages/nocodb-sdk/src/lib/formulaHelpers.ts
  2. 22
      packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts
  3. 3
      packages/nocodb/src/db/functionMappings/commonFns.ts
  4. 9
      packages/nocodb/src/db/functionMappings/pg.ts
  5. 8
      packages/nocodb/src/models/FormulaColumn.ts

6
packages/nocodb-sdk/src/lib/formulaHelpers.ts

@ -1594,7 +1594,11 @@ async function extractColumnIdentifierType({
res.dataType = FormulaDataTypes.STRING; res.dataType = FormulaDataTypes.STRING;
break; break;
case UITypes.Checkbox: case UITypes.Checkbox:
res.dataType = FormulaDataTypes.NUMERIC; if (col.dt === 'boolean' || col.dt === 'bool') {
res.dataType = FormulaDataTypes.BOOLEAN;
} else {
res.dataType = FormulaDataTypes.NUMERIC;
}
break; break;
case UITypes.ID: case UITypes.ID:
case UITypes.ForeignKey: case UITypes.ForeignKey:

22
packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts

@ -905,6 +905,23 @@ async function _formulaQueryBuilder(
// if operator is == or !=, then handle comparison with BLANK which should accept NULL and empty string // if operator is == or !=, then handle comparison with BLANK which should accept NULL and empty string
if (pt.operator === '==' || pt.operator === '!=') { 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 (pt.left.callee?.name !== pt.right.callee?.name) {
// if left/right is BLANK, accept both NULL and empty string // if left/right is BLANK, accept both NULL and empty string
for (const operand of ['left', 'right']) { for (const operand of ['left', 'right']) {
@ -1168,7 +1185,7 @@ export default async function formulaQueryBuilderv2(
const formula = await column.getColOptions<FormulaColumn>(); const formula = await column.getColOptions<FormulaColumn>();
// clean the previous formula error if the formula works this time // clean the previous formula error if the formula works this time
if (formula.error) { if (formula.error) {
await FormulaColumn.update(formula.id, { await FormulaColumn.update(column.id, {
error: null, error: null,
}); });
} }
@ -1178,9 +1195,8 @@ export default async function formulaQueryBuilderv2(
console.error(e); console.error(e);
if (column) { if (column) {
const formula = await column.getColOptions<FormulaColumn>();
// add formula error to show in UI // add formula error to show in UI
await FormulaColumn.update(formula.id, { await FormulaColumn.update(column.id, {
error: e.message, error: e.message,
}); });
// update cache to reflect the error in UI // update cache to reflect the error in UI

3
packages/nocodb/src/db/functionMappings/commonFns.ts

@ -184,6 +184,9 @@ export default {
STRING(args: MapFnArgs) { STRING(args: MapFnArgs) {
return args.fn(args.pt?.arguments?.[0]); return args.fn(args.pt?.arguments?.[0]);
}, },
BOOLEAN(args: MapFnArgs) {
return args.fn(args.pt?.arguments?.[0]);
},
AND: async (args: MapFnArgs) => { AND: async (args: MapFnArgs) => {
return { return {
builder: args.knex.raw( builder: args.knex.raw(

9
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; export default pg;

8
packages/nocodb/src/models/FormulaColumn.ts

@ -62,7 +62,7 @@ export default class FormulaColumn {
id: string; id: string;
static async update( static async update(
id: string, columnId: string,
formula: Partial<FormulaColumn> & { parsed_tree?: any }, formula: Partial<FormulaColumn> & { parsed_tree?: any },
ncMeta = Noco.ncMeta, ncMeta = Noco.ncMeta,
) { ) {
@ -75,7 +75,7 @@ export default class FormulaColumn {
]); ]);
// get existing cache // get existing cache
const key = `${CacheScope.COL_FORMULA}:${id}`; const key = `${CacheScope.COL_FORMULA}:${columnId}`;
let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT); let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT);
if (o) { if (o) {
o = { ...o, ...updateObj }; o = { ...o, ...updateObj };
@ -85,7 +85,9 @@ export default class FormulaColumn {
if ('parsed_tree' in updateObj) if ('parsed_tree' in updateObj)
updateObj.parsed_tree = stringifyMetaProp(updateObj, 'parsed_tree'); updateObj.parsed_tree = stringifyMetaProp(updateObj, 'parsed_tree');
// set meta // 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() { public getParsedTree() {

Loading…
Cancel
Save