code: public static ColumnValueSelector<ExprEval> makeExprEvalSelector(
        ColumnSelectorFactory columnSelectorFactory,
        Expr expression
    )
    {
      final List<String> columns = Parser.findRequiredBindings(expression);
  
      if (columns.size() == 1) {
        final String column = Iterables.getOnlyElement(columns);
        final ColumnCapabilities capabilities = columnSelectorFactory.getColumnCapabilities(column);
  
        if (capabilities != null && capabilities.getType() == ValueType.LONG) {
          // Optimization for expressions that hit one long column and nothing else.
          return new SingleLongInputCachingExpressionColumnValueSelector(
              columnSelectorFactory.makeColumnValueSelector(column),
              expression,
              !ColumnHolder.TIME_COLUMN_NAME.equals(column) // __time doesn't need an LRU cache since it is sorted.
          );
        } else if (capabilities != null
                   && capabilities.getType() == ValueType.STRING
                   && capabilities.isDictionaryEncoded()) {
          // Optimization for expressions that hit one string column and nothing else.
          return new SingleStringInputCachingExpressionColumnValueSelector(
              columnSelectorFactory.makeDimensionSelector(new DefaultDimensionSpec(column, column, ValueType.STRING)),
              expression
          );
        }
      }
  
      final Expr.ObjectBinding bindings = createBindings(expression, columnSelectorFactory);
  
      if (bindings.equals(ExprUtils.nilBindings())) {
        // Optimization for constant expressions.
        return new ConstantExprEvalSelector(expression.eval(bindings));
      }
  
      // No special optimization.
      return new ExpressionColumnValueSelector(expression, bindings);
    }
docs: Makes a ColumnValueSelector whose getObject method returns an {@link ExprEval}.
  
  @see ExpressionSelectors#makeColumnValueSelector(ColumnSelectorFactory, Expr)