Optimize operator name with use_rich_format enabled
This commit is contained in:
		@ -53,7 +53,7 @@ int ObMonitoringDumpOp::inner_open()
 | 
			
		||||
    LOG_WARN("unexpected status: child is null", K(ret));
 | 
			
		||||
  } else {
 | 
			
		||||
    ObObj val;
 | 
			
		||||
    const char* name = get_phy_op_name(spec_.get_left()->type_);
 | 
			
		||||
    const char* name = get_phy_op_name(spec_.get_left()->type_, spec_.use_rich_format_);
 | 
			
		||||
    op_name_.set_string(name, strlen(name));
 | 
			
		||||
    if (OB_FAIL(ctx_.get_my_session()->get_sys_variable(SYS_VAR_TRACEFILE_IDENTIFIER, val))) {
 | 
			
		||||
      LOG_WARN("Get sys variable error", K(ret));
 | 
			
		||||
 | 
			
		||||
@ -361,6 +361,7 @@ int ObOpSpec::create_operator_recursive(ObExecContext &exec_ctx, ObOperator *&op
 | 
			
		||||
        op->get_monitor_info().set_plan_depth(plan_depth_);
 | 
			
		||||
        op->get_monitor_info().set_tenant_id(GET_MY_SESSION(exec_ctx)->get_effective_tenant_id());
 | 
			
		||||
        op->get_monitor_info().open_time_ = oceanbase::common::ObClockGenerator::getClock();
 | 
			
		||||
        op->get_monitor_info().set_rich_format(use_rich_format_);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -231,7 +231,7 @@ public:
 | 
			
		||||
  virtual ~ObOpSpec();
 | 
			
		||||
 | 
			
		||||
  DECLARE_VIRTUAL_TO_STRING;
 | 
			
		||||
  const char *op_name() const { return ob_phy_operator_type_str(type_); }
 | 
			
		||||
  const char *op_name() const { return ob_phy_operator_type_str(type_, use_rich_format_); }
 | 
			
		||||
 | 
			
		||||
  // Pre-order recursive create execution components (ObOperator and ObOperatorInput)
 | 
			
		||||
  // for current DFO.
 | 
			
		||||
@ -274,7 +274,7 @@ public:
 | 
			
		||||
  int32_t get_child_num() const { return get_child_cnt(); }
 | 
			
		||||
  ObPhyOperatorType get_type() const { return type_; }
 | 
			
		||||
  uint64_t get_id() const { return id_; }
 | 
			
		||||
  const char *get_name() const { return get_phy_op_name(type_); }
 | 
			
		||||
  const char *get_name() const { return get_phy_op_name(type_, use_rich_format_); }
 | 
			
		||||
 | 
			
		||||
  int accept(ObOpSpecVisitor &visitor) const;
 | 
			
		||||
  int64_t get_rows() const { return rows_; }
 | 
			
		||||
 | 
			
		||||
@ -34,6 +34,7 @@ struct ObOpTypeTraits
 | 
			
		||||
  constexpr static bool vectorized_ = false;
 | 
			
		||||
  constexpr static uint64_t ob_version_ = 0;
 | 
			
		||||
  constexpr static bool support_rich_format_ = false;
 | 
			
		||||
  constexpr static const char *vec_op_name_ = "";
 | 
			
		||||
  typedef char LogOp;
 | 
			
		||||
  typedef char Spec;
 | 
			
		||||
  typedef char Op;
 | 
			
		||||
@ -65,12 +66,12 @@ struct SUPPORT_RICH_FORMAT {};
 | 
			
		||||
#define DEF_OP_INPUT_TRAITS_1(input, type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define REGISTER_OPERATOR_FULL(log_op, type, spec, op, x, y, z, rich_fmt) \
 | 
			
		||||
  REGISTER_OPERATOR_FULL_(log_op, type, spec, op, x, y, z, rich_fmt)
 | 
			
		||||
#define REGISTER_OPERATOR_FULL(log_op, type, spec, op, x, y, z, rich_fmt, vec_op_name) \
 | 
			
		||||
  REGISTER_OPERATOR_FULL_(log_op, type, spec, op, x, y, z, rich_fmt, vec_op_name)
 | 
			
		||||
#define REGISTER_OPERATOR_FULL_(...) REGISTER_OPERATOR_FULL__(__VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
#define REGISTER_OPERATOR_FULL__(log_op, type, op_spec, op, input_type,        \
 | 
			
		||||
                                 vec_type, ob_version, rich_fmt)               \
 | 
			
		||||
                                 vec_type, ob_version, rich_fmt, vec_op_name)  \
 | 
			
		||||
  namespace op_reg {                                                           \
 | 
			
		||||
  template <> struct ObOpTypeTraits<type> {                                    \
 | 
			
		||||
    constexpr static bool registered_ = true;                                  \
 | 
			
		||||
@ -80,7 +81,8 @@ struct SUPPORT_RICH_FORMAT {};
 | 
			
		||||
    constexpr static uint64_t ob_version_ =                                    \
 | 
			
		||||
        (ob_version == 0 ? CLUSTER_VERSION_4_0_0_0 : ob_version);              \
 | 
			
		||||
    constexpr static bool support_rich_format_ =                               \
 | 
			
		||||
        std::is_same<SUPPORT_RICH_FORMAT, rich_fmt>::value;                       \
 | 
			
		||||
        std::is_same<SUPPORT_RICH_FORMAT, rich_fmt>::value;                    \
 | 
			
		||||
    constexpr static const char *vec_op_name_ = support_rich_format_ ? vec_op_name : #type;\
 | 
			
		||||
    typedef log_op LogOp;                                                      \
 | 
			
		||||
    typedef op_spec Spec;                                                      \
 | 
			
		||||
    typedef op Op;                                                             \
 | 
			
		||||
@ -94,13 +96,15 @@ struct SUPPORT_RICH_FORMAT {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#define REGISTER_OPERATOR_5(log_op, type, spec, op, x) \
 | 
			
		||||
    REGISTER_OPERATOR_FULL(log_op, type, spec, op, x, char, 0, char)
 | 
			
		||||
    REGISTER_OPERATOR_FULL(log_op, type, spec, op, x, char, 0, char, "")
 | 
			
		||||
#define REGISTER_OPERATOR_6(log_op, type, spec, op, x, y) \
 | 
			
		||||
    REGISTER_OPERATOR_FULL(log_op, type, spec, op, x, y, 0, char)
 | 
			
		||||
    REGISTER_OPERATOR_FULL(log_op, type, spec, op, x, y, 0, char, "")
 | 
			
		||||
#define REGISTER_OPERATOR_7(log_op, type, spec, op, x, y, z) \
 | 
			
		||||
    REGISTER_OPERATOR_FULL(log_op, type, spec, op, x, y, z, char)
 | 
			
		||||
    REGISTER_OPERATOR_FULL(log_op, type, spec, op, x, y, z, char, "")
 | 
			
		||||
#define REGISTER_OPERATOR_8(log_op, type, spec, op, x, y, z, rich_fmt) \
 | 
			
		||||
    REGISTER_OPERATOR_FULL(log_op, type, spec, op, x, y, z, rich_fmt)
 | 
			
		||||
    REGISTER_OPERATOR_FULL(log_op, type, spec, op, x, y, z, rich_fmt, #type)
 | 
			
		||||
#define REGISTER_OPERATOR_9(log_op, type, spec, op, x, y, z, rich_format, new_vec_op)\
 | 
			
		||||
    REGISTER_OPERATOR_FULL(log_op, type, spec, op, x, y, z, rich_format, new_vec_op)
 | 
			
		||||
 | 
			
		||||
#define REGISTER_OPERATOR___(n, ...) REGISTER_OPERATOR_ ##n(__VA_ARGS__)
 | 
			
		||||
#define REGISTER_OPERATOR__(...) REGISTER_OPERATOR___(__VA_ARGS__)
 | 
			
		||||
@ -307,7 +311,7 @@ class ObTableScanSpec;
 | 
			
		||||
class ObTableScanOp;
 | 
			
		||||
REGISTER_OPERATOR(ObLogTableScan, PHY_TABLE_SCAN,
 | 
			
		||||
                  ObTableScanSpec, ObTableScanOp, ObTableScanOpInput,
 | 
			
		||||
                  VECTORIZED_OP, 0 /*version*/, SUPPORT_RICH_FORMAT);
 | 
			
		||||
                  VECTORIZED_OP, 0 /*version*/, SUPPORT_RICH_FORMAT, "PHY_VEC_TABLE_SCAN");
 | 
			
		||||
 | 
			
		||||
class ObLogTableScan;
 | 
			
		||||
class ObRowSampleScanOpInput;
 | 
			
		||||
@ -438,7 +442,7 @@ class ObSubPlanScanSpec;
 | 
			
		||||
class ObSubPlanScanOp;
 | 
			
		||||
REGISTER_OPERATOR(ObLogSubPlanScan, PHY_SUBPLAN_SCAN, ObSubPlanScanSpec,
 | 
			
		||||
                  ObSubPlanScanOp, NOINPUT, VECTORIZED_OP,  0 /*+version*/,
 | 
			
		||||
                  SUPPORT_RICH_FORMAT);
 | 
			
		||||
                  SUPPORT_RICH_FORMAT, "PHY_VEC_SUBPLAN_SCAN");
 | 
			
		||||
 | 
			
		||||
class ObLogUnpivot;
 | 
			
		||||
class ObUnpivotSpec;
 | 
			
		||||
@ -530,7 +534,7 @@ class ObJoinFilterOp;
 | 
			
		||||
class ObJoinFilterOpInput;
 | 
			
		||||
REGISTER_OPERATOR(ObLogJoinFilter, PHY_JOIN_FILTER, ObJoinFilterSpec,
 | 
			
		||||
                  ObJoinFilterOp, ObJoinFilterOpInput, VECTORIZED_OP,
 | 
			
		||||
                  0 /*+version*/, SUPPORT_RICH_FORMAT);
 | 
			
		||||
                  0 /*+version*/, SUPPORT_RICH_FORMAT, "PHY_VEC_JOIN_FILTER");
 | 
			
		||||
 | 
			
		||||
// PX Operator
 | 
			
		||||
// PHY_GRANULE_ITERATOR,
 | 
			
		||||
@ -547,7 +551,7 @@ class ObGranuleIteratorOp;
 | 
			
		||||
class ObGIOpInput;
 | 
			
		||||
REGISTER_OPERATOR(ObLogGranuleIterator, PHY_GRANULE_ITERATOR, ObGranuleIteratorSpec,
 | 
			
		||||
                  ObGranuleIteratorOp, ObGIOpInput, VECTORIZED_OP, 0 /*+version*/,
 | 
			
		||||
                  SUPPORT_RICH_FORMAT);
 | 
			
		||||
                  SUPPORT_RICH_FORMAT, "PHY_VEC_GRANULE_ITERATOR");
 | 
			
		||||
 | 
			
		||||
class ObLogExchange;
 | 
			
		||||
class ObPxFifoReceiveSpec;
 | 
			
		||||
@ -555,7 +559,7 @@ class ObPxFifoReceiveOp;
 | 
			
		||||
class ObPxFifoReceiveOpInput;
 | 
			
		||||
REGISTER_OPERATOR(ObLogExchange, PHY_PX_FIFO_RECEIVE, ObPxFifoReceiveSpec,
 | 
			
		||||
                  ObPxFifoReceiveOp, ObPxFifoReceiveOpInput, VECTORIZED_OP,
 | 
			
		||||
                  0 /*+version*/, SUPPORT_RICH_FORMAT);
 | 
			
		||||
                  0 /*+version*/, SUPPORT_RICH_FORMAT, "PHY_VEC_PX_FIFO_RECEIVE");
 | 
			
		||||
 | 
			
		||||
