remove check_table_id_exists when resolve stmt
This commit is contained in:
parent
3b425920cb
commit
a08c6adbb9
@ -5559,11 +5559,11 @@ int ObDMLResolver::resolve_base_or_alias_table_item_normal(uint64_t tenant_id,
|
||||
if (session_info_->get_ddl_info().is_ddl()) {
|
||||
if (!tschema->is_storage_local_index_table()) {
|
||||
item->ref_id_ = tschema->get_table_id();
|
||||
item->table_id_ = tschema->get_table_id();
|
||||
item->table_id_ = generate_table_id();
|
||||
item->is_system_table_ = tschema->is_sys_table();
|
||||
item->is_view_table_ = tschema->is_view_table();
|
||||
item->table_name_ = tschema->get_table_name_str();
|
||||
item->alias_name_ = tschema->get_table_name_str();
|
||||
item->alias_name_ = alias_name;
|
||||
item->ddl_schema_version_ = tschema->get_schema_version();
|
||||
item->ddl_table_id_ = tschema->get_table_id();
|
||||
item->table_type_ = tschema->get_table_type();
|
||||
@ -5573,45 +5573,16 @@ int ObDMLResolver::resolve_base_or_alias_table_item_normal(uint64_t tenant_id,
|
||||
LOG_WARN("get data table schema failed", K(ret), K_(item->ref_id));
|
||||
} else {
|
||||
item->ref_id_ = tab_schema->get_table_id();
|
||||
item->table_id_ = tab_schema->get_table_id();
|
||||
item->table_id_ = generate_table_id();
|
||||
item->is_system_table_ = tab_schema->is_sys_table();
|
||||
item->is_view_table_ = tab_schema->is_view_table();
|
||||
item->table_name_ = tab_schema->get_table_name_str();
|
||||
item->alias_name_ = tab_schema->get_table_name_str();
|
||||
item->alias_name_ = alias_name;
|
||||
item->ddl_schema_version_ = tschema->get_schema_version();
|
||||
item->ddl_table_id_ = tschema->get_table_id();
|
||||
item->table_type_ = tschema->get_table_type();
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
// sql used by foreign key checking ddl may have more than one table items refering to the same table
|
||||
if (item->ref_id_ == OB_INVALID_ID) {
|
||||
ret = OB_TABLE_NOT_EXIST;
|
||||
LOG_USER_ERROR(OB_TABLE_NOT_EXIST, to_cstring(db_name), to_cstring(tbl_name));
|
||||
} else if (TableItem::BASE_TABLE == item->type_) {
|
||||
bool is_exist = false;
|
||||
if (OB_FAIL(check_table_id_exists(item->ref_id_, is_exist))) {
|
||||
LOG_WARN("check table id exists failed", K_(item->ref_id));
|
||||
} else if (is_exist) {
|
||||
//in the whole query stmt, table exists in the other query layer, so subquery must alias it
|
||||
//implicit alias table, alias name is table name
|
||||
item->table_id_ = generate_table_id();
|
||||
item->type_ = TableItem::ALIAS_TABLE;
|
||||
if (!synonym_name.empty()) {
|
||||
// bug: 31827906
|
||||
item->alias_name_ = synonym_name;
|
||||
} else {
|
||||
item->alias_name_ = tbl_name;
|
||||
}
|
||||
} else {
|
||||
//base table, no alias name
|
||||
item->table_id_ = generate_table_id();
|
||||
}
|
||||
} else {
|
||||
item->table_id_ = generate_table_id();
|
||||
item->alias_name_ = alias_name;
|
||||
}
|
||||
}
|
||||
} else if (tschema->is_index_table() || tschema->is_materialized_view()) {
|
||||
//feature: select * from index_name where... rewrite to select index_col1, index_col2... from data_table_name where...
|
||||
//the feature only use in mysqtest case, not open for user
|
||||
@ -5655,37 +5626,13 @@ int ObDMLResolver::resolve_base_or_alias_table_item_normal(uint64_t tenant_id,
|
||||
}
|
||||
} else {
|
||||
item->ref_id_ = tschema->get_table_id();
|
||||
item->table_id_ = generate_table_id();
|
||||
item->table_name_ = tbl_name;
|
||||
item->alias_name_ = alias_name;
|
||||
item->is_system_table_ = tschema->is_sys_table();
|
||||
item->is_view_table_ = tschema->is_view_table();
|
||||
item->ddl_schema_version_ = tschema->get_schema_version();
|
||||
item->table_type_ = tschema->get_table_type();
|
||||
if (item->ref_id_ == OB_INVALID_ID) {
|
||||
ret = OB_TABLE_NOT_EXIST;
|
||||
LOG_USER_ERROR(OB_TABLE_NOT_EXIST, to_cstring(db_name), to_cstring(tbl_name));
|
||||
} else if (TableItem::BASE_TABLE == item->type_) {
|
||||
bool is_exist = false;
|
||||
if (OB_FAIL(check_table_id_exists(item->ref_id_, is_exist))) {
|
||||
LOG_WARN("check table id exists failed", K_(item->ref_id));
|
||||
} else if (is_exist) {
|
||||
//in the whole query stmt, table exists in the other query layer, so subquery must alias it
|
||||
//implicit alias table, alias name is table name
|
||||
item->table_id_ = generate_table_id();
|
||||
item->type_ = TableItem::ALIAS_TABLE;
|
||||
if (!synonym_name.empty()) {
|
||||
// bug: 31827906
|
||||
item->alias_name_ = synonym_name;
|
||||
} else {
|
||||
item->alias_name_ = tbl_name;
|
||||
}
|
||||
} else {
|
||||
//base table, no alias name
|
||||
item->table_id_ = generate_table_id();
|
||||
}
|
||||
} else {
|
||||
item->table_id_ = generate_table_id();
|
||||
item->alias_name_ = alias_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
|
@ -1385,23 +1385,6 @@ int ObStmtHint::merge_normal_hint(ObHint &hint,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObStmtHint::reset_explicit_trans_hint(ObItemType hint_type)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObHint *cur_hint = get_normal_hint(hint_type);
|
||||
if (NULL == cur_hint) {
|
||||
/* do nothing */
|
||||
} else if (OB_UNLIKELY(!cur_hint->is_transform_hint())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected hint type", K(ret), K(*cur_hint));
|
||||
} else if (!static_cast<const ObTransHint*>(cur_hint)->is_explicit()) {
|
||||
/* do nothing */
|
||||
} else if (OB_FAIL(remove_normal_hints(&hint_type, 1))) {
|
||||
LOG_WARN("failed to remove hints", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObStmtHint::has_enable_hint(ObItemType hint_type) const
|
||||
{
|
||||
const ObHint *cur_hint = get_normal_hint(hint_type);
|
||||
|
@ -231,7 +231,6 @@ struct ObStmtHint
|
||||
int merge_stmt_hint(const ObStmtHint &other, ObHintMergePolicy policy = HINT_DOMINATED_EQUAL);
|
||||
int merge_hint(ObHint &hint, ObHintMergePolicy policy, ObIArray<ObItemType> &conflict_hints);
|
||||
int merge_normal_hint(ObHint &hint, ObHintMergePolicy policy, ObIArray<ObItemType> &conflict_hints);
|
||||
int reset_explicit_trans_hint(ObItemType hint_type);
|
||||
|
||||
|
||||
bool has_enable_hint(ObItemType hint_type) const;
|
||||
|
@ -360,7 +360,6 @@ struct ObResolverParams
|
||||
has_recursive_word_(false),
|
||||
tg_timing_event_(-1),
|
||||
is_column_ref_(true),
|
||||
table_ids_(),
|
||||
hidden_column_scope_(T_NONE_SCOPE),
|
||||
outline_parse_result_(NULL),
|
||||
is_execute_call_stmt_(false),
|
||||
@ -432,7 +431,6 @@ public:
|
||||
bool has_recursive_word_;
|
||||
int64_t tg_timing_event_; // mysql mode, trigger的触发时机和类型
|
||||
bool is_column_ref_; // used to mark normal column ref
|
||||
common::hash::ObPlacementHashSet<uint64_t, common::OB_MAX_TABLE_NUM_PER_STMT, true> table_ids_;
|
||||
ObStmtScope hidden_column_scope_; // record scope for first hidden column which need check hidden_column_visable in opt_param hint
|
||||
ParseResult *outline_parse_result_;
|
||||
bool is_execute_call_stmt_;
|
||||
|
@ -363,22 +363,5 @@ int ObStmtResolver::get_column_schema(const uint64_t table_id,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObStmtResolver::check_table_id_exists(uint64_t table_id, bool &is_exist)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
is_exist = false;
|
||||
if (OB_HASH_EXIST == (ret = params_.table_ids_.exist_refactored(table_id))) {
|
||||
ret = OB_SUCCESS;
|
||||
is_exist = true;
|
||||
} else if (OB_HASH_NOT_EXIST == ret) {
|
||||
if (OB_FAIL(params_.table_ids_.set_refactored(table_id))) {
|
||||
SQL_RESV_LOG(WARN, "insert table_id to set failed", K(table_id), K(ret));
|
||||
}
|
||||
} else {
|
||||
SQL_RESV_LOG(WARN, "check table_id in table_ids set failed", K(table_id));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
|
@ -149,8 +149,6 @@ public:
|
||||
const bool get_hidden = false,
|
||||
bool is_link = false);
|
||||
|
||||
int check_table_id_exists(uint64_t table_id, bool &is_exist);
|
||||
|
||||
protected:
|
||||
int normalize_table_or_database_names(common::ObString &name);
|
||||
|
||||
|
@ -2186,8 +2186,6 @@ int ObTransformOrExpansion::transform_or_expansion(ObSelectStmt *stmt,
|
||||
LOG_WARN("unexpect null stmt", K(ret), K(copy_stmt));
|
||||
} else if (OB_FAIL(copy_stmt->deep_copy(*stmt_factory, *expr_factory, *stmt))) {
|
||||
LOG_WARN("failed to deep copy child statement", K(ret));
|
||||
} else if (OB_FAIL(copy_stmt->get_stmt_hint().reset_explicit_trans_hint(T_USE_CONCAT))) {
|
||||
LOG_WARN("failed to reset explicit trans hint", K(ret));
|
||||
} else if (OB_FAIL(get_expand_conds(*copy_stmt, trans_id, conds_exprs))) {
|
||||
LOG_WARN("failed to get expand conds", K(ret));
|
||||
} else if (FALSE_IT(view_stmt = copy_stmt)) {
|
||||
|
@ -393,7 +393,7 @@ insert into t1 values(1, 1);
|
||||
create view v as select * from t1 where not exists(select * from t1 where c1>0);
|
||||
show create view v;
|
||||
View Create View character_set_client collation_connection
|
||||
v CREATE VIEW `v` AS select `view`.`t1`.`c1` AS `c1`,`view`.`t1`.`c2` AS `c2` from `view`.`t1` where not exists((select `t1`.`c1`,`t1`.`c2` from `view`.`t1` `t1` where (`t1`.`c1` > 0))) utf8mb4 utf8mb4_general_ci
|
||||
v CREATE VIEW `v` AS select `view`.`t1`.`c1` AS `c1`,`view`.`t1`.`c2` AS `c2` from `view`.`t1` where not exists((select `view`.`t1`.`c1`,`view`.`t1`.`c2` from `view`.`t1` where (`view`.`t1`.`c1` > 0))) utf8mb4 utf8mb4_general_ci
|
||||
select * from v;
|
||||
c1 c2
|
||||
create view xy as select 123 from dual where not exists (select 1 from dual) limit 1;
|
||||
@ -416,7 +416,7 @@ create table t1 (k int, v int);
|
||||
create view v as (select k, v from t1) union (select 1, 1 from t1);
|
||||
show create view v;
|
||||
View Create View character_set_client collation_connection
|
||||
v CREATE VIEW `v` AS (select `view`.`t1`.`k` AS `k`,`view`.`t1`.`v` AS `v` from `view`.`t1`) union (select 1 AS `1`,1 AS `1` from `view`.`t1` `t1`) utf8mb4 utf8mb4_general_ci
|
||||
v CREATE VIEW `v` AS (select `view`.`t1`.`k` AS `k`,`view`.`t1`.`v` AS `v` from `view`.`t1`) union (select 1 AS `1`,1 AS `1` from `view`.`t1`) utf8mb4 utf8mb4_general_ci
|
||||
drop table if exists t1;
|
||||
drop table if exists t2;
|
||||
CREATE TABLE `t11` ( `a` int(11) NOT NULL, `b` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, PRIMARY KEY (`a`) );
|
||||
|
@ -2079,8 +2079,8 @@ Outline Data:
|
||||
PQ_SUBQUERY(@"SEL$1" ("SEL$2" "SEL$3") LOCAL LOCAL)
|
||||
FULL(@"SEL$1" "test"."t1"@"SEL$1")
|
||||
FULL(@"SEL$2" "test"."t2"@"SEL$2")
|
||||
FULL(@"SEL$3" "t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "t2"@"SEL$3")
|
||||
FULL(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
OPTIMIZER_FEATURES_ENABLE('')
|
||||
END_OUTLINE_DATA
|
||||
*/
|
||||
@ -2203,8 +2203,8 @@ Outline Data:
|
||||
PQ_SUBQUERY(@"SEL$1" ("SEL$2" "SEL$3") LOCAL LOCAL)
|
||||
FULL(@"SEL$1" "test"."t1"@"SEL$1")
|
||||
FULL(@"SEL$2" "test"."t2"@"SEL$2")
|
||||
FULL(@"SEL$3" "t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "t2"@"SEL$3")
|
||||
FULL(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
OPTIMIZER_FEATURES_ENABLE('')
|
||||
END_OUTLINE_DATA
|
||||
*/
|
||||
@ -2327,8 +2327,8 @@ Outline Data:
|
||||
PQ_SUBQUERY(@"SEL$1" ("SEL$2" "SEL$3") LOCAL LOCAL)
|
||||
FULL(@"SEL$1" "test"."t1"@"SEL$1")
|
||||
FULL(@"SEL$2" "test"."t2"@"SEL$2")
|
||||
FULL(@"SEL$3" "t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "t2"@"SEL$3")
|
||||
FULL(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
OPTIMIZER_FEATURES_ENABLE('')
|
||||
END_OUTLINE_DATA
|
||||
*/
|
||||
@ -2451,8 +2451,8 @@ Outline Data:
|
||||
PQ_SUBQUERY(@"SEL$1" ("SEL$2" "SEL$3") LOCAL LOCAL)
|
||||
FULL(@"SEL$1" "test"."t1"@"SEL$1")
|
||||
FULL(@"SEL$2" "test"."t2"@"SEL$2")
|
||||
FULL(@"SEL$3" "t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "t2"@"SEL$3")
|
||||
FULL(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
OPTIMIZER_FEATURES_ENABLE('')
|
||||
END_OUTLINE_DATA
|
||||
*/
|
||||
@ -2582,10 +2582,10 @@ Outline Data:
|
||||
PQ_SUBQUERY(@"SEL$1" ("SEL$2" "SEL$3" "SEL$4") LOCAL LOCAL)
|
||||
FULL(@"SEL$1" "test"."t1"@"SEL$1")
|
||||
FULL(@"SEL$2" "test"."t2"@"SEL$2")
|
||||
FULL(@"SEL$3" "t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "t2"@"SEL$3")
|
||||
FULL(@"SEL$4" "t2"@"SEL$4")
|
||||
USE_DAS(@"SEL$4" "t2"@"SEL$4")
|
||||
FULL(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
FULL(@"SEL$4" "test"."t2"@"SEL$4")
|
||||
USE_DAS(@"SEL$4" "test"."t2"@"SEL$4")
|
||||
OPTIMIZER_FEATURES_ENABLE('')
|
||||
END_OUTLINE_DATA
|
||||
*/
|
||||
@ -2761,18 +2761,18 @@ Outline Data:
|
||||
FULL(@"SEL$1" "test"."t1"@"SEL$1")
|
||||
FULL(@"SEL$2" "test"."t2"@"SEL$2")
|
||||
USE_DAS(@"SEL$2" "test"."t2"@"SEL$2")
|
||||
FULL(@"SEL$3" "t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "t2"@"SEL$3")
|
||||
FULL(@"SEL$4" "t2"@"SEL$4")
|
||||
USE_DAS(@"SEL$4" "t2"@"SEL$4")
|
||||
FULL(@"SEL$5" "t2"@"SEL$5")
|
||||
USE_DAS(@"SEL$5" "t2"@"SEL$5")
|
||||
FULL(@"SEL$6" "t2"@"SEL$6")
|
||||
USE_DAS(@"SEL$6" "t2"@"SEL$6")
|
||||
FULL(@"SEL$7" "t2"@"SEL$7")
|
||||
USE_DAS(@"SEL$7" "t2"@"SEL$7")
|
||||
FULL(@"SEL$8" "t2"@"SEL$8")
|
||||
USE_DAS(@"SEL$8" "t2"@"SEL$8")
|
||||
FULL(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
FULL(@"SEL$4" "test"."t2"@"SEL$4")
|
||||
USE_DAS(@"SEL$4" "test"."t2"@"SEL$4")
|
||||
FULL(@"SEL$5" "test"."t2"@"SEL$5")
|
||||
USE_DAS(@"SEL$5" "test"."t2"@"SEL$5")
|
||||
FULL(@"SEL$6" "test"."t2"@"SEL$6")
|
||||
USE_DAS(@"SEL$6" "test"."t2"@"SEL$6")
|
||||
FULL(@"SEL$7" "test"."t2"@"SEL$7")
|
||||
USE_DAS(@"SEL$7" "test"."t2"@"SEL$7")
|
||||
FULL(@"SEL$8" "test"."t2"@"SEL$8")
|
||||
USE_DAS(@"SEL$8" "test"."t2"@"SEL$8")
|
||||
OPTIMIZER_FEATURES_ENABLE('')
|
||||
END_OUTLINE_DATA
|
||||
*/
|
||||
@ -2996,18 +2996,18 @@ Outline Data:
|
||||
FULL(@"SEL$1" "test"."t1"@"SEL$1")
|
||||
FULL(@"SEL$2" "test"."t2"@"SEL$2")
|
||||
USE_DAS(@"SEL$2" "test"."t2"@"SEL$2")
|
||||
FULL(@"SEL$3" "t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "t2"@"SEL$3")
|
||||
FULL(@"SEL$4" "t2"@"SEL$4")
|
||||
USE_DAS(@"SEL$4" "t2"@"SEL$4")
|
||||
FULL(@"SEL$5" "t2"@"SEL$5")
|
||||
USE_DAS(@"SEL$5" "t2"@"SEL$5")
|
||||
FULL(@"SEL$6" "t2"@"SEL$6")
|
||||
USE_DAS(@"SEL$6" "t2"@"SEL$6")
|
||||
FULL(@"SEL$7" "t2"@"SEL$7")
|
||||
USE_DAS(@"SEL$7" "t2"@"SEL$7")
|
||||
FULL(@"SEL$8" "t2"@"SEL$8")
|
||||
USE_DAS(@"SEL$8" "t2"@"SEL$8")
|
||||
FULL(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
FULL(@"SEL$4" "test"."t2"@"SEL$4")
|
||||
USE_DAS(@"SEL$4" "test"."t2"@"SEL$4")
|
||||
FULL(@"SEL$5" "test"."t2"@"SEL$5")
|
||||
USE_DAS(@"SEL$5" "test"."t2"@"SEL$5")
|
||||
FULL(@"SEL$6" "test"."t2"@"SEL$6")
|
||||
USE_DAS(@"SEL$6" "test"."t2"@"SEL$6")
|
||||
FULL(@"SEL$7" "test"."t2"@"SEL$7")
|
||||
USE_DAS(@"SEL$7" "test"."t2"@"SEL$7")
|
||||
FULL(@"SEL$8" "test"."t2"@"SEL$8")
|
||||
USE_DAS(@"SEL$8" "test"."t2"@"SEL$8")
|
||||
OPTIMIZER_FEATURES_ENABLE('')
|
||||
END_OUTLINE_DATA
|
||||
*/
|
||||
@ -3231,18 +3231,18 @@ Outline Data:
|
||||
FULL(@"SEL$1" "test"."t1"@"SEL$1")
|
||||
FULL(@"SEL$2" "test"."t2"@"SEL$2")
|
||||
USE_DAS(@"SEL$2" "test"."t2"@"SEL$2")
|
||||
FULL(@"SEL$3" "t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "t2"@"SEL$3")
|
||||
FULL(@"SEL$4" "t2"@"SEL$4")
|
||||
USE_DAS(@"SEL$4" "t2"@"SEL$4")
|
||||
FULL(@"SEL$5" "t2"@"SEL$5")
|
||||
USE_DAS(@"SEL$5" "t2"@"SEL$5")
|
||||
FULL(@"SEL$6" "t2"@"SEL$6")
|
||||
USE_DAS(@"SEL$6" "t2"@"SEL$6")
|
||||
FULL(@"SEL$7" "t2"@"SEL$7")
|
||||
USE_DAS(@"SEL$7" "t2"@"SEL$7")
|
||||
FULL(@"SEL$8" "t2"@"SEL$8")
|
||||
USE_DAS(@"SEL$8" "t2"@"SEL$8")
|
||||
FULL(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
USE_DAS(@"SEL$3" "test"."t2"@"SEL$3")
|
||||
FULL(@"SEL$4" "test"."t2"@"SEL$4")
|
||||
USE_DAS(@"SEL$4" "test"."t2"@"SEL$4")
|
||||
FULL(@"SEL$5" "test"."t2"@"SEL$5")
|
||||
USE_DAS(@"SEL$5" "test"."t2"@"SEL$5")
|
||||
FULL(@"SEL$6" "test"."t2"@"SEL$6")
|
||||
USE_DAS(@"SEL$6" "test"."t2"@"SEL$6")
|
||||
FULL(@"SEL$7" "test"."t2"@"SEL$7")
|
||||
USE_DAS(@"SEL$7" "test"."t2"@"SEL$7")
|
||||
FULL(@"SEL$8" "test"."t2"@"SEL$8")
|
||||
USE_DAS(@"SEL$8" "test"."t2"@"SEL$8")
|
||||
OPTIMIZER_FEATURES_ENABLE('')
|
||||
END_OUTLINE_DATA
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user