import {} from './aggregates';
export function evaluateExpression(exp, context) {
switch (exp.type) {
case 'number':
case 'string':
case 'literal':
case 'star':
return exp.value;
case 'identifier':
if (context.hasOwnProperty(exp.value)) {
return context[exp.value];
}
throw ReferenceError('Column not found: ' + exp.string);
case 'call':
if (functions.hasOwnProperty(exp.functionName)) {
const argValues = exp.arguments.map(
arg => evaluateExpression(arg, context));
return functions[exp.functionName](...argValues);
}
throw ReferenceError(`SQL function not found: ${exp.functionName}`);
case 'binaryExpression':
return performBinaryOperation(
exp.operator,
evaluateExpression(exp.left, context),
evaluateExpression(exp.right, context));
case 'aggregate':
return context._aggregateValues[exp.id];
case 'caseIf':
return evaluateCaseIf(exp, context);
case 'caseSwitch':
return evaluateCaseSwitch(exp, context);
default:
throw Error(`Unexpected expression type: ${exp.type}`);
}
}
function performBinaryOperation(operator, left, right) {
switch (operator) {
case '=':
return str(left) === str(right);
case '!=':
case '':
return str(left) !== str(right);
case '>':
return Number(left) > Number(right);
case '=':
return Number(left) >= Number(right);
case '