class ObLogExchange;
 | 
			
		||||
class ObPxMSReceiveSpec;
 | 
			
		||||
@ -578,7 +582,7 @@ class ObPxDistTransmitOp;
 | 
			
		||||
class ObPxDistTransmitOpInput;
 | 
			
		||||
REGISTER_OPERATOR(ObLogExchange, PHY_PX_DIST_TRANSMIT, ObPxDistTransmitSpec,
 | 
			
		||||
                  ObPxDistTransmitOp, ObPxDistTransmitOpInput, VECTORIZED_OP,
 | 
			
		||||
                  0 /*+version*/, SUPPORT_RICH_FORMAT);
 | 
			
		||||
                  0 /*+version*/, SUPPORT_RICH_FORMAT, "PHY_VEC_PX_DIST_TRANSMIT");
 | 
			
		||||
 | 
			
		||||
class ObLogExchange;
 | 
			
		||||
class ObPxRepartTransmitSpec;
 | 
			
		||||
@ -586,7 +590,7 @@ class ObPxRepartTransmitOp;
 | 
			
		||||
class ObPxRepartTransmitOpInput;
 | 
			
		||||
REGISTER_OPERATOR(ObLogExchange, PHY_PX_REPART_TRANSMIT, ObPxRepartTransmitSpec,
 | 
			
		||||
                  ObPxRepartTransmitOp, ObPxRepartTransmitOpInput, VECTORIZED_OP,
 | 
			
		||||
                  0 /*+version*/, SUPPORT_RICH_FORMAT);
 | 
			
		||||
                  0 /*+version*/, SUPPORT_RICH_FORMAT, "PHY_VEC_PX_REPART_TRANSMIT");
 | 
			
		||||
 | 
			
		||||
