Browse Source

feat: convert `+` to string concatenation if atleast one of the operand is no-numeric

pull/7268/head
Pranav C 8 months ago
parent
commit
34941d849e
  1. 32
      packages/nocodb-sdk/src/lib/formulaHelpers.ts
  2. 16
      packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts

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

@ -1496,16 +1496,38 @@ export function validateFormulaAndExtractTreeWithType({
} else { } else {
res.dataType = FormulaDataTypes.STRING; res.dataType = FormulaDataTypes.STRING;
} }
} else if ( } else if (parsedTree.type === JSEPNode.UNARY_EXP) {
parsedTree.type === JSEPNode.BINARY_EXP || throw new FormulaError(
parsedTree.type === JSEPNode.UNARY_EXP FormulaErrorType.NOT_SUPPORTED,
) { {},
'Unary expression is not supported'
);
} else if (parsedTree.type === JSEPNode.BINARY_EXP) {
res.left = validateAndExtract(parsedTree.left); res.left = validateAndExtract(parsedTree.left);
res.right = validateAndExtract(parsedTree.right); res.right = validateAndExtract(parsedTree.right);
if (['==', '<', '>', '<=', '>=', '!='].includes(parsedTree.operator)) { if (['==', '<', '>', '<=', '>=', '!='].includes(parsedTree.operator)) {
res.dataType = FormulaDataTypes.COND_EXP; res.dataType = FormulaDataTypes.COND_EXP;
} else res.dataType = FormulaDataTypes.NUMERIC; }
else if (parsedTree.operator === '+') {
res.dataType = FormulaDataTypes.NUMERIC;
// if any side is string/date/other type, then the result will be concatenated string
// e.g. 1 + '2' = '12'
[res.left, res.right].some(
(r) =>
![
FormulaDataTypes.NUMERIC,
FormulaDataTypes.BOOLEAN,
FormulaDataTypes.NULL,
FormulaDataTypes.UNKNOWN,
].includes(r.dataType)
)
) {
res.dataType = FormulaDataTypes.STRING;
}
} else {
res.dataType = FormulaDataTypes.NUMERIC;
}
} }
return res; return res;

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

@ -833,6 +833,22 @@ async function _formulaQueryBuilder(
); );
} }
// if operator is + and expected return type is string, convert to concat
if (pt.operator === '+' && pt.dataType === FormulaDataTypes.STRING) {
return fn(
{
type: 'CallExpression',
arguments: [pt.left, pt.right],
callee: {
type: 'Identifier',
name: 'CONCAT',
},
},
alias,
prevBinaryOp,
);
}
if (pt.operator === '==') { if (pt.operator === '==') {
pt.operator = '='; pt.operator = '=';
// if left/right is of different type, convert to string and compare // if left/right is of different type, convert to string and compare

Loading…
Cancel
Save