Browse Source

refactor: SWITCH and IF type extraction correction

pull/7268/head
Pranav C 11 months ago
parent
commit
2f26553ccd
  1. 64
      packages/nocodb-sdk/src/lib/formulaHelpers.ts

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

@ -664,16 +664,28 @@ const formulas: Record<string, FormulaMeta> = {
'IF(5 > 1, "YES", "NO") => "YES"', 'IF(5 > 1, "YES", "NO") => "YES"',
'IF({column} > 1, "YES", "NO")', 'IF({column} > 1, "YES", "NO")',
], ],
returnType: (argsTypes: FormulaDataTypes[]) => { returnType: (argTypes: FormulaDataTypes[]) => {
if (argsTypes.slice(1).includes(FormulaDataTypes.STRING)) { // extract all return types except NULL, since null can be returned by any type
const returnValueTypes = new Set(
argTypes.slice(1).filter((type) => type !== FormulaDataTypes.NULL)
);
// if there are more than one return types or if there is a string return type
// return type as string else return the type
if (
returnValueTypes.size > 1 ||
returnValueTypes.has(FormulaDataTypes.STRING)
) {
return FormulaDataTypes.STRING; return FormulaDataTypes.STRING;
} else if (argsTypes.slice(1).includes(FormulaDataTypes.NUMERIC)) { } else if (returnValueTypes.has(FormulaDataTypes.NUMERIC)) {
return FormulaDataTypes.NUMERIC; return FormulaDataTypes.NUMERIC;
} else if (argsTypes.slice(1).includes(FormulaDataTypes.BOOLEAN)) { } else if (returnValueTypes.has(FormulaDataTypes.BOOLEAN)) {
return FormulaDataTypes.BOOLEAN; return FormulaDataTypes.BOOLEAN;
} else if (returnValueTypes.has(FormulaDataTypes.DATE)) {
return FormulaDataTypes.DATE;
} }
return argsTypes[1]; // if none of the above conditions are met, return the first return argument type
return argTypes[1];
}, },
}, },
SWITCH: { SWITCH: {
@ -681,7 +693,7 @@ const formulas: Record<string, FormulaMeta> = {
validation: { validation: {
args: { args: {
min: 3, min: 3,
}, }
}, },
description: 'Switch case value based on expr output', description: 'Switch case value based on expr output',
syntax: 'SWITCH(expr, [pattern, value, ..., default])', syntax: 'SWITCH(expr, [pattern, value, ..., default])',
@ -691,19 +703,29 @@ const formulas: Record<string, FormulaMeta> = {
'SWITCH(3, 1, "One", 2, "Two", "N/A") => "N/A"', 'SWITCH(3, 1, "One", 2, "Two", "N/A") => "N/A"',
'SWITCH({column1}, 1, "One", 2, "Two", "N/A")', 'SWITCH({column1}, 1, "One", 2, "Two", "N/A")',
], ],
// todo: resolve return type based on the args
returnType: (argTypes: FormulaDataTypes[]) => { returnType: (argTypes: FormulaDataTypes[]) => {
const returnArgTypes = argTypes.slice(2).filter((_, i) => i % 2 === 0); // extract all return types except NULL, since null can be returned by any type
const returnValueTypes = new Set(
argTypes.slice(2).filter((_, i) => i % 2 === 0)
);
if (returnArgTypes.includes(FormulaDataTypes.STRING)) { // if there are more than one return types or if there is a string return type
// return type as string else return the type
if (
returnValueTypes.size > 1 ||
returnValueTypes.has(FormulaDataTypes.STRING)
) {
return FormulaDataTypes.STRING; return FormulaDataTypes.STRING;
} else if (returnArgTypes.includes(FormulaDataTypes.NUMERIC)) { } else if (returnValueTypes.has(FormulaDataTypes.NUMERIC)) {
return FormulaDataTypes.NUMERIC; return FormulaDataTypes.NUMERIC;
} else if (returnArgTypes.includes(FormulaDataTypes.BOOLEAN)) { } else if (returnValueTypes.has(FormulaDataTypes.BOOLEAN)) {
return FormulaDataTypes.BOOLEAN; return FormulaDataTypes.BOOLEAN;
} else if (returnValueTypes.has(FormulaDataTypes.DATE)) {
return FormulaDataTypes.DATE;
} }
return returnArgTypes[0]; // if none of the above conditions are met, return the first return argument type
return argTypes[1];
}, },
}, },
URL: { URL: {
@ -965,13 +987,13 @@ const formulas: Record<string, FormulaMeta> = {
enum FormulaErrorType { enum FormulaErrorType {
NOT_AVAILABLE = 'NOT_AVAILABLE', NOT_AVAILABLE = 'NOT_AVAILABLE',
NOT_SUPPORTED = 'NOT_SUPPORTED', NOT_SUPPORTED = 'NOT_SUPPORTED',
'MIN_ARG' = 'MIN_ARG', MIN_ARG = 'MIN_ARG',
'MAX_ARG' = 'MAX_ARG', MAX_ARG = 'MAX_ARG',
'TYPE_MISMATCH' = 'TYPE_MISMATCH', TYPE_MISMATCH = 'TYPE_MISMATCH',
'INVALID_ARG' = 'INVALID_ARG', INVALID_ARG = 'INVALID_ARG',
'INVALID_ARG_TYPE' = 'INVALID_ARG_TYPE', INVALID_ARG_TYPE = 'INVALID_ARG_TYPE',
'INVALID_ARG_VALUE' = 'INVALID_ARG_VALUE', INVALID_ARG_VALUE = 'INVALID_ARG_VALUE',
'INVALID_ARG_COUNT' = 'INVALID_ARG_COUNT', INVALID_ARG_COUNT = 'INVALID_ARG_COUNT',
CIRCULAR_REFERENCE = 'CIRCULAR_REFERENCE', CIRCULAR_REFERENCE = 'CIRCULAR_REFERENCE',
INVALID_FUNCTION_NAME = 'INVALID_FUNCTION_NAME', INVALID_FUNCTION_NAME = 'INVALID_FUNCTION_NAME',
} }
@ -1075,11 +1097,11 @@ export function validateFormulaAndExtractTreeWithType(
} }
)); ));
const argsTypes = validateResult.map((v: any) => v.dataType); const argTypes = validateResult.map((v: any) => v.dataType);
if (typeof formulas[calleeName].returnType === 'function') { if (typeof formulas[calleeName].returnType === 'function') {
res.dataType = (formulas[calleeName].returnType as any)?.( res.dataType = (formulas[calleeName].returnType as any)?.(
argsTypes argTypes
) as FormulaDataTypes; ) as FormulaDataTypes;
} else if (formulas[calleeName].returnType) { } else if (formulas[calleeName].returnType) {
res.dataType = formulas[calleeName].returnType as FormulaDataTypes; res.dataType = formulas[calleeName].returnType as FormulaDataTypes;

Loading…
Cancel
Save