class ObLogExchange;
 | 
			
		||||
class ObPxReduceTransmitSpec;
 | 
			
		||||
@ -594,7 +598,7 @@ class ObPxReduceTransmitOp;
 | 
			
		||||
class ObPxReduceTransmitOpInput;
 | 
			
		||||
REGISTER_OPERATOR(ObLogExchange, PHY_PX_REDUCE_TRANSMIT, ObPxReduceTransmitSpec,
 | 
			
		||||
                  ObPxReduceTransmitOp, ObPxReduceTransmitOpInput, VECTORIZED_OP,
 | 
			
		||||
                  0 /*+version*/, SUPPORT_RICH_FORMAT);
 | 
			
		||||
                  0 /*+version*/, SUPPORT_RICH_FORMAT, "PHY_VEC_PX_REDUCE_TRANSMIT");
 | 
			
		||||
 | 
			
		||||
class ObLogExchange;
 | 
			
		||||
class ObPxFifoCoordSpec;
 | 
			
		||||
@ -602,14 +606,14 @@ class ObPxFifoCoordOp;
 | 
			
		||||
class ObPxFifoCoordOpInput;
 | 
			
		||||
REGISTER_OPERATOR(ObLogExchange, PHY_PX_FIFO_COORD, ObPxFifoCoordSpec,
 | 
			
		||||
                  ObPxFifoCoordOp, ObPxFifoCoordOpInput, VECTORIZED_OP,
 | 
			
		||||
                  0 /*+version*/, SUPPORT_RICH_FORMAT);
 | 
			
		||||
                  0 /*+version*/, SUPPORT_RICH_FORMAT, "PHY_VEC_PX_FIFO_COORD");
 | 
			
		||||
 | 
			
		||||
