@Nullable @Override public String toDruidExpression(RexNode rexNode, RelDataType rowType, DruidQuery query
    ) {
      final RexCall call = (RexCall) rexNode;
      if (call.getOperands().size() != 2) {
        throw new IllegalStateException("date_add/date_sub() requires 2 arguments, got " + call.getOperands().size());
      }
      final String arg0 = DruidExpressions.toDruidExpression(call.getOperands().get(0), rowType, query);
      final String arg1 = DruidExpressions.toDruidExpression(call.getOperands().get(1), rowType, query);
      if (arg0 == null || arg1 == null) {
        return null;
      }

      final String steps = direction == -1 ? DruidQuery.format("-( %s )", arg1) : arg1;
      return DruidExpressions.functionCall(
          "timestamp_shift",
          ImmutableList.of(
              arg0,
              DruidExpressions.stringLiteral("P1D"),
              steps,
              DruidExpressions.stringLiteral(timezoneId(query, call.getOperands().get(0)).getID())));
    }
Base class for Date Add/Sub operator conversion
ql/src/java/org/apache/hadoop/hive/ql/parse/DruidSqlOperatorConverter.java