Browse Source

fix: invalidate parse tree when a ref column updated

pull/7299/head
Pranav C 9 months ago
parent
commit
acfd9c54a4
  1. 35
      packages/nocodb/src/helpers/formulaHelpers.ts
  2. 24
      packages/nocodb/src/models/Column.ts
  3. 4
      packages/nocodb/src/models/FormulaColumn.ts

35
packages/nocodb/src/helpers/formulaHelpers.ts

@ -0,0 +1,35 @@
import jsep from 'jsep';
import { UITypes } from 'nocodb-sdk';
import type FormulaColumn from '../models/FormulaColumn';
import type { Column } from '~/models';
export async function getFormulasReferredTheColumn({
column,
columns,
}: {
column: Column;
columns: Column[];
}): Promise<Column[]> {
const fn = (pt) => {
if (pt.type === 'CallExpression') {
return pt.arguments.some((arg) => fn(arg));
} else if (pt.type === 'Literal') {
} else if (pt.type === 'Identifier') {
return [column.id, column.title].includes(pt.name);
} else if (pt.type === 'BinaryExpression') {
return fn(pt.left) || fn(pt.right);
}
};
return columns.reduce(async (columnsPromise, c) => {
const columns = await columnsPromise;
if (c.uidt !== UITypes.Formula) return columns;
const formula = await c.getColOptions<FormulaColumn>();
if (fn(jsep(formula.formula))) {
columns.push(c);
}
return columns;
}, Promise.resolve([]));
}

24
packages/nocodb/src/models/Column.ts

@ -3,6 +3,7 @@ import {
isLinksOrLTAR,
UITypes,
} from 'nocodb-sdk';
import { Logger } from '@nestjs/common';
import type { ColumnReqType, ColumnType } from 'nocodb-sdk';
import FormulaColumn from '~/models/FormulaColumn';
import LinkToAnotherRecordColumn from '~/models/LinkToAnotherRecordColumn';
@ -28,6 +29,7 @@ import {
} from '~/utils/globals';
import NocoCache from '~/cache/NocoCache';
import { parseMetaProp, stringifyMetaProp } from '~/utils/modelUtils';
import { getFormulasReferredTheColumn } from '~/helpers/formulaHelpers';
const selectColors = [
'#cfdffe',
@ -42,6 +44,8 @@ const selectColors = [
'#eeeeee',
];
const logger = new Logger('Column');
export default class Column<T = any> implements ColumnType {
public fk_model_id: string;
public base_id: string;
@ -1159,6 +1163,26 @@ export default class Column<T = any> implements ColumnType {
// on column update, delete any optimised single query cache
await NocoCache.delAll(CacheScope.SINGLE_QUERY, `${oldCol.fk_model_id}:*`);
const updatedColumn = await Column.get({ colId });
// invalidate formula parsed-tree in which current column is used
// whenever a new request comes for that formula, it will be populated again
getFormulasReferredTheColumn({
column: updatedColumn,
columns: await Column.list({ fk_model_id: column.fk_model_id }),
})
.then(async (formulas) => {
for (const formula of formulas) {
await FormulaColumn.update(formula.id, {
parsed_tree: null,
});
}
})
// ignore the error and continue, if formula is no longer valid it will be captured in the next run
.catch((err) => {
logger.error(err);
});
}
static async updateAlias(

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

@ -74,8 +74,6 @@ export default class FormulaColumn {
'parsed_tree',
]);
updateObj.parsed_tree = stringifyMetaProp(updateObj, 'parsed_tree');
// get existing cache
const key = `${CacheScope.COL_FORMULA}:${id}`;
let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT);
@ -84,6 +82,8 @@ export default class FormulaColumn {
// set cache
await NocoCache.set(key, o);
}
if ('parsed_tree' in updateObj)
updateObj.parsed_tree = stringifyMetaProp(updateObj, 'parsed_tree');
// set meta
await ncMeta.metaUpdate(null, null, MetaTable.COL_FORMULA, updateObj, id);
}

Loading…
Cancel
Save