class ObPxOrderedCoordSpec;
 | 
			
		||||
class ObPxOrderedCoordOp;
 | 
			
		||||
class ObPxOrderedCoordOpInput;
 | 
			
		||||
REGISTER_OPERATOR(ObLogExchange, PHY_PX_ORDERED_COORD, ObPxOrderedCoordSpec,
 | 
			
		||||
                  ObPxOrderedCoordOp, ObPxOrderedCoordOpInput, VECTORIZED_OP,
 | 
			
		||||
                  0 /*+version*/, SUPPORT_RICH_FORMAT);
 | 
			
		||||
                  0 /*+version*/, SUPPORT_RICH_FORMAT, "PHY_VEC_PX_ORDERED_COORD");
 | 
			
		||||
class ObLogExchange;
 | 
			
		||||
class ObPxMSCoordSpec;
 | 
			
		||||
class ObPxMSCoordOp;
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@
 | 
			
		||||
#include "lib/atomic/ob_atomic.h"
 | 
			
		||||
#include "share/ob_define.h"
 | 
			
		||||
#include "lib/oblog/ob_log.h"
 | 
			
		||||
#include "sql/engine/ob_operator_reg.h"
 | 
			
		||||
 | 
			
		||||
using namespace oceanbase::sql;
 | 
			
		||||
