ExpressionEvaluatorImpl implements ExpressionEvaluator { @Override public Map<String, Set<String>> getColumnNames(Object expression) { if (isColumnExpression(expression)) { ColumnExpression columnExpression = asColumnExpression(expression); String tableAlias = columnExpression.getTableAlias(); String columnName = columnExpression.getColumnName(); return Collections.singletonMap(tableAlias, Collections.singleton(columnName)); } else if (expression instanceof FunctionExpression) { final Map<String, Set<String>> ret = new HashMap<>(); FunctionExpression functionExpression = (FunctionExpression) expression; functionExpression.getArgs().stream() .map(this::getColumnNames) .forEach(m -> m.keySet().forEach(k -> { ret.putIfAbsent(k, new LinkedHashSet<>()); ret.get(k).addAll(m.get(k)); })); return ret; } else if (expression instanceof UnaryArithmeticExpression) { return getColumnNames(((UnaryArithmeticExpression) expression).getValue()); } else if (expression instanceof BinaryArithmeticExpression) { BinaryArithmeticExpression binaryArithmeticExpression = (BinaryArithmeticExpression) expression; Map<String, Set<String>> leftColumnNames = getColumnNames(binaryArithmeticExpression.getLeft()); Map<String, Set<String>> rightColumnNames = getColumnNames(binaryArithmeticExpression.getRight()); return mergeColumnNames(leftColumnNames, rightColumnNames); } return Collections.emptyMap(); }  @Override Map<String, Set<String>> getColumnNames(Object expression); @Override T evaluate(Object expression, DataRow dataRow); @Override T evaluateAs(Object expression, DataRow dataRow, Class<T> cls);  }
@Test public void testGetColumnNames() { ColumnExpression columnExpression = new ColumnExpression("id", "mock"); BinaryArithmeticExpression binaryArithmeticExpression = new BinaryArithmeticExpression(columnExpression, BinaryArithmeticOperator.PLUS, 1); UnaryArithmeticExpression unaryArithmeticExpression = new UnaryArithmeticExpression(binaryArithmeticExpression, UnaryArithmeticOperator.MINUS); FunctionExpression functionExpression = new FunctionExpression("abs", new ArrayList<Object>() { { add(unaryArithmeticExpression); } }); Map<String, Set<String>> columns = expressionEvaluator.getColumnNames(functionExpression); assertThat(columns.keySet(), hasSize(1)); assertThat(columns.keySet(), contains("mock")); assertThat(columns.get("mock"), hasSize(1)); assertThat(columns.get("mock"), contains("id")); }