@Nullable
  public static DruidExpression toDruidExpression(
      final PlannerContext plannerContext,
      final RowSignature rowSignature,
      final RexNode rexNode
  )
  {
    final SqlKind kind = rexNode.getKind();
    final SqlTypeName sqlTypeName = rexNode.getType().getSqlTypeName();

    if (kind == SqlKind.INPUT_REF) {
      // Translate field references.
      final RexInputRef ref = (RexInputRef) rexNode;
      final String columnName = rowSignature.getRowOrder().get(ref.getIndex());
      if (columnName == null) {
        throw new ISE("WTF?! Expression referred to nonexistent index[%d]", ref.getIndex());
      }

      return DruidExpression.fromColumn(columnName);
    } else if (rexNode instanceof RexCall) {
      final SqlOperator operator = ((RexCall) rexNode).getOperator();

      final SqlOperatorConversion conversion = plannerContext.getOperatorTable()
                                                             .lookupOperatorConversion(operator);

      if (conversion == null) {
        return null;
      } else {
        return conversion.toDruidExpression(plannerContext, rowSignature, rexNode);
      }
    } else if (kind == SqlKind.LITERAL) {
      // Translate literal.
      if (RexLiteral.isNullLiteral(rexNode)) {
        return DruidExpression.fromExpression(DruidExpression.nullLiteral());
      } else if (SqlTypeName.NUMERIC_TYPES.contains(sqlTypeName)) {
        return DruidExpression.fromExpression(DruidExpression.numberLiteral((Number) RexLiteral.value(rexNode)));
      } else if (SqlTypeFamily.INTERVAL_DAY_TIME == sqlTypeName.getFamily()) {
        // Calcite represents DAY-TIME intervals in milliseconds.
        final long milliseconds = ((Number) RexLiteral.value(rexNode)).longValue();
        return DruidExpression.fromExpression(DruidExpression.numberLiteral(milliseconds));
      } else if (SqlTypeFamily.INTERVAL_YEAR_MONTH == sqlTypeName.getFamily()) {
        // Calcite represents YEAR-MONTH intervals in months.
        final long months = ((Number) RexLiteral.value(rexNode)).longValue();
        return DruidExpression.fromExpression(DruidExpression.numberLiteral(months));
      } else if (SqlTypeName.STRING_TYPES.contains(sqlTypeName)) {
        return DruidExpression.fromExpression(DruidExpression.stringLiteral(RexLiteral.stringValue(rexNode)));
      } else if (SqlTypeName.TIMESTAMP == sqlTypeName || SqlTypeName.DATE == sqlTypeName) {
        if (RexLiteral.isNullLiteral(rexNode)) {
          return DruidExpression.fromExpression(DruidExpression.nullLiteral());
        } else {
          return DruidExpression.fromExpression(
              DruidExpression.numberLiteral(
                  Calcites.calciteDateTimeLiteralToJoda(rexNode, plannerContext.getTimeZone()).getMillis()
              )
          );
        }
      } else if (SqlTypeName.BOOLEAN == sqlTypeName) {
        return DruidExpression.fromExpression(DruidExpression.numberLiteral(RexLiteral.booleanValue(rexNode) ? 1 : 0));
      } else {
        // Can't translate other literals.
        return null;
      }
    } else {
      // Can't translate.
      return null;
    }
  }
@ Nullable public static DruidExpression toDruidExpression ( final PlannerContext plannerContext , final RowSignature rowSignature , final RexNode rexNode ) { final SqlKind kind = rexNode . getKind ( ) ; final SqlTypeName sqlTypeName = rexNode . getType ( ) . getSqlTypeName ( ) ; if ( kind == SqlKind . INPUT_REF ) { final RexInputRef ref = ( RexInputRef ) rexNode ; final String columnName = rowSignature . getRowOrder ( ) . get ( ref . getIndex ( ) ) ; if ( columnName == null ) { throw new ISE ( "WTF?! Expression referred to nonexistent index[%d]" , ref . getIndex ( ) ) ; } return DruidExpression . fromColumn ( columnName ) ; } else if ( rexNode instanceof RexCall ) { final SqlOperator operator = ( ( RexCall ) rexNode ) . getOperator ( ) ; final SqlOperatorConversion conversion = plannerContext . getOperatorTable ( ) . lookupOperatorConversion ( operator ) ; if ( conversion == null ) { return null ; } else { return conversion . toDruidExpression ( plannerContext , rowSignature , rexNode ) ; } } else if ( kind == SqlKind . LITERAL ) { if ( RexLiteral . isNullLiteral ( rexNode ) ) { return DruidExpression . fromExpression ( DruidExpression . nullLiteral ( ) ) ; } else if ( SqlTypeName . NUMERIC_TYPES . contains ( sqlTypeName ) ) { return DruidExpression . fromExpression ( DruidExpression . numberLiteral ( ( Number ) RexLiteral . value ( rexNode ) ) ) ; } else if ( SqlTypeFamily . INTERVAL_DAY_TIME == sqlTypeName . getFamily ( ) ) { final long milliseconds = ( ( Number ) RexLiteral . value ( rexNode ) ) . longValue ( ) ; return DruidExpression . fromExpression ( DruidExpression . numberLiteral ( milliseconds ) ) ; } else if ( SqlTypeFamily . INTERVAL_YEAR_MONTH == sqlTypeName . getFamily ( ) ) { final long months = ( ( Number ) RexLiteral . value ( rexNode ) ) . longValue ( ) ; return DruidExpression . fromExpression ( DruidExpression . numberLiteral ( months ) ) ; } else if ( SqlTypeName . STRING_TYPES . contains ( sqlTypeName ) ) { return DruidExpression . fromExpression ( DruidExpression . stringLiteral ( RexLiteral . stringValue ( rexNode ) ) ) ; } else if ( SqlTypeName . TIMESTAMP == sqlTypeName || SqlTypeName . DATE == sqlTypeName ) { if ( RexLiteral . isNullLiteral ( rexNode ) ) { return DruidExpression . fromExpression ( DruidExpression . nullLiteral ( ) ) ; } else { return DruidExpression . fromExpression ( DruidExpression . numberLiteral ( Calcites . calciteDateTimeLiteralToJoda ( rexNode , plannerContext . getTimeZone ( ) ) . getMillis ( ) ) ) ; } } else if ( SqlTypeName . BOOLEAN == sqlTypeName ) { return DruidExpression . fromExpression ( DruidExpression . numberLiteral ( RexLiteral . booleanValue ( rexNode ) ? 1 : 0 ) ) ; } else { return null ; } } else { return null ; } }
Translate a Calcite {@code RexNode} to a Druid expressions.

@param plannerContext SQL planner context
@param rowSignature   signature of the rows to be extracted from
@param rexNode        expression meant to be applied on top of the rows

@return rexNode referring to fields in rowOrder, or null if not possible