@Explain(explainLevels = { Level.USER })
  public String getUserLevelJoinCondString() {
    JSONObject join = new JSONObject(new LinkedHashMap<>());
    try {
      switch (type) {
      case JoinDesc.INNER_JOIN:
        join.put("type", "Inner");
        break;
      case JoinDesc.FULL_OUTER_JOIN:
        join.put("type", "Outer");
        break;
      case JoinDesc.LEFT_OUTER_JOIN:
        join.put("type", "Left Outer");
        break;
      case JoinDesc.RIGHT_OUTER_JOIN:
        join.put("type", "Right Outer");
        break;
      case JoinDesc.UNIQUE_JOIN:
        join.put("type", "Unique");
        break;
      case JoinDesc.LEFT_SEMI_JOIN:
        join.put("type", "Left Semi");
        break;
      case JoinDesc.ANTI_JOIN:
        join.put("type", "Anti");
        break;
      default:
        join.put("type", "Unknown Join");
        break;
      }
      join.put("left", left);
      join.put("right", right);
    } catch (JSONException e) {
      // impossible to throw any json exceptions.
      LOG.trace(e.getMessage());
    }
    return join.toString();
  }
@param preserved
         if table is preserved, false otherwise
ql/src/java/org/apache/hadoop/hive/ql/plan/JoinCondDesc.java