using namespace oceanbase::common;
 | 
			
		||||
@ -24,48 +25,77 @@ namespace oceanbase
 | 
			
		||||
namespace sql
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  const char *get_phy_op_name(ObPhyOperatorType type) {
 | 
			
		||||
    const char* ret_char = NULL;
 | 
			
		||||
    static const char *ObPhyOpName[PHY_END + 2] =
 | 
			
		||||
      {
 | 
			
		||||
const char *get_phy_op_name(ObPhyOperatorType type, bool enable_rich_format /*false*/)
 | 
			
		||||
{
 | 
			
		||||
  const char *ret_char = NULL;
 | 
			
		||||
  static const char *ObPhyOpName[PHY_END + 2] = {
 | 
			
		||||
#define PHY_OP_DEF(type) #type,
 | 
			
		||||
#include "ob_phy_operator_type.h"
 | 
			
		||||
#undef PHY_OP_DEF
 | 
			
		||||
#define END ""
 | 
			
		||||
        END
 | 
			
		||||
    END
 | 
			
		||||
#undef END
 | 
			
		||||
      };
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
    if (type >= 0 && type < PHY_END + 2) {
 | 
			
		||||
      ret_char = ObPhyOpName[type];
 | 
			
		||||
  static const char *ObPhyVecOpName[PHY_END + 2] =
 | 
			
		||||
  {
 | 
			
		||||
#define PHY_OP_DEF(type) op_reg::ObOpTypeTraits<type>::vec_op_name_,
 | 
			
		||||
#include "ob_phy_operator_type.h"
 | 
			
		||||
#undef PHY_OP_DEF
 | 
			
		||||
#define END ""
 | 
			
		||||
    END
 | 
			
		||||
#undef END
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  if (type >= 0 && type < PHY_END + 2)
 | 
			
		||||
  {
 | 
			
		||||
    if (enable_rich_format && strlen(ObPhyVecOpName[type]) > 0) {
 | 
			
		||||
      ret_char = ObPhyVecOpName[type];
 | 
			
		||||
    } else {
 | 
			
		||||
      ret_char = "INVALID_OP";
 | 
			
		||||
      ret_char = ObPhyOpName[type];
 | 
			
		||||
    }
 | 
			
		||||
    return ret_char;
 | 
			
		||||
  } else {
 | 
			
		||||
    ret_char = "INVALID_OP";
 | 
			
		||||
  }
 | 
			
		||||
  return ret_char;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ObPhyOperatorTypeDescSet::set_type_str(ObPhyOperatorType type, const char *type_str)
 | 
			
		||||
ObPhyOperatorTypeDescSet::ObPhyOperatorTypeDescSet()
 | 
			
		||||
{
 | 
			
		||||
#define PHY_OP_DEF(type) set_type_str(type, #type, op_reg::ObOpTypeTraits<type>::vec_op_name_);
 | 
			
		||||
#include "sql/engine/ob_phy_operator_type.h"
 | 
			
		||||
#undef PHY_OP_DEF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ObPhyOperatorTypeDescSet::set_type_str(ObPhyOperatorType type, const char *type_str,
 | 
			
		||||
                                            const char *vec_name)
 | 
			
		||||
{
 | 
			
		||||
  if (OB_LIKELY(type >= PHY_INVALID && type < PHY_END)) {
 | 
			
		||||
    set_[type].name_ = type_str;
 | 
			
		||||
    set_[type].vec_name_ = vec_name;
 | 
			
		||||
  } else {
 | 
			
		||||
    LOG_WARN_RET(OB_ERR_UNEXPECTED, "invalid phy operator", K(type));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *ObPhyOperatorTypeDescSet::get_type_str(ObPhyOperatorType type) const
 | 
			
		||||
const char *ObPhyOperatorTypeDescSet::get_type_str(ObPhyOperatorType type,
 | 
			
		||||
                                                   bool enable_rich_format /* false */) const
 | 
			
		||||
{
 | 
			
		||||
  const char *ret = "UNKNOWN_PHY_OP";
 | 
			
		||||
  if (OB_LIKELY(type >= PHY_INVALID && type < PHY_END)) {
 | 
			
		||||
    ret = set_[type].name_;
 | 
			
		||||
    if (enable_rich_format && strlen(set_[type].vec_name_) > 0) {
 | 
			
		||||
      ret = set_[type].vec_name_;
 | 
			
		||||
    } else {
 | 
			
		||||
      ret = set_[type].name_;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ObPhyOperatorTypeDescSet PHY_OP_TYPE_DESC_SET;
 | 
			
		||||
const char *ob_phy_operator_type_str(ObPhyOperatorType type)
 | 
			
		||||
const char *ob_phy_operator_type_str(ObPhyOperatorType type, bool enable_rich_format /*false*/)
 | 
			
		||||
{
 | 
			
		||||
  return PHY_OP_TYPE_DESC_SET.get_type_str(type);
 | 
			
		||||
  return PHY_OP_TYPE_DESC_SET.get_type_str(type, enable_rich_format);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -154,22 +154,18 @@ namespace sql
 | 
			
		||||
#include "sql/engine/ob_phy_operator_type.h"
 | 
			
		||||
#undef PHY_OP_DEF
 | 
			
		||||
  };
 | 
			
		||||
  const char *get_phy_op_name(ObPhyOperatorType type);
 | 
			
		||||
  const char *get_phy_op_name(ObPhyOperatorType type, bool enable_rich_format = false);
 | 
			
		||||
struct ObPhyOperatorTypeDescSet
 | 
			
		||||
{
 | 
			
		||||
  struct ObPhyOperatorTypeDesc
 | 
			
		||||
  {
 | 
			
		||||
    const char *name_;
 | 
			
		||||
    ObPhyOperatorTypeDesc() : name_(NULL) {}
 | 
			
		||||
    const char *vec_name_;
 | 
			
		||||
    ObPhyOperatorTypeDesc() : name_(NULL), vec_name_(NULL) {}
 | 
			
		||||
  };
 | 
			
		||||
  ObPhyOperatorTypeDescSet()
 | 
			
		||||
  {
 | 
			
		||||
#define PHY_OP_DEF(type) set_type_str(type, #type);
 | 
			
		||||
#include "sql/engine/ob_phy_operator_type.h"
 | 
			
		||||
#undef PHY_OP_DEF
 | 
			
		||||
  }
 | 
			
		||||
  void set_type_str(ObPhyOperatorType type, const char *type_str);
 | 
			
		||||
  const char *get_type_str(ObPhyOperatorType type) const;
 | 
			
		||||
  ObPhyOperatorTypeDescSet();
 | 
			
		||||
  void set_type_str(ObPhyOperatorType type, const char *type_str, const char *vec_name);
 | 
			
		||||
  const char *get_type_str(ObPhyOperatorType type, bool enable_rich_format = false) const;
 | 
			
		||||
private:
 | 
			
		||||
  ObPhyOperatorTypeDesc set_[PHY_END];
 | 
			
		||||
};
 | 
			
		||||
@ -179,7 +175,7 @@ OB_INLINE bool is_phy_op_type_valid(ObPhyOperatorType type)
 | 
			
		||||
  return PHY_INVALID < type && type < PHY_END;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *ob_phy_operator_type_str(ObPhyOperatorType type);
 | 
			
		||||
const char *ob_phy_operator_type_str(ObPhyOperatorType type, bool enable_rich_format = false